Linux设备驱动--第六章 ioctl接口

首先,我们先看看什么叫ioctl接口。从字面上看,可以说成是一种用户对设备进行控制的接口,比如说,《ldd》里说到---- 

-------------------------------------------------------------------------------- 

大部分驱动需要 -- 除了读写设备的能力 -- 通过设备驱动进行各种硬件控制的能力. 大部分设备可进行超出简单的数据传输之外的操作; 用户空间必须常常能够请求, 例如, 设备锁上它的门, 弹出它的介质, 报告错误信息, 改变波特率, 或者自我销毁. 这些操作常常通过 ioctl 方法来支持, 它通过相同名子的系统调用来实现. 



-------------------------------------------------------------------------------- 


ioctl接口,是用户空间和内核空间进行交换的方式。它是一种命令形式的存在。 

ioctl 驱动方法有和用户空间版本不同的原型: 



int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); 


inode 和 filp 指针是对应应用程序传递的文件描述符 fd 的值, 和传递给 open 方法的相同参数. cmd 参数从用户那里不改变地传下来, 并且可选的参数 arg 参数以一个 unsigned long 的形式传递, 不管它是否由用户给定为一个整数或一个指针. 如果调用程序不传递第 3 个参数, 被驱动操作收到的 arg 值是无定义的. 因为类型检查在这个额外参数上被关闭, 编译器不能警告你如果一个无效的参数被传递给 ioctl, 并且任何关联的错误将难以查找. 

如果你可能想到的, 大部分 ioctl 实现包括一个大的 switch 语句来根据 cmd 参数, 选择正确的做法. 不同的命令有不同的数值, 它们常常被给予符号名来简化编码. 符号名通过一个预处理定义来安排. 定制的驱动常常声明这样的符号在它们的头文件中; scull.h 为 scull 声明它们. 用户程序必须, 当然, 包含那个头文件来存取这些符号. 



-------------------------------------------------------------------------------- 


选择ioctl 命令 



-------------------------------------------------------------------------------- 


(以下文字全部摘抄) 

在编写ioctl代码之前,需要选择对应不同命令的编号。为了防止对错误的设备使用正确的命令,命令号应该在系统范围内唯一,这种错误匹配并不是不会发生,程序可能发现自己正在试图对FIFO和audio等这类非串行设备输入流修改波特率,如果每一个ioctl命令都是唯一的,应用程序进行这种操作时就会得到一个EINVAL错误,而不是无意间成功地完成了意想不到的操作。 

要按Linux内核的约定方法为驱动程序选择ioctl编号,应该首先看看include/asm/ioctl.h和Doucumention/ioctl-number.txt这两个文件。头文件定义了要使用的位字段:类型(幻数)、序数、传送方向以及参数大小等。ioctl-number.txt文件中罗列了内核所使用的幻数,选择自己的幻数要避免和内核冲突。 


#define _IOC_NRBITS 8 //序数(number)字段的字位宽度,8bits 

#define _IOC_TYPEBITS 8 //幻数(type)字段的字位宽度,8bits 

#define _IOC_SIZEBITS 14 //大小(size)字段的字位宽度,14bits 

#define _IOC_DIRBITS 2 //方向(direction)字段的字位宽度,2bits 


#define _IOC_NRMASK ((1 //序数字段的掩码,0x000000FF 

#define _IOC_TYPEMASK ((1 //幻数字段的掩码,0x000000FF 

#define _IOC_SIZEMASK ((1 //大小字段的掩码,0x00003FFF 

#define _IOC_DIRMASK ((1 //方向字段的掩码,0x00000003 


#define _IOC_NRSHIFT 0 //序数字段在整个字段中的位移,0 

#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //幻数字段的位移,8 

#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) //大小字段的位移,16 

#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //方向字段的位移,30 


%2 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值