linux驱动之 ioctrl接口

18、ioctl接口

unlocked_ioctrl 接口

1、什么是unlocked_ioctrl 接口?

​ unlocked_ioctrl 在之前的名字是ioctrl, 之前的是带锁的,现在的是不带锁的, 原因是为了提高实时性

虽然名字发生了改变,但是功能和对应的系统调用均没有发生变化

2、unlocked_ioctl 和 read/write 有什么相同点和不同点?
1、相同点

​ 都可以往内核写数据

2、不同点

​ read函数只能完成读的功能, write 只能完成写的功能

读取大量数据的时候效率高

​ ioctl 即可以读也可以写 读取大量数据的效率低

3、unlocked_ioctrl 接口命令规则。

命令一个unsigned int 类型的无符号整型数

魔数 (magic number)
魔数范围为 0~255 。通常,用英文字符 “A” ~ “Z” 或者 “a” ~ “z” 来表示。设备驱动程序从传递进来的命令获取魔数,然后与自身处理的魔数想比较,如果相同则处理,不同则不处理。魔数是拒绝误使用的初步辅助状态。设备驱动 程序可以通过 _IOC_TYPE (cmd) 来获取魔数。不同的设备驱动程序最好设置不同的魔数,但并不是要求绝对,也是可以使用其他设备驱动程序已用过的魔数。
基(序列号)数
基数用于区别各种命令。通常,从 0开始递增,相同设备驱动程序上可以重复使用该值。例如,读取和写入命令中使用了相同的基数,设备驱动程序也能分辨出来,原因在于设备驱动程序区分命令时 使用 switch ,且直接使用命令变量 cmd值。创建命令的宏生成的值由多个域组合而成,所以即使是相同的基数,也会判断为不同的命令。设备驱动程序想要从命令中获取该基数,就使用下面的宏:
_IOC_NR (cmd)
通常,switch 中的 case 值使用的是命令的本身。
变量型
变量型使用 arg 变量指定传送的数据大小,但是不直接代入输入,而是代入变量或者是变量的类型,原因是在使用宏创建命令,已经包含了 sizeof() 编译命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o73r3O8E-1619337654048)(linux%E9%A9%B1%E5%8A%A8.assets/image-20210421092245174.png)]

第一个分区 : 0-7位 , 命令的编号 0-255

第二个分区: 8-15位, 命令的幻(魔)数

第一个分区和第二个分区, 主要是用来区分命令的

第三个分区:16-29 表示传递的数据大小

第四个分区:30-31 代表读写方向

参数功能
00表示应用程序和驱动程序没有数据传递
10表示应用程序从驱动里面读数据
01表示应用程序向驱动里面写数据
11表示应用程序先写数据到驱动,然后再从驱动里面读数据
4、命令的合成与分解宏

1、合成宏:

宏定义功能
_IO(type, nr)用来定义没有数据传递的命令
_IOR(type, nr, size)用来定义从驱动中读取数据的命令
_IOW(type, nr, size)用来定义向驱动写入数据的命令
_IOWR(type, nr, size)用来定义数据交换类型的命令**,先写入,在读取**
参数描述
type表示命令组成的幻(魔)数,也就是8-15位
nr表示命令组成的编号,也就是0-7位
size表示命令组成的参数传递大小,注意这里不是传递数字而是数据类型, 如要传递4字节,就可以写成int
#ifndef _IOC_NONE
# define _IOC_NONE	0U		//0x00
#endif

#ifndef _IOC_WRITE
# define _IOC_WRITE	1U		//0x01
#endif

#ifndef _IOC_READ
# define _IOC_READ	2U		//0x10
#endif

#define _IOC(dir,type,nr,size) \
        (((dir)  << _IOC_DIRSHIFT) | \		// dir << 30
         ((type) << _IOC_TYPESHIFT) | \		// type << 8
         ((nr)   << _IOC_NRSHIFT) | \		//nr << 0
         ((size) << _IOC_SIZESHIFT))		//size << 16

#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),sizeof(size)
#define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))

2、分解宏

宏定义功能
_IOC_DIR(nr)分解命令的方向,也就是 30-31 位的值
_IOC_TYPE(nr)分解命令的魔数,也就是上面的8-15位的值
_IOC_NR(nr)分解命令的编号,也就是上面的0-7位的值
_IOC_SIZE(nr)分解命令的数据大小,也就是上面的16-29位

参数说名 nr 要分解的命令

#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)   
    //(nr>>30)& 0x3
#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) 
    //(nr>>8)& 0xFF
#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)         
    // (nr)&0xFF
#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
    //(nr>>16)&0x3FFF

应用层的ioctl与驱动的ioctrl的参数对应关系

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值