device_create();和class_create()和cdev_init();cdev_add()的区别
时间: 2024-05-16 17:19:40 浏览: 298
这三个函数都是在Linux内核中用于创建和注册字符设备驱动的函数,但是它们的作用和实现方式略有不同。
- device_create()函数用于创建一个设备文件,并将该设备文件和对应的设备驱动程序进行绑定。它是在/sys/class/目录下创建设备文件,例如/dev/sda就是一个设备文件,用于表示Linux系统中的第一块磁盘设备。该函数需要指定设备文件所属的class以及设备号,而设备号通常是由主设备号和次设备号组成。这个函数在设备驱动程序的probe函数中通常会调用。
- class_create()函数用于创建一个class,并将该class和对应的设备驱动程序进行绑定。该函数会在/sys/class/目录下创建一个目录,例如/sys/class/input表示输入设备的class。创建class后,可以通过device_create()函数来创建class所对应的设备文件。
- cdev_init()和cdev_add()函数用于向Linux内核注册字符设备驱动程序。cdev_init()函数用于初始化struct cdev结构体,而cdev_add()函数则将此结构体添加到内核中。在设备驱动程序的probe函数中,通常需要使用cdev_init()函数来初始化字符设备驱动程序,并使用cdev_add()函数将其添加到系统中。
综上所述,device_create()和class_create()函数用于创建和管理设备文件和class,而cdev_init()和cdev_add()函数则用于注册字符设备驱动程序。
相关问题
/1. 声明一个 led 字符设备结构体 static struct cdev led_cdev; //2.1 声明一个设备号 static dev_t led_num; //声明一个 myled 的类指针 static struct class * led_class; //声明一个 led 的设备指针 static struct device *led_device; //4.定义一个文件操作集 int led_open(struct inode * inode, struct file *file) { printk(KERN_INFO"led_open\n"); return 0; } //ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t led_write(struct file * file, const char __user * buff, size_t len, loff_t * offset) { int rt; char kbuf[64]={0}; if(buff==NULL) return -EINVAL; if(len > sizeof kbuf) len=sizeof kbuf; //注释:unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) rt=copy_from_user(kbuf,buff,len); len=len-rt; printk("copy from user buf is %s,len=%d\n",buff,len); return len; } //注释:ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t led_read(struct file *file, char __user * buff, size_t len, loff_t * offset) { int rt; char kbuff[64]="I'm kernel data"; if(buff==NULL) return -EINVAL; if(len > sizeof kbuff) len=sizeof kbuff; rt=copy_to_user(buff, kbuff, strlen(kbuff)); len=strlen(kbuff)-rt; printk("len=%d\n",len); return len; } int led_close(struct inode * inode, struct file *file) { printk("led_close\n"); return 0; } struct file_operations led_fops={ .owner = THIS_MODULE, .open = led_open, .write = led_write, .read = led_read, .release = led_close }; static int __init kernel_init(void) { int re; //2.2 构建一个设备号,主设备号为 240,次设备号为 0 led_num=MKDEV(240,0); /3. 注册是设备号 re=register_chrdev_region(led_num, 1, "myled"); if(re<0) { printk("register_chrdev_region error\n"); goto err_register_chrdev_region; } cdev_init(&led_cdev,&led_fops); re=cdev_add(&led_cdev, led_num, 1); if(re<0) { printk("cdev_add failed\n"); goto err_cdev_add; } //创建 myled 的设备类/sys/class 目录中找到 led_class=class_create(THIS_MODULE,"myled"); if(IS_ERR(led_class)) { printk(KERN_INFO"class create error\n"); re=PTR_ERR(led_class); goto err_class_create; } //创建设备类成功创建 myled 的设备信息 led_device=device_create(led_class,NULL,led_num,NULL,"myled"); if (IS_ERR(led_device)) { re = PTR_ERR(led_device); printk("device_create leds device fail\n"); goto err_device_create; } printk(KERN_INFO"mylded_drv\n"); return 0; err_device_create: class_destroy(led_class); err_class_create: cdev_del(&led_cdev); err_cdev_add: unregister_chrdev_region(led_num, 1); return re; err_register_chrdev_region: return re; } static void __exit kernel_exit(void) { device_destroy(led_class,led_num); class_destroy(led_class); cdev_del(&led_cdev); unregister_chrdev_region(led_num, 1); printk("exit myled_drv\n"); } module_init(kernel_init); module_exit(kernel_exit); MODULE_AUTHOR("wangna wangna@blackfin.uclinux.org 1351234556"); MODULE_DESCRIPTION("kernel module test"); MODULE_LICENSE("GPL");为以上代码增加注释
/*
* 该模块实现了一个 led 字符设备,在 /dev 目录下创建 myled 设备文件。
* 本模块实现了文件操作集中的 open、write、read 和 close 函数。
* 使用 register_chrdev_region 函数注册了设备号,使用 cdev_add 函数将设备添加到系统中。
* 使用 class_create 函数创建了 myled 的设备类,使用 device_create 函数创建了 myled 的设备信息。
* 最后使用 module_init 和 module_exit 宏定义了 init 和 exit 函数,并且指定了模块的作者、描述和许可证。
*/
现有函数 A:cdev init,B:allo chrdev region, C: class create,D:cdev add,E:device create.要创建设备文件节点,写出个各函数调用顺序,比如: B、C、A、D、E
正确的函数调用顺序应为:
1. 调用allo_chrdev_region()函数分配主设备号和次设备号。
2. 调用class_create()函数创建一个设备类。
3. 调用cdev_init()函数初始化cdev结构体。
4. 调用cdev_add()函数将cdev结构体添加到内核中。
5. 调用device_create()函数创建设备节点文件。
因此,正确的函数调用顺序应该是:B、C、A、D、E。
阅读全文