Yuhang Zheng

第二十一节、ioctl接口

N 人看过

本节用于介绍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位
//参数:要分解的命令