IOCTL接口主要用来进行I/O控制,应用程序可以通过IOCTL接口向设备发送命令、参数设置等信息。file_operations结构中对应的IOCTL接口函数原型如下:
long(*unlocked_ioctl)(struct file*file,unsigned int cmd,unsigned long arg);
其中cmd是命令类型,arg是参数。
例1.6 字符设备IOCTL实例
代码见\samples\1door\1-5ioctl。核心代码如下所示:
接下来编写一个应用程序,参考代码如下:
本例运行结果如下:
[root@urbetter/home]#insmod demo.ko
[root@urbetter/home]#mknod/dev/fgj c 2240
[root@urbetter/home]#./test
open/dev/fgj successfully
send command1 successfully
send command2 successfully
unlocked_ioctl函数中的命令参数cmd不能随意定义,有一些值已经被系统使用,就不能在设备驱动中使用,否则会发生冲突。例如:
内核代码/fs/ioctl.c中的do_vfs_ioctl函数对这些特殊的cmd做了处理:
实际上,IOCTL接口中的cmd参数每个位都有特殊的含义,见表1-1。(www.xing528.com)
表1-1 cmd参数每个位的含义
TYPE范围为0~255,通常用英文字符"A"~"Z"或者"a"~"z"来表示。设备驱动程序从传递进来的命令获取TYPE,然后与自身能处理的TYPE进行比较,如果相同则处理,不同则不处理。用于创建IOCTL接口命令的宏包括:
#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_IOR_BAD(type,nr,size)_IOC(_IOC_READ,(type),(nr),sizeof(size))
#define_IOW_BAD(type,nr,size)_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define_IOWR_BAD(type,nr,size)_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
用于解码IOCTL命令的宏包括:
#define_IOC_DIR(nr)(((nr)>>_IOC_DIRSHIFT)&_IOC_DIRMASK)
#define_IOC_TYPE(nr)(((nr)>>_IOC_TYPESHIFT)&_IOC_TYPEMASK)
#define_IOC_NR(nr)(((nr)>>_IOC_NRSHIFT)&_IOC_NRMASK)
#define_IOC_SIZE(nr)(((nr)>>_IOC_SIZESHIFT)&_IOC_SIZEMASK)
下面是音频驱动中的几个IOCTL命令的组装示例:
#define SNDRV_TIMER_IOCTL_INFO_IOR('T',0x11,struct snd_timer_info)
#define SNDRV_TIMER_IOCTL_PARAMS_IOW('T',0x12,struct snd_timer_params)
#define SNDRV_TIMER_IOCTL_STATUS_IOR('T',0x14,struct snd_timer_status)
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。