Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法

#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)))

ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值。cmd除了可区别数字外,还包含有助于处理的几种相应信息。 cmd的大小为 32位,共分 4 个域:
     bit31~bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令。
     bit29~bit15 14位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小。
     bit20~bit08  8位为 “魔数"(也称为"幻数")区,这个值用以与其它设备驱动程序的 ioctl 命令进行区别。
     bit07~bit00   8位为 "区别序号" 区,是区分命令的命令顺序序号。

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

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

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

在使用_IOR()、_IOW ()、_IOWR()时,ioctl() 的 arg 变量值指定设备驱动程序上写入或读取数据时的缓存 (结构体) 地址。即第三个参数是由ioctl()函数的第三个参数决定的,不需要用户来填写,只需要指定类型即可。

原文地址:https://www.cnblogs.com/leo0621/p/9138502.html

时间: 2024-10-04 16:46:15

Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法的相关文章

linux内核驱动中_IO, _IOR, _IOW, _IOWR 宏的用法与解析

在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个域:     bit31~bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令.     bit29~bit15 14位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小.     bit20~bit08  8位为 “魔数"(也称为&q

_IO, _IOR, _IOW, _IOWR 宏的用法与解析

今天在写字符驱动验证程序的时候要用到ioctl函数,其中有一个cmd参数,搞了半天也不了解是什么意思,那个cmd还有什么命令码了什么的,还好google下,觉得这篇文章写的不错,就转来看看:在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个域: bit31~bit30 2位为 “区别读写” 区,作用是区分是读取命令还是写入命令. bit29~bit

Linux 内核中 likely 与 unlikely 的宏定义解析

在 2.6 内核中,随处可以见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么区别? 首先要明确: if(likely(value)) 等价于 if(value) if(unlikely(value)) 也等价于 if(value) 也就是说 likely() 和 unlikely() 从阅读和理解代码的角度来看,是一样的!!! #define likely(x) __builtin_expect((x),1) #define unlikely(x) _

(六)linux内核中的offsetof与container_of宏

参考: offsetof与container_of宏[总结] #define offsetof(type, member) (size_t)&(((type*)0)->member) #define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );}) 原文地

(十)Linux内核中的常用宏container_of

Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Container_of的定义如下: #define OffsetOf(type, member) ((unsigned long) &(((type *)0)->member)) #define container_of(p, type, member)  ((type *) ((char *)(p) - O

linux内核中的宏ffs(x)【转】

转自:https://www.cnblogs.com/fengeryi/p/3449720.html linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) static inline int fls(int x) { int ret; if (__builtin_constant_p(x)) r

Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解

在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; /***second***/susecond_t tv_usec;/***microsecond***/}到底microsecond是毫秒还是微秒?? 1秒=1000毫秒(3个零),1秒=1000 000微秒(6个零),1秒=1000 000 000纳秒(9个零),1秒=1000 000 000

向linux内核中添加外部中断驱动模块

本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内核中添加外部中断驱动模块.7.完整驱动程序代码.linux的内核版本为linux2.6.32.2. 一.linux模块的框架以及混杂设备相关知识 1.内核模块的框架如下图所示,其中module_init()(图中有误,不是modules_init)只有在使用insmod命令手动加载模块时才会被调用,

Linux内核中的软中断、tasklet和工作队列详解

[TOC] 本文基于Linux2.6.32内核版本. 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom half)演变而来.下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者. 介绍这三种下半部实现之前,有必要说一下上半部与下半部的区别. 上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务.举个例子:在网络传输中,网卡接收到数据包这