设备驱动程序的一个基本功能就是管理和控制设备,同时为用户应用程序提供管理和控制设备的接口,在Linux
中这个接口是通过ioctl
函数来实现的。
int ( *ioctl ) ( struct inode *, struct file *, unsigned int, unsigned long );
struct inode *
和struct file *
描述了操作的文件,unsigned int
描述了ioctl
命令号,最后一个参数是unsigned long
数据类型,描述了ioctl
命令可能带有的参数,它可能是一个整数或指针数据。
ioctl命令号
ioctl
命令号是这个函数中最重要的参数,它描述的ioctl
要处理的命令。Linux
中使用一个32
位的数据来编码ioctl
命令,它包含四个部分:dir
、type
、nr
和size
。
dir
:代表数据传输的方向,占2
位,可以是_IOC_NONE
(无数据传输,0U
)、_IOC_WRITE
(向设备写数据,1U
)或_IOC_READ
(从设备读数据,2U
)或他们的逻辑或组合,当然只有_IOC_WRITE
和_IOC_READ
的逻辑或才有意义。type
:描述了ioctl
命令的类型,8
位。每种设备或系统都可以指定自己的一个类型号,ioctl
用这个类型来表示ioctl
命令所属的设备或驱动。一般用ASCII
码字符来表示,如a
。nr
:ioctl
命令序号,一般为8
位。对于一个指定的设备驱动,可以对它的ioctl
命令做一个顺序编码,一般从零开始,这个编码就是ioctl
命令的序号。size
:ioctl
命令的参数大小,一般为14
位。ioctl
命令号的这个数据成员不是强制使用的,你可以不使用它,但是我们建议你指定这个数据成员,通过它我们可以检查用户空间数据的大小以避免错误的数据操作,也可以实现兼容旧版本的ioctl
命令。
我们可以自己来直接指定一个ioctl
命令号,它可能仅仅是一个整数集,但Linux
中的ioctl
命令号都是有特定含义的,因此通常我们不推荐这么做。其实Linux
内核已经提供了相应的宏来自动生成ioctl
命令号:
_IO ( type, nr )
_IOR ( type, nr, size )
_IOW ( type, nr, size )
_IOWR ( type