Linux IO控制命令生成
在驱动程序里, 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" 来表示。设备驱动程序从传递进来的命令获取魔数,然后与自身处理的魔数想比较,如果相同则处理,不同则不处理。魔数是拒绝误使用的初步辅助状态。不同的设备驱动程序最好设置不同的魔数,但并不是要求绝对,也是可以使用其他设备驱动程序已用过的魔数。设备驱动程序获取魔数:
基(序列号)数
基数用于区别各种命令。通常,从 0开始递增,相同设备驱动程序上可以重复使用该值。例如,读取和写入命令中使用了相同的基数,设备驱动程序也能分辨出来,原因在于设备驱动程序区分命令时 使用 switch ,且直接使用命令变量 cmd值。创建命令的宏生成的值由多个域组合而成,所以即使是相同的基数,也会判断为不同的命令。设备驱动程序获取该基数:
变量型
变量型使用 arg 变量指定传送的数据大小,但是不直接代入输入,而是代入变量或者是变量的类型,原因是在使用宏创建命令,已经包含了 sizeof() 编译命令。比如 _IOR() 宏的定义是:
而_IOC_TYPECHECK() 的定义正是:
设备驱动程序想要从传送的命令获取相应的值,就要使用下列宏函数:
_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控制命令生成相关推荐
- linux直接控制IO叫,Linux IO控制命令生成
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...
- linux 命令读db文件格式,使用linux的db_load命令生成db数据库
使用linux的db_load命令生成db数据库 发布时间:2020-07-22 10:17:25 来源:亿速云 阅读:113 作者:清晨 栏目:服务器 不懂使用linux的db_load命令生成db ...
- Linux下使用命令生成二维码
首先在保证linux联网的情况下安装 qrencode yum -y install qrencode 使用命令生成二维码(-s 后面的数字是二维码的大小 这里的18 是 18*18) qrencod ...
- 玩转Linux进程控制命令
目录 1.0查看系统中的进程命令 1.1 ps命令 1.2 top命令 2.0 控制系统中的进程命令 2.1 kill命令 2.2 killall 命令 2.3 nice 命令 2.4 renice命 ...
- linux 声音控制 命令,linux 声音大小调整的命令
alsamixer 输入上面的命令 回车即可看到图形界面,界面如下 ┌──────────────────────────── AlsaMixer v1.0.27.1 ──────────────── ...
- linux使用dd命令生成指定大小文件
dd命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1000M的test文件,文件内容为全0(因从/dev/zero ...
- linux 声音控制 命令,命令行下调整声音大小
命令行下调整声音大小 发布时间:2010-05-26 20:03:16来源:红联作者:wangyu 首先感谢熊猫大侠(haibian). 我用的系统是MagicLinux,一个国内Fedora的山寨版 ...
- Linux之tree命令生成文件目录结构
在写博客的过程中,看到别人有添加目录结构的好习惯,觉得效果很好,如图所示,查找得知是使用tree指令来生成的,因此对tree的使用方法进行总结 首先先验证一下是否安装了tree,如果没有安装,只需要运 ...
- linux io复用命令,Linux中IO多路复用机制
之前的面试有问到主线程在 ActivityThread 里初始化 Looper 后调用了 Looper.loop() 这个死循环为什么不会阻塞主线程,当时回答因为在 Looper.loop() 方法里 ...
最新文章
- 关于位运算的错误问题
- php mysql修改命令_PHP编程:mysql alter table命令修改表结构实例详解
- mysql创建非聚集索引_聚集索引和非聚集索引的区别
- 阿里云高级技术专家:面向5G的云网一体及云原生应用实践
- 开启ssh不能用root登入的限制
- 相对路径和绝对路径概念
- python报错:No such file or directory: ‘D:\\Anaconda3\\lib\\venv\\scripts\\nt\\python.exe‘
- 导入csv_使用ADManager Plus从CSV批量导入用户
- 《shell脚本学习指南》自学笔记——入门
- Wireshark通过TCP协议抓取QQ好友IP以及定位
- 【011】Excel宏编程相关封装模块(新建文件、关闭文件、新增/删除工作薄)_004_#VBA
- 用无线热点入门树莓派4详解
- 【概率论】Laplace 分布 / Laplace Distribution
- 快速解决Ubuntu缺少各种驱动的方法: 解决ThinkPad T14s没有无线网卡驱动以及WIFI无法连接等驱动问题
- win7计算机无法连接投影仪,联想笔记本win7系统连接投影仪的方法【图文详解】...
- 中国 SaaS 二十年的回顾
- 中山大学HCP Lab系列论文:AI解题新突破,神经网络推开数学推理大门
- can通讯bdc_纯电动汽车网络总线 数据通信网络连接系统介绍
- RecyclerView StaggeredGridLayoutManager瀑布流实现中遇到的问题
- c语言实现数字华容道编程,【JIONEY】掌控版+遥传感器 实现数字华容道小游戏...
热门文章
- 设置grub从哪个分区的menu.lst引导系统
- 华为机试HJ83:二维数组操作
- 拉格朗日中值定理ξ怎么求_微分学核心定理——中值定理
- 测试自己幸运数字的软件,心理测试:4个数字哪个是你的幸运数字?测试你的心理年龄!...
- 怎么只要小数部分C语言,如何得出一个浮点数的小数部分,要把各个位保存到一个数组里边。...
- 功能测试——测试流程1
- char flag[20]c语言,C语言试卷
- CSS基础——CSS复合选择器【学习笔记】
- Mongo查询数据库及表占用磁盘大小
- 软件测试开发人员的价值如何体现?