linux驅動之自動創建設備節點

利用cat /proc/devices查看申請到的設備名,設備號。
創建設備節點
1.使用mknod手工創建:mknod filename type major minor
2.自動創建設備節點:利用udev(mdev)來實現設備文件的自動創建,首先應保證支持udev(mdev),由busybox配置。

在驅動用加入對udev 的支持主要做的就是:在驅動初始化的代碼裏調用class_create(…)爲該設備創建一個class,再爲每個設備調用device_create(…)創建對應的設備。
內核中定義的struct class結構體,顧名思義,一個struct class結構體類型變量對應一個類,內核同時提供了class_create(…)函數,可以用它來創建一個類,這個類存放於sysfs下面,一旦創建好了這個類,再調用 device_create(…)函數來在/dev目錄下創建相應的設備節點。
這樣,加載模塊的時候,用戶空間中的udev會自動響應 device_create()函數,去/sysfs下尋找對應的類從而創建設備節點。

下面是兩個函數的解析:
1、class_create(…) 函數
功能:創建一個類;
內核源碼:

#define class_create(owner, name)       \
({                      \
    static struct lock_class_key __key; \
    __class_create(owner, name, &__key);    \
})

owner:THIS_MODULE
name : 類名字
2.設備類的銷燬函數

void class_destroy(struct class *cls)
{
    if ((cls == NULL) || (IS_ERR(cls)))
        return;

    class_unregister(cls);
}

2.device_create(…) 函數
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, …)
{
va_list vargs;
struct device *dev;

va_start(vargs, fmt);
dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
va_end(vargs);
return dev;
}
功能:創建一個字符設備文件
參數:
struct class *class :類
struct device *parent:NULL
dev_t devt :設備號
void *drvdata :null、
const char *fmt :名字
返回:
struct device *

代碼示例

#include <linux/module.h>  
#include <linux/fs.h>  
#include <linux/cdev.h>  
#include <linux/device.h>  

static int major = 250;  
static int minor=0;  
static dev_t devno;  
static struct class *cls;  
static struct device *test_device;  

static int hello_open (struct inode *inode, struct file *filep)  
{  
    printk("hello_open \n");  
    return 0;  
}  
static struct file_operations hello_ops=  
{  
    .open = hello_open,  
};  

static int hello_init(void)  
{  
    int ret;      
    printk("hello_init \n");  


    devno = MKDEV(major,minor);  
    ret = register_chrdev(major,"hello",&hello_ops);  

    cls = class_create(THIS_MODULE, "myclass");  
    if(IS_ERR(cls))  
    {  
        unregister_chrdev(major,"hello");  
        return -EBUSY;  
    }  
    test_device = device_create(cls,NULL,devno,NULL,"hello");//mknod /dev/hello  
    if(IS_ERR(test_device))  
    {  
        class_destroy(cls);  
        unregister_chrdev(major,"hello");  
        return -EBUSY;  
    }     
    return 0;  
}  
static void hello_exit(void)  
{  
    device_destroy(cls,devno);  
    class_destroy(cls);   
    unregister_chrdev(major,"hello");  
    printk("hello_exit \n");  
}  
MODULE_LICENSE("GPL");  
module_init(hello_init);  
module_exit(hello_exit);  
發佈了102 篇原創文章 · 獲贊 110 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章