在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值。cmd除了可区别数字外,还包含有助于处理的几种相应信息。 cmd的大小为 32位,共分 4 个域:

bit31~bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令。
bit29~bit16 14位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小。

bit15~bit08 8位为 “魔数"(也称为"幻数")区,这个值用以与其它设备驱动程序的 ioctl 命令进行区别。

bit07~bit00 8位为 "区别序号" 区,是区分命令的命令顺序序号。

内核定义了 _IO() , _IOR() , IOW() 和 _IOWR() 这 4 个宏来辅助生成上面的 cmd

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

命令码中的 “区分读写区” 里的值可能是 _IOC_NONE (0值)表示无数据传输,_IOC_READ (读), _IOC_WRITE (写) , _IOC_READ|_IOC_WRITE (双向)。

#define _IO(type,nr)     _IOC(_IOC_NONE,(type),(nr),0)
#define _IOC(dir,type,nr,size) \(((dir)  << _IOC_DIRSHIFT) | \((type) << _IOC_TYPESHIFT) | \((nr)   << _IOC_NRSHIFT) | \((size) << _IOC_SIZESHIFT))#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)#define _IOC_NRBITS  8
#define _IOC_TYPEBITS   8
# define _IOC_SIZEBITS  14

宏展开后

#define _IO(type,nr)         (((_IOC_NONE)  << 30) | ((0) << 16)) | ((type) << 8) | ((nr)   << 0)

(dir) << _IOC_DIRSHIFT) dir 往左移 30 位,即移到 bit31~bit30 两位上,得到方向(读写)的属性;
(size) << _IOC_SIZESHIFT) size左移 16 位得到“数据大小”区;
(type) << _IOC_TYPESHIFT) type左移 8位得到"魔数区" ;
(nr) << _IOC_NRSHIFT) nr左移 0 位( bit7~bit0) "得到基数区";

这几个宏的使用格式为:
_IO (魔数, 基数);
_IOR (魔数, 基数, 变量型)
_IOW (魔数, 基数, 变量型)
_IOWR (魔数, 基数,变量型 )

魔数 (magic number)

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

_IOC_TYPE (cmd)

基(序列号)数

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

_IOC_NR (cmd)

变量型

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

#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))

而_IOC_TYPECHECK() 的定义正是:

#define _IOC_TYPECHECK(t) (sizeof(t))

设备驱动程序想要从传送的命令获取相应的值,就要使用下列宏函数:

_IOC_SIZE(cmd)

_IO 宏

该宏函数没有可传送的变量,只是用于传送命令。例如如下约定:
#define TEST_DRV_RESET _IO ('Q', 0)
此时,省略由应用程序传送的 arg 变量或者代入 0 。在应用程序中使用该宏时,比如:
ioctl (dev, TEST_DEV_RESET, 0) 或者 ioctl (dev, TEST_DRV_RESET) 。
这是因为变量的有效因素是可变因素。只作为命令使用时,没有必要判 断出设备上数据的输出或输入。因此,设备驱动程序没有必要执行设备文件大开选项的相关处理。

_IOR 宏

该函数用 于创建从设备读取数据的命令,例如可如下约定:
#define TEST_DEV_READ _IRQ('Q', 1, int)
这说明应用程序从设备读取数据的大小为 int 。下面宏用于判断传送到设备驱动程序的 cmd 命令的读写状态:
_IOC_DIR (cmd)
运行该宏时,返回值的类型 如下:
_IOC_NONE : 无属性
_IOC_READ : 可读属性
_IOC_WRITE : 可写属性
_IOC_READ | _IOC_WRITE : 可读,可写属性
使用该命令时,应用程序的 ioctl() 的 arg 变量值指定设备驱动程序上读取数据时的缓存(结构体)地址。

_IOW 宏

用于创建设 备上写入数据的命令,其余内容与 _IOR 相同。通常,使用该命令时,ioctl() 的 arg 变量值指定设备驱动程序上写入数据时的缓存(结构体)地址。

_IOWR 宏

用于创建设备上读写数据的命令。其余内 容与 _IOR 相同。通常,使用该命令时,ioctl() 的 arg 变量值指定设备驱动程序上写入或读取数据时的缓存 (结构体) 地址。

Linux IO控制命令生成相关推荐

  1. linux直接控制IO叫,Linux IO控制命令生成

    在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...

  2. linux 命令读db文件格式,使用linux的db_load命令生成db数据库

    使用linux的db_load命令生成db数据库 发布时间:2020-07-22 10:17:25 来源:亿速云 阅读:113 作者:清晨 栏目:服务器 不懂使用linux的db_load命令生成db ...

  3. Linux下使用命令生成二维码

    首先在保证linux联网的情况下安装 qrencode yum -y install qrencode 使用命令生成二维码(-s 后面的数字是二维码的大小 这里的18 是 18*18) qrencod ...

  4. 玩转Linux进程控制命令

    目录 1.0查看系统中的进程命令 1.1 ps命令 1.2 top命令 2.0 控制系统中的进程命令 2.1 kill命令 2.2 killall 命令 2.3 nice 命令 2.4 renice命 ...

  5. linux 声音控制 命令,linux 声音大小调整的命令

    alsamixer 输入上面的命令 回车即可看到图形界面,界面如下 ┌──────────────────────────── AlsaMixer v1.0.27.1 ──────────────── ...

  6. linux使用dd命令生成指定大小文件

    dd命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1000M的test文件,文件内容为全0(因从/dev/zero ...

  7. linux 声音控制 命令,命令行下调整声音大小

    命令行下调整声音大小 发布时间:2010-05-26 20:03:16来源:红联作者:wangyu 首先感谢熊猫大侠(haibian). 我用的系统是MagicLinux,一个国内Fedora的山寨版 ...

  8. Linux之tree命令生成文件目录结构

    在写博客的过程中,看到别人有添加目录结构的好习惯,觉得效果很好,如图所示,查找得知是使用tree指令来生成的,因此对tree的使用方法进行总结 首先先验证一下是否安装了tree,如果没有安装,只需要运 ...

  9. linux io复用命令,Linux中IO多路复用机制

    之前的面试有问到主线程在 ActivityThread 里初始化 Looper 后调用了 Looper.loop() 这个死循环为什么不会阻塞主线程,当时回答因为在 Looper.loop() 方法里 ...

最新文章

  1. 关于位运算的错误问题
  2. php mysql修改命令_PHP编程:mysql alter table命令修改表结构实例详解
  3. mysql创建非聚集索引_聚集索引和非聚集索引的区别
  4. 阿里云高级技术专家:面向5G的云网一体及云原生应用实践
  5. 开启ssh不能用root登入的限制
  6. 相对路径和绝对路径概念
  7. python报错:No such file or directory: ‘D:\\Anaconda3\\lib\\venv\\scripts\\nt\\python.exe‘
  8. 导入csv_使用ADManager Plus从CSV批量导入用户
  9. 《shell脚本学习指南》自学笔记——入门
  10. Wireshark通过TCP协议抓取QQ好友IP以及定位
  11. 【011】Excel宏编程相关封装模块(新建文件、关闭文件、新增/删除工作薄)_004_#VBA
  12. 用无线热点入门树莓派4详解
  13. 【概率论】Laplace 分布 / Laplace Distribution
  14. 快速解决Ubuntu缺少各种驱动的方法: 解决ThinkPad T14s没有无线网卡驱动以及WIFI无法连接等驱动问题
  15. win7计算机无法连接投影仪,联想笔记本win7系统连接投影仪的方法【图文详解】...
  16. 中国 SaaS 二十年的回顾
  17. 中山大学HCP Lab系列论文:AI解题新突破,神经网络推开数学推理大门
  18. can通讯bdc_纯电动汽车网络总线 数据通信网络连接系统介绍
  19. RecyclerView StaggeredGridLayoutManager瀑布流实现中遇到的问题
  20. c语言实现数字华容道编程,【JIONEY】掌控版+遥传感器 实现数字华容道小游戏...

热门文章

  1. 设置grub从哪个分区的menu.lst引导系统
  2. 华为机试HJ83:二维数组操作
  3. 拉格朗日中值定理ξ怎么求_微分学核心定理——中值定理
  4. 测试自己幸运数字的软件,心理测试:4个数字哪个是你的幸运数字?测试你的心理年龄!...
  5. 怎么只要小数部分C语言,如何得出一个浮点数的小数部分,要把各个位保存到一个数组里边。...
  6. 功能测试——测试流程1
  7. char flag[20]c语言,C语言试卷
  8. CSS基础——CSS复合选择器【学习笔记】
  9. Mongo查询数据库及表占用磁盘大小
  10. 软件测试开发人员的价值如何体现?