| /******************** * 字符设备驱动 ********************/ |
(1)字符设备驱动介绍
字符设备是指那些按字节流访问的设备,针对字符设备的驱动称为字符设备驱动。
此类驱动适合于大多数简单的硬件设备。比如并口打印机,我们通过在/dev下建立一个设备文件(如/dev/printer)来访问它。
用户应用程序用标准的open函数打开dev/printer,然后用write向文件中写入数据,用read从里面读数据。
调用流程:
write(): 用户空间 --> sys_write(): VFS --> f_op->write: 特定设备的写方法所谓驱动,就是提供最后的write函数,通过访问打印机硬件的寄存器直接和打印机对话
(2)主设备号和次设备号
a.设备编号介绍
对字符设备的访问是通过文件系统内的设备文件进行的。这些文件位于/dev。用"ls -l"查看。
设备通过设备号来标识。设备号分两部分,主设备号和次设备号。
通常,主设备号标示设备对应的驱动程序,linux允许多个驱动共用一个主设备号;
而次设备号用于确定设备文件所指的设备。
在内核中,用dev_t类型<linux/types.h>保存设备编号。
2.4内核中采用16位设备号(8位主,8位从),而2.6采用32位,12位主,20位从。
在驱动中访问设备号应该用<linux/kdev_t.h>中定义的宏。
获取设备号:
MAJOR(dev_t dev) MINOR(dev_t dev) MKDEV(int major, int minor)b.分配和释放设备编号
在建立一个字符设备前,驱动需要先获得设备编号。
分配:
| #include <linux/fs.h> int register_chrdev_region(dev_t first, unsigned int count, char *name); //first:要分配的设备编号范围的起始值(次设备号常设为0) //count: 所请求的连续编号范围 //name: 和编号关联的设备名称(见/proc/devices) |
也可以要求内核动态分配:
| int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); //firstminor: 通常为0 //*dev: 存放内核返回的设备号 |
释放:
| void unregister_chrdev_region(dev_t first, unsigned int count); //在模块的清除函数中调用 |
在Documentation/devices.txt中可以找到内核已经分配的设备号。
c.建立设备文件
当设备驱动模块向系统申请了主设备号和次设备号,并且已经通过insmod加载到内核中后,我们就可以通过在/dev下创建设备文件来访问这个设备了。
字符设备的创建:$>mknod /dev/mychar c major minor
我们在驱动中常常采用动态分配主次设备号的方法,这样不会和系统中已有的设备号冲突。
动态分配时,/dev下的设备文件也需要通过分析/proc/devices动态建立。








