红联Linux门户
Linux帮助

linux驱动ioctl函数

发布时间:2016-08-16 14:53:03来源:linux网站作者:痞子晶
一、ioctl的简介:
虽然在文件操作结构体"structfile_operations"中有很多对应的设备操作函数,但是有些命令是实在找不到对应的操作函数。如CD-ROM的驱动,想要一个弹出光驱的操作,这种操作并不是所有的字符设备都需要的,所以文件操作结构体也不会有对应的函数操作。
出于这样的原因,ioctl就有它的用处了————一些没办法归类的函数就统一放在ioctl这个函数操作中,通过指定的命令来实现对应的操作。所以,ioctl函数里面都实现了多个的对硬件的操作,通过应用层传入的命令来调用相应的操作。
简单介绍一下函数:
int (*ioctl) (struct inode * node, structfile *filp, unsigned int cmd, unsigned long arg);
参数:
1)inode和file:ioctl的操作有可能是要修改文件的属性,或者访问硬件。要修改
文件属性的话,就要用到这两个结构体了,所以这里传来了它们的指针。
2)cmd:命令,接下来要长篇大论地说。
3)arg:参数,接下来也要长篇大论。
返回值:
1)如果传入的非法命令,ioctl返回错误号-EINVAL。
2)内核中的驱动函数返回值都有一个默认的方法,只要是正数,内核就会傻乎乎的认为这是正确的返回,并把它传给应用层,如果是负值,内核就会认为它是错误号了。
Ioctl里面多个不同的命令,那就要看它函数的实现来决定返回值了。打个比方,如果ioctl里面有一个类似read的函数,那返回值也就可以像read一样返回。
当然,不返回也是可以的。
 
二、ioctl中的cmd
一个cmd被分为了4个段,每一段都有各自的意义,cmd的定义在。注:但实际上中只是包含了,这说明了这是跟平台相关的,ARM的定义在,但这文件也是包含别的文件,千找万找,终于找到了。
解释一下四部分,全部都在和ioctl-number.txt这两个文档有说明。
1)幻数:说得再好听的名字也只不过是个0~0xff的数,占8bit(_IOC_TYPEBITS)。这个数是用来区分不同的驱动的,像设备号申请的时候一样,内核有一个文档给出一些推荐的或者已经被使用的幻数。
2)序数:用这个数来给自己的命令编号,占8bit(_IOC_NRBITS),我的程序从1开始排序。
3)数据传输方向:占2bit(_IOC_DIRBITS)。如果涉及到要传参,内核要求描述一下传输的方向,传输的方向是以应用层的角度来描述的。
01)_IOC_NONE:值为0,无数据传输。
02)_IOC_READ:值为1,从设备驱动读取数据。
03)_IOC_WRITE:值为2,往设备驱动写入数据。
04)_IOC_READ|_IOC_WRITE:双向数据传输。
4)数据大小:与体系结构相关,ARM下占14bit(_IOC_SIZEBITS),如果数据是int,内核给这个赋的值就是sizeof(int)。
 
源代码:
//用户调用ioctl时,驱动的此接口会被调用  
static long hello_unlocked_ioctl(struct file *pfile,  
unsigned int cmd, unsigned long arg)  
{  
long ret;  
ret = 1234; // 测试返回值  
switch (cmd) {  
case CMD_0:  
printk(KERN_INFO "cmd = %d \n", cmd);  
break;  
case CMD_1:  
printk("cmd = %d arg=%lu \n", cmd, arg);  
break;  
default:   
printk(KERN_WARNING "no such command! \n");  
break;  
}  
return ret;  
}  
struct file_operations hello_ops = {  
.owner = THIS_MODULE,  
.open = hello_open,  
.release = hello_release,  
.read = hello_read,  
.write = hello_write,  
.unlocked_ioctl = hello_unlocked_ioctl,  
};
 
本文永久更新地址:http://www.linuxdiyf.com/linux/23358.html