_IO, _IOR, _IOW, _IOWR 宏的用法与解析
转载:http://blog.chinaunix.net/uid-20754793-id-177774.html
今天在写字符驱动验证程序的时候要用到ioctl函数,其中有一个cmd参数,搞了半天也不了解是什么意思,那个cmd还有什么命令码了什么的,还好google下,觉得这篇文章写的不错,就转来看看:
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值。cmd除了可区别数字外,还包含有助于处理的几种相应信息。 cmd的大小为 32位,共分 4 个域:
bit31~bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令。
bit29~bit15 14位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小。
bit20~bit08 8位为 “魔数"(也称为"幻数")区,这个值用以与其它设备驱动程序的 ioctl 命令进行区别。
bit07~bit00 8位为 "区别序号" 区,是区分命令的命令顺序序号。
像 命令码中的 “区分读写区” 里的值可能是 _IOC_NONE (0值)表示无数据传输,_IOC_READ (读), _IOC_WRITE (写) , _IOC_READ|_IOC_WRITE (双向)。
内核定义了 _IO() , _IOR() , IOW() 和 _IOWR() 这 4 个宏来辅助生成上面的 cmd 。下面分析 _IO() 的实现,其它的类似。
在 asm-generic/ioctl.h 里可以看到 _IO() 的定义:
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) |
再看 _IOC() 的定义:
#define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) |
可 见,_IO() 的最后结果由 _IOC() 中的 4 个参数移位组合而成。
再看 _IOC_DIRSHIT 的定义:
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) |
_IOC_SIZESHIFT 的定义:
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) |
_IOC_TYPESHIF 的定义:
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) |
_IOC_NRSHIFT 的定义:
#define _IOC_NRSHIFT 0 |
_IOC_NRBITS 的定义:
#define _IOC_NRBITS 8 |
_IOC_TYPEBITS 的定义:
#define _IOC_TYPEBITS 8 |
由 上面的定义,往上推得到:
引 用_IOC_TYPESHIFT = 8_IOC_SIZESHIFT = 16
_IOC_DIRSHIFT = 30
所以,(dir) << _IOC_DIRSHIFT) 表是 dir 往左移 30 位,即移到 bit31~bit30 两位上,得到方向(读写)的属性;
(size) << _IOC_SIZESHIFT) 位左移 16 位得到“数据大小”区;
(type) << _IOC_TYPESHIFT) 左 移 8位得到"魔数区" ;
(nr) << _IOC_NRSHIFT) 左移 0 位( bit7~bit0) 。
这样,就得到了 _IO() 的宏值。
beyes | 2009-09-26 11:23 |
这几个宏的使用格式为:
魔数 (magic number) 基(序列号)数 基数用于区别各种命令。通常,从 变 量型 变量型使用 arg 变量指定传送的数据大小,但是不直接代入输入,而是代入变量或者是变量的类型,原因是在使用宏创建命令,已经包含了 sizeof() 编译命令。比如 _IOR() 宏的定义是:
而 _IOC_TYPECHECK() 的定义正是:
设 备驱动程序想要从传送的命令获取相应的值,就要使用下列宏函数: _IO 宏 该宏函数没有可传送的变量,只是用于传送命令。例如如下约定:
此时,省略由应用程序传送的 arg 变量或者代入 0 。在应用程序中使用该宏时,比如: ioctl (dev, TEST_DEV_RESET, 0) 或者 ioctl (dev, TEST_DRV_RESET) 。 这是因为变量的有效因素是可变因素。只作为命令使用时,没有必要判 断出设备上数据的输出或输入。因此,设备驱动程序没有必要执行设备文件大开选项的相关处理。 _IOR 宏 该函数用 于创建从设备读取数据的命令,例如可如下约定:
这 说明应用程序从设备读取数据的大小为 int 。下面宏用于判断传送到设备驱动程序的 cmd 命令的读写状态: 运行该宏时,返回值的类型 如下:
使用该命令时,应用程序的 ioctl() 的 arg 变量值指定设备驱动程序上读取数据时的缓存(结构体)地址。 _IOW 宏 用于创建设 备上写入数据的命令,其余内容与 _IOR 相同。通常,使用该命令时,ioctl() 的 arg 变量值指定设备驱动程序上写入数据时的缓存(结构体)地址。 _IOWR 宏 用于创建设备上读写数据的命令。其余内 容与 _IOR 相同。通常,使用该命令时,ioctl() 的 arg 变量值指定设备驱动程序上写入或读取数据时的缓存 (结构体) 地址。 _IOR() , _IOW(), IORW() 的定义 : |
_IO, _IOR, _IOW, _IOWR 宏的用法与解析的更多相关文章
- 完善_IO, _IOR, _IOW, _IOWR 宏的用法与解析
_IO, _IOR, _IOW, _IOWR 宏的用法与解析 原文地址:http://www.eefocus.com/ayayayaya/blog/12-03/245777_20cdd.html 作 ...
- linux内核驱动中_IO, _IOR, _IOW, _IOWR 宏的用法与解析(引用)
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...
- linux内核驱动中_IO, _IOR, _IOW, _IOWR 宏的用法与解析
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...
- Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析【转】
转自:http://blog.csdn.net/hzn407487204/article/details/7995041 在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设 ...
- Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
ref from : http://blog.csdn.net/zhuxiaoping54532/article/details/49680537 main 在驱动程序里, ioctl() 函数上传送 ...
- [宏]_IO, _IOR, _IOW, _IOWR 宏的用法与解析
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...
- Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size) _IOC(_IOC_RE ...
- linux 内核驱动编程 简单例子 与_IO, _IOR, _IOW, _IOWR 宏解析
一._IO, _IOR, _IOW, _IOWR 宏的用法与解析 在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包 ...
- C# yield return 用法与解析
原文:C# yield return 用法与解析 C# yield return 用法与解析 本文参考自:http://www.jb51.net/article/54810.htm 当初没有认真理解 ...
随机推荐
- 预定义宏_GNUC_ _MSC_VER
一.预定义__GNUC__宏 1 __GNUC__ 是gcc编译器编译代码时预定义的一个宏.需要针对gcc编写代码时, 可以使用该宏进行条件编译. 2 __GNUC__ 的值表示gcc的版本.需要针对 ...
- Servlet 2.4 规范之第一篇:概览
写在前面的话: 本系列是对<Java Servlet Specification Version 2.4>的完全翻译,力争但不保证完美表达出英文原文的思想内涵.如有疏漏之处,还 ...
- 咏南多层开发框架支持最新的DELPHI 10 SEATTLE
购买了咏南多层开发框架的老用户如有需要提供免费升级. 中间件
- IIS 7 WAS服务不可用
在 Windows Server 2008 上使用 %windir%\system32\inetsrv\appcmd.exe list wp 命令,得到如下错误: ERROR ( message:WA ...
- input value的值不可改变
同样是东钿微信服务平台,使用积分的问题,原来的版本是,默认用户不使用积分,也就没有给input赋值,后面华总说默认让用户使用积分,于是我就信誓旦旦把从后台得到用户可使用的积分赋在input上,后来,用 ...
- QT输入输出(一) 之 QDataStream 测试
QT提供了两个高级别的流类---QDataStream和QTextStream,可以从任意的输入输出设备读取或写入数据. QDataStream用于读写二进制数据,它的优点是:在读写数据的时候已经严格 ...
- Labeled ContentControl & LabeledControl【项目】
LabeledTextBoxControl: C#定义 using System; using System.Collections.Generic; using System.Linq; using ...
- UI:字典的两种取值的区别
字典的两种取值的区别 (objectForKey: 和 valueForKey )参考 一般来说 key 可以是任意字符串组合,如果 key 不是以 @ 符号开头,这时候 valueForKey: 等 ...
- OC:内存管理、dealloc方法、copy知识点
属性的声明:使⽤@property声明属性 例如:@property NSString *name: 相当于@interface中声明了两个⽅法(setter.getter): 属性的实现:使⽤@s ...
- ActiveMQ简介与安装
开源消息总线 支持JMS1.1和J2EE 1.4规范的 JMS Provider实现(持久化,XA消息,事务) 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去 支持 ...