第二十一节、ioctl接口
本节用于介绍ioctl接口
unlocked_ioctl接口
1、什么是unlocked_ioctl接口?
在linux3.0之前是ioctl接口,是带锁的,导致内核实时性不高,所以后来的ioctl变成了不带锁的
unlocked_ioctl就是ioctl接口,是功能和对应的系统调用均没有发生变化。
2、unlocked_ioctl和read/write函数有什么相同点和不同点?
文件位置:include/linux/fs.h
struct file_operations {
struct module *owner;
...
//当我们在应用层ioctl设备节点的时候,就会触发我们驱动里面这个函数。
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
...
}
相同点:都可以往内核写数据。
不同点:read函数只能完成读的功能,write只能完成写的功能。读取大数据的时候效率高
ioctl 既可以读也可以写。读取大数据的时候效率不高
3、unlocked_ioctl 接口命令规则。
ioctl命令是一个unsigned int类型的,在这32位里面一共有四个分区,这四个分区里面所代表的含义是不同的
第一个分区:0-7,命令的编号,范围是0-255
第二个分区:8-15,命令的幻数。
第一个分区和第二个分区主要作用是用来区分命令的。
第三个分区:16-29,表示传递的数据大小。
第四个分区:30-31,代表读写的方向。
- 00:表示用户程序和驱动程序没有数据传递
- 10:表示用户程序从驱动里面读数据
- 01:表示用户程序向驱动里面写数据
- 11:先写数据到驱动里面然后在从驱动里面把数据读出来。
4、命令的合成宏与分解宏
合成宏:
文件位置:include/uapi/asm-generic/ioctl.h
_IO(type,nr) //用来定义没有数据传递的命令
_IOR(type,nr,size) //用来定义从驱动中读取数据的命令
_IOW(type,nr,size) //用来定义向驱动写入数据的命令
_IOWR(type,nr,size) //用来定义数据交换类型的命令,先写入数据,再读取数据这类命令。
//参数:
//type:表示命令组成的幻数,也就是8~15位
//nr:表示命令组成的编号,也就是0~7位
//size:表示命令组成的参数传递大小,注意这里不是传递数字,而是数据类型,如要传递4字节,就可以写成int
分解宏:
文件位置:include/uapi/asm-generic/ioctl.h
_IOC_DIR(nr) //分解命令的方向,也就是上面说30~31位的值
_IOC_TYPE(nr) //分解命令的幻数,也就是上面说8~15位的值
_IOC_NR(nr) //分解命令的编号,也就是上面说0~7位
_IOC_SIZE(nr) //分解命令的复制数据大小,也就是上面说的16~29位
//参数:要分解的命令