Misc设备–特殊的字符设备

本质上仍然是字符设备,只是被增加了以层封装而已。Misc设备共享一个主设备号MISC_MAJOR(10),但次设备号不同(系统最多有255个杂项设备),所有的misc设备形成一个链表,对设备访问时内核根据次设备号查找对应的 misc设备,然后调用其中的file_operations结构体中注册的文件操作接口进行操作,因此其驱动的主体工作还是file_operations的成员函数。

1.字符设备模板及说明解析:

1.http://blog.csdn.net/wdzxl198/article/details/8817147 (自动创建设备节点)
2.http://blog.chinaunix.net/uid-20698426-id-136243.html
主要是init函数(获取设备号,创建节点) ,exit函数(回收操作),及设备操作集对应的操作函数。

2.设备操作集file_operations结构体分析:

http://www.linuxidc.com/Linux/2011-09/43530.htm

特别的异步IO轮询函数:
unsigned int (*poll)(struct file *, struct poll_table_struct *);
(这是一个设备驱动中的轮询函数,第一个参数为file结构指针,第二个为轮询表指针)
这个函数返回设备资源的可获取状态,即POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL等宏的位“或”结果。
每个宏都表明设备的一种状态,如:POLLIN(定义为0x0001)意味着设备可以无阻塞的读,POLLOUT(定义为0x0004)意味着设备可以无阻塞的写。
(poll 方法是 3 个系统调用的后端: poll, epoll, 和 select, 都用作查询对一个或多个文件描述符的读或写是否会阻塞.
poll 方法应当返回一个位掩码指示是否非阻塞的读或写是可能的, 并且, 可能地, 提供给内核信息用来使调用进程睡眠直到 I/O 变为可能.
如果一个驱动的 poll 方法为 NULL, 设备假定为不阻塞地可读可写.
(这里通常将设备看作一个文件进行相关的操作,而轮询操作的取值直接关系到设备的响应情况,可以是阻塞操作结果,同时也可以是非阻塞操作结果)

3.ioctl函数详解:

http://blog.csdn.net/shanshanpt/article/details/19897897

ioctl函数的cmd:
cmd的大小为 32位,共分 4 个域:
bit31bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令。
bit29
bit15 14位为 ”数据大小” 区,表示 ioctl() 中的 arg 变量传送的内存大小。
bit20bit08  8位为 “魔数”(“幻数”)区,这个值用以与其它设备驱动程序的 ioctl 命令进行区别。
bit07
bit00   8位为 ”区别序号” 区,是区分命令的命令顺序序号。

这几个宏的使用格式为:

  • _IO (魔数, 基数);

  • _IOR (魔数, 基数, 变量型)

  • _IOW  (魔数, 基数, 变量型)

  • _IOWR (魔数, 基数,变量型 )

    魔数 (magic number)
    魔数范围为 0255 。通常,用英文字符 ”A”  ”Z” 或者 ”a” ~ ”z” 来表示。设备驱动程序从传递进来的命令获取魔数,然后与自身处理的魔数想比较,如果相同则处理,不同则不处理。魔数是拒绝误使用的初步辅助状态。设备驱动 程序可以通过 _IOC_TYPE (cmd) 来获取魔数。不同的设备驱动程序最好设置不同的魔数,但并不是要求绝对,也是可以使用其他设备驱动程序已用过的魔数。

    基(序列号)数
    基数用于区别各种命令。通常,从 0开始递增,相同设备驱动程序上可以重复使用该值。例如,读取和写入命令中使用了相同的基数,设备驱动程序也能分辨出来,原因在于设备驱动程序区分命令时 使用 switch ,且直接使用命令变量 cmd值。创建命令的宏生成的值由多个域组合而成,所以即使是相同的基数,也会判断为不同的命令。设备驱动程序想要从命令中获取该基数,就使用下面的宏:
    _IOC_NR (cmd)
    通常,switch 中的 case 值使用的是命令的本身。

    变量型
    变量型使用 arg 变量指定传送的数据大小,但是不直接代入输入,而是代入变量或者是变量的类型,原因是在使用宏创建命令,已经包含了 sizeof() 编译命令。

    Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析:http://blog.csdn.net/hzn407487204/article/details/7995041

4.misc设备相关:

misc设备结构体:
struct miscdevice  {
int minor;  //次设备号,若为 MISC_DYNAMIC_MINOR 自动分配
const char *name;  //设备名
const struct file_operations *fops;  //设备文件操作结构体
struct list_head list;    //misc_list链表头
struct device *parent;
struct device *this_device;

};

misc设备注册和注销API:
int misc_register(struct miscdevice *misc)
int misc_deregister(struct miscdevice *misc)

misc设备驱动模型及实例解析:
参考:http://blog.csdn.net/chenlong12580/article/details/7339127

5.具体实例:

详见code文件夹