参看朱有鹏老师嵌入式视屏,第五部分第三章
1、(1)老接口:register_chrdev
(2)新接口:register_chrdev_region/alloc_chrdev_region + cdev
register_chrdev_region/alloc_chrdev_region注册设备号的作用,register_chrdev_region的作用是静态给一个设备号,alloc_chrdev_region的作用的由系统动态分配一个设备号;cdev是注册驱动,与file_operations挂钩
2、cdev结构体
cdev结构体路径:kernel/include/linux/cdev.h
(1) 我们关心的有两个,file_operation结构体、dev_t设备号
(2)相关函数:cdev_alloc(给结构体创建内存空间)、cdev_init(初始化)、cdev_add(像内核中注册驱动)、cdev_del(注销驱动)
3、函数解析
(1)cdev_init()函数讲解
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
参数:*cdev表示cdev结构体,*fops表示file_operations结构体
没有返回值,作用是初始化cdev结构体、初始化file_operations结构体
(2)cdev_add()函数讲解
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
参数:
p表示这个设备的cdev结构体
dev表示设备标号
count表示设备数量
返回值,大于0表示调价失败,等于0表示添加设备成功。
(3)int register_chrdev_region(dev_t from,unsigned int count,char*name)
//from为第一个设备编号,count为连续的设备个数,即是驱动程序所管理的设备个数,name为驱动程序名
实例如下:
现假设有一个设备驱动程序使用的主设备号是257,次设备号分别是0,1,2,3
其调用
int ret=register_chrdev_region(MKDEV(257,0),4,"demodev");
接下来还要判断ret返回值,若果返回值大于0,则说明创建设备号失败,否则创建成功。
(4)alloc_chrdev_region函数
该函数由系统协助分配设备号,分配的主设备号在1-254间
int alloc_chrdev_region(dev_t *dev,unisgned baseminor,unsigned count,const char*name)
//dev仅用于输出的参数,在成功完成调用后将保存以分配范围的第一个编号。baseminor所请求的第一个编号,count是连续的分配个数,char为驱动程序名
4、使用class_create()函数和device_create()函数自动创建设备文件
问题:之前insmod xxx.ko安装一个模块之后,还要在命令行中执行【mknod /dev/test c 250 0】去手工创建设备文件,这样非常麻烦。现在要做的就是执行insmod之后,系统自动创建设备文件;执行rmmod之后,系统自动删除设备文件。
实现方式, (1)class_create 对应 class_destroy
(2)device_create 对应 device_destroy
5、在chrdev_init中注册设备文件完成之后,用如下代码去实现自动创建设备文件。创建设备文件之后,才可以在应用层去访问这个设备。
1. // 注册字符设备驱动完成后,添加设备类的操作,以让内核帮我们发信息 2. // 给udev,让udev自动创建和删除设备文件 3. test_class = class_create(THIS_MODULE, "aston_class"); 4. if (IS_ERR(test_class)) 5. return -EINVAL; 6. // 最后1个参数字符串,就是我们将来要在/dev目录下创建的设备文件的名字 7. // 所以我们这里要的文件名是/dev/test 8. device_create(test_class, NULL, mydev, NULL, "test111");
在实验时,可以看到执行insmod指令之后,直接去/dev目录下查看设备,可以看到设备是存在的,我们这里命名设备为test111
同时ls /sys/class,可以看到目录中有我们创建的类aston_class.