Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141815
  • 博文数量: 20
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 876
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-09 10:56
文章分类

全部博文(20)

文章存档

2013年(20)

我的朋友

分类: LINUX

2013-04-11 11:06:14

      参考了一部分网上内容

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

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

先看此位字段的图示:

以下是对include/asm/ioctl.h中定义的宏的注释:

#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 << _IOC_NRBITS)-1)     //序数字段的掩码,0x000000FF

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

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

#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-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

/*

* Direction bits.

*/

#define _IOC_NONE    0U     //没有数据传输

#define _IOC_WRITE   1U     //向设备写入数据,驱动程序必须从用户空间读入数据

#define _IOC_READ    2U     //从设备中读取数据,驱动程序必须向用户空间写入数据

/*

*_IOC 宏将dirtypenrsize四个参数组合成一个cmd参数,如下图:

*/

以上宏定义分别定义了各字段的大小,操作掩码和偏移量等信息,为其具体操作提供了便捷。

阅读(2195) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~