首先明确ioctl的作用:向设备文件上写入或者读取数据时使用read()和write(),但是两者不能区别写入或读取的是控制数据还是通信状态数据等信息,这就需要用到ioctl;
在设备驱动中应用ioctl函数需要在file_operation结构体中定义。
设备驱动中的ioctl的形式一般为:xxx_ioctl(struct inode *inode , struct file *filp , unsigned int cmd , unsigned long arg)
其中我们重点了解cmd这个参数以及与之相关的一些宏:
cmd是应用程序用于向驱动请求 处理的内容的标示,不同的cmd标示请求处理的内容不一样。
cmd的大小为32位,被分为4个区域
1)区别序号;
2)魔数 ,用于判断命令是否属于该驱动 ;
3)数据大小
4)区别读写
那么如何生成这些命令呢?
我们通常的做法是写一个头文件,在其中定义驱动使用到的命令(当然是用宏产生的),该头文件是驱动和应用程序共享的。
用于产生命令的宏以及其格式为_IO(魔术,基数) ,_IOR(魔术,基数,变量型),_IOW(魔术,基数,变量型),_IOWR(魔术,基数,变量型),其中变量型一般为一个结构体,这也要在头文件中定义。
解析这些命令用到的宏:IOC_NR:读取基数域值 IOC_TYPE读取模数IOC_SIZE读取数据大小 IOC_DIR读取读写属性。
通常在ioctl函数中用switch区分命令并执行相应的操作。