Linux IO节制号令天生
来源:长沙it培训学院|发布时间:2016-05-21|浏览量:
摘要:在驱动法式里, ioctl() 函数上传送的变量 cmd 是应用法式用于辨别配备驱动法式请求处置内容的值。cmd除可辨别数字外,还包括有助于处置的几种响应信息。在驱动法式里, 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)))
#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 (双向)。
[cpp]view plaincopyprint?
#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(_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宏睁开后[cpp]view plaincopyprint?
#define _IO(type,nr) (((_IOC_NONE) 30) | ((0) 16)) | ((type) 8) | ((nr) 0)
#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 (魔数, 基数,变量型 )
_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 变量值指定配备驱动法式上写进或读取数据时的缓存 (规划体) 地址。
扫码关注微信公众号了解更多详情
跟技术大咖,专业导师一起交流学习