分类: 嵌入式
2018-10-21 15:58:42
一、注册设备节点
参考:百度“register_chrdev” 百度“register_chrdev register_chrdev_region”
int register_chrdev (unsigned int major, const char *name, struct file_operations*fops);
第一个参数是主设备号,0代表动态分配,如#define SPIDEV_MAJOR 153,这里spi的主设备号是153。(对于已完成注册的设备,用cat /proc/devices可以查询到)
第二个参数是设备的名字。
第三个参数是文件操作指针。
每个设备文件对应有两个设备号:一个是主设备号,标识该设备的种类,也标识了该设备所使用的驱动程序;另一个是次设备号,标识使用同一设备驱动程序的不同硬件设备。设备文件的主设备号(device_create()时)必须与设备驱动程序在登录该设备时申请的主设备号(register_chrdev()时)一致,否则用户进程将无法访问到设备驱动程序。
注意:除了register_chrdev()函数,在2.6的内核之后,新增了一个register_chrdev_region()函数,同时也保留了原有的register_chrdev()函数。
register_chrdev()调用了__register_chrdev_region(),并强制指定了起始次设备号为0,256个,把一个主设备号下的所有次设备号都申请光了;同时它还封装了cdev_init()和 cdev_add(),倒是很省事。这种方式每一个主设备号只能存放一种设备,它们使用相同的 file_operation 结构体,也就是说内核最多支持 256 个字符设备驱动程序。模块卸载时,register_chrdev()对应需要调用unregister_chrdev()注销字符设备。
register_chrdev_region也调用了__register_chrdev_region(),但是次设备号可以根据自己需要进行申请;同时我们需要手动 cdev_init(),cdev_add()。这种方式支持将同一个主设备号下的次设备号进行分段,每一段供给一个字符设备驱动程序使用,使得资源利用率大大提升。模块卸载时,register_chrdev_region()对应需要调用unregister_chrdev_region()释放原先申请的设备号;cdev_init(),cdev_add()对应需要调用cdev_del()来释放cdev占用的内存。
但是,在 2.6 的内核中这两种方法都会调用到 __register_chrdev_region 函数。
用法:
点击(此处)折叠或打开
实例:1.2.2 使用register_chrdev注册字符设备 字符设备之register_chrdev与register_chrdev_region
二、创建设备节点
参考:class_create(),device_create自动创建设备文件结点 一步一步学习 Linux 驱动之自动创建设备节点
刚开始学习驱动的时候,每次都需要mknod /dev/timer c 500 0 这样手动去创建一个设备节点。实际上Linux内核提供一组函数,可以用来在驱动模块加载的时候自动在/dev目录下创建相应的设备节点(my_device),并在卸载模块时删除该节点(my_device)。
class_create(owner, name)和class_destroy(struct class *cls);配对使用
device_create(struct class *class, struct device *parent,dev_t devt, void
*drvdata, const char *fmt, ...)和device_destroy(struct class *class,dev_t devt)配对使用
内核中定义了struct
class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
注意:在2.6较早的内核版本中,device_create()函数名称不同,是class_device_create()。
实例:一步一步学习 Linux 驱动之自动创建设备节点 字符设备之register_chrdev与register_chrdev_region