Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66794
  • 博文数量: 14
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-20 10:58
文章分类
文章存档

2010年(5)

2009年(9)

我的朋友

分类: 嵌入式

2009-11-20 14:41:09

设备的控制函数ioctl
 
设备除了具备读写能力外,还需要具备进行各种文件的控制功能,而这种功能通常需要ioctl来实现。
驱动程序的ioctl方法原型:
int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg);
其中:cmd 由用户空间直接传递给驱动程序, arg 不论用户程序使用的是指针还是整数值,都以 unsigned long 的形式传递给驱动程序。
 
ioctl特征:
  • 类似与read 和write 函数,可执行写入和读取操作;
  • 用于控制硬件或获取状态信息;
  • 应用程序命令不同,设备驱动程序中对变量的解释也不同;

编写驱动程序中ioctl的步骤:

  1. 选择ioctl命令:命令编号为32位数,分为四个段如下表:

 31-30  29-16 15-8  7-0
 direction(2bits)  size(14bits)  type(8bits)  number(8bits)

新的符号都定义在linux/ioctl.h :  中。

_IO(type,nr)/*没有参数的命令*/
_IOR(type, nr, datatype)/*从驱动中读数据*/
_IOW(type,nr,datatype)/*写数据*/
_IOWR(type,nr,datatype)/*双向传送*/
/*type number 成员作为参数被传递, 并且 size 成员通过应用 sizeof datatype 参数而得到*/

 

在使用switch之前,对cmd进行有效检验,如果检验无效返回:-ENOTTY

以及通过函数access_ok验证指向用户空间的地址是否合法,不合法返回:-EINVAL

int err = 0, tmp;
 int retval = 0;
   
 /*
  * extract the type and number bitfields, and don't decode
  * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
  */
 if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY;
 if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY;

 /*
  * the direction is a bitmask, and VERIFY_WRITE catches R/W
  * transfers. `Type' is user-oriented, while
  * access_ok is kernel-oriented, so the concept of "read" and
  * "write" is reversed
  */
 if (_IOC_DIR(cmd) & _IOC_READ)
  err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
 else if (_IOC_DIR(cmd) & _IOC_WRITE)
  err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
 if (err) return -EFAULT;

接下来就要根据不同的设备对各种命令进行实现.

*******************************************************

文件头有: //ioctl  构造命令编号的各种宏

  // access_ok, put_user __put_user copy_to_user

// get_user  __get_user   copy_from_user

//系统能够理解的所有权能

//capable  权能的检查

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

chinaunix网友2009-11-28 11:40:43

en