ioctl系统调用,是用于设备控制的公共接口。
除了读取和写入设备外,驱动程序还需要具备一项能力:执行各种类型的硬件控制。
实现通常是一个基于命令号的switch语句。
原型:
int(*ioctl) (struct inode *inode,struct file *filp,unsigned int cmd,unsigned longarg);
inode、filp:对应应用文件传递的文件描述符fd
cmd:用户空间传递的命令值。
大部分ioctl实现都包括switch语句,根据cmd参数选择对应操作。
arg:可选:无论是指针还是整数,都以unsigned long形式传递
要对不同命令选择不同编号
(
我的理解:为switch中的每个case选择一个独有编号
即ioctl中出现的每一个case对应的语句,都是一个ioctl[i]操作
他们有相同的头编号,说明是一个ioctl函数下的,
尾编号不同来辨别同一个ioctl函数中的不同case(区分ioctl[i])
)
为创建唯一的ioctl命令号,每一个命令好被分为多个为字段。
高8为是与设备相关的幻数,低8位是一个序列号码,设备内唯一。
eg:
#define RELAY_IOC_MAGIC 0x11
#define RELAY_IOC_RESET _IO(RELAY_IOC_MAGIC,0)
#define RELAY_IOC_ON _IO(RELAY_IOC_MAGIC,1)
#define RELAY_IOC_OFF _IO(RELAY_IOC_MAGIC,2)
static int relay_dev_ioctl(struct inode* inode,struct file*filp,unsigned int cmd,unsigned long arg){
int retval = 0;
switch(cmd){
case RELAY_IOC_RESET:
//
break;
case RELAY_IOC_ON:
/*
s3c2410_gpio_cfgpin(DQ,CFG_OUT);
s3c2410_gpio_setpin(DQ,1);
printk(KERN_ALERT"******RELAY ON******\n");
*/
break;
case RELAY_IOC_OFF:
/*
s3c2410_gpio_cfgpin(DQ,CFG_OUT);
s3c2410_gpio_setpin(DQ,0);
printk(KERN_ALERT"******RELAY OFF******\n");
*/
break;
default:
return -ENOTTY;
}
return retval;
}