驱动程序中除了需要具备读写的能力外,还需具备对硬件的控制能力。
在用户空间使用ioctl来控制设备,其原型如下
int ioctl(int fd,usnigned long cmd...)
ioctl 驱动实现方法
int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
不使用BLK(大内核锁),将使用以下函数指针代替ioctl
long (*unlocked_ioctl)(struct file*,unsigned int,unsigned long);
64位系统使用以下函数指针代替
long (*compat_ioctl)(struct file*,unsigned int,unsigned long);
ioctl 函数定义命令
ioctl命令被分为几个段,include/asm/ioctl.h中定义了这些字段:类型(幻数)8,基数8,传送方向2,参数大小8~14等
命令的方向字段为两段
_IOC_NONE 无数据传输
_IOC_READ 读
_IOC_WRITE 写
_IOC_READ|WRITE双向
内核提供下面宏来帮助定义命令:
_IO(type,nr) //没有参数的命令
_IOR(type,nr,datatype) //从驱动中读数据
_IOW(type,nr,datatype) //写数据
_IOWR(type,nr,datatype) //双向传送
还定义了用来解开下列各字段的宏
_IOC_(nr) //传输方向
_IOC_ TYPE(nr) //命令类型
_IOC_NR(nr) //序号
_IOC_ SIZE(nr) //用户数据大小
内核中预定义了一些IO控制命令
FIOCLEX:file ioctl close on exec,对文件设置专用标志,通知内核当exec()系统调用发生时自动关闭打开的文件
FIOCLEX: file ioctl not close on exec与上述相反,清除FIOCLEX命令设置的标志
FIOQSIZE: 获得一个文件或者目录的大小,当用于设备文件时,返回一个ENOTTY错误
FIONBIO:file ioctl non-blocking I/O修改在file->f_flags中的O_NONBLOCK标志
上述宏定义命令的值分别为0x5450 0x5451 0x5460 0x5421
参数使用,如果是整数,可直接使用,若是地址,需检测其合法性使用如下函数int access_ok(int type,const void *addr,unsigned long size)
第一个参数是VERIFY_READ或者是VERIFY_WRITE用来表明读用户内存还是写用户内存,addr参数是要操作的地址,size是要操作的长度
返回一个布尔值1是成功,0表示失败