好好学习,天天向上
分类: LINUX
2011-04-08 12:13:57
驱动提供read,write是为了和应用程序进行数据的交流,应用程序也可以简单地发送相关命令给驱动执行,如LED驱动点亮LED的命令。一般而言,这些是通过IOCTL实现的。
用户空间的ioctl:
#include
int ioctl(int fildes, int request, ... /* arg */);
驱动使用不同的版本:
linux/fs.h
int (*ioctl) (struct inode* inode,struct file* filp,unsigned int cmd,unsigned long param);
当接到不正确的cmd时,应当返回-ENOTTY
做个最简单的ioctl
base_char.c(添加ioctl的实现,并将ioctl添加到file_operations)
int base_char_ioctl(struct inode* inode,struct file* filp,unsigned int cmd,unsigned long param)
{
printk("base char: ioctl : cmd : %d\n",cmd);
switch(cmd)
{
case 0:
/*do some thing*/
break;
case 1:
/*do some thing*/
break;
default:
/*do some thing*/
return -NOTTY;
}
return 0;
}
struct file_operations fop=
{
.owner=THIS_MODULE,
.open=base_char_open,
.release=base_char_release,
.ioctl=base_char_ioctl,
};
test.c
#include
#include
#include
#include
#include
#include
int main()
{
int fd=open("/dev/base_char",O_RDWR);
int count=0;
if(fd<0)
{
perror("");
return -1;
}
ioctl(fd,0,0);
close(fd);
return 0;
}
测试结果如下(系统日志中):
Apr 8 10:39:03 localhost kernel: base char register successful!
Apr 8 10:39:05 localhost kernel: base char open!
Apr 8 10:39:05 localhost kernel: base char: ioctl : cmd : 0
Apr 8 10:39:05 localhost kernel: base char close!
我无法想像向错误的设备发出正确的命令这种情形的实现,但是内核开发者既然提出了,那这样的事情是可能存在的。避免造成损失,内核提供了让我们的cmd在系统中唯一的方法,使用魔数(也有叫幻数的).
下面介绍怎么构造一个唯一的cmd.
linux/ioctl.h
type:number: direction: size
type是魔数,8位,在参考Documentation/ioctl-number.txt后选择一个唯一没有使用的。
number命令序号,8位
direction:数据传输方向,可以是_IOC_NONE,_IOC_READ,_IOC_WRITE
size:数据大小,13或14位,可以忽略,好处是可以检测应用程序的错误
开始建立cmd:
_IO(type,number)(给没有参数的命令)
_IOR(type, number, size)(给从驱动中读数据的)
_IOW(type, number,size) (给写数据)
_IOWR(type, number,size)(给双向传送)
我选择的魔数是 ‘o’,那么我的cmd这样来建立
#define BASE_CHAR_TYPE ‘o’
#define BASE_CHAR_CMD_READ _IOR(BASE_CHAR_TYPE,0,1)
#define BASE_CHAR_CMD_WRITE _IOW(BASE_CHAR_TYPE,1,1)
把这些宏定义放到驱动和应用程序中就可以使用了。
不要以为每个命令都可以使用,事实上在调用ioctl之前内核会自己处理下,它留了一些自己使用的cmd,如果你的正好和它预留的一样,那就悲剧了,你不会看到任何的给那个命令的请求, 并且应用程序获得某些不期望的东西。
FIOCLEX
设置 close-on-exec 标志(File IOctl Close on EXec) 设置这个标志使文件描述符被关闭。
FIONCLEX
清除 close-no-exec 标志(File IOctl Not CLose on EXec)
FIOQSIZE
这个命令返回一个文件或者目录的大小; 当用作一个设备文件,它返回一个 ENOTTY 错误.