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

在用户空间, ioctl 系统调用有下面的原型: int ioctl(int fd, unsigned long cmd, ...);

这个原型由于这些点而凸现于 Unix 系统调用列表, 这些点常常表示函数有数目不定的参 数. 在实际系统中, 但是, 一个系统调用不能真正有变数目的参数. 系统调用必须有一个 很好定义的原型, 因为用户程序可存取它们只能通过硬件的"门". 因此, 原型中的点不表 示一个变数目的参数, 而是一个单个可选的参数, 传统上标识为 char *argp. 这些点在 那里只是为了阻止在编译时的类型检查. 第 3 个参数的实际特点依赖所发出的特定的控 制命令( 第 2 个参数 ). 一些命令不用参数, 一些用一个整数值, 以及一些使用指向其 他数据的指针. 使用一个指针是传递任意数据到 ioctl 调用的方法; 设备接着可与用户 空间交换任何数量的数据.

ioctl 调用的非结构化特性使它在内核开发者中失宠. 每个 ioctl 命令, 基本上, 是一 个单独的, 常常无文档的系统调用, 并且没有方法以任何类型的全面的方式核查这些调用. 也难于使非结构化的 ioctl 参数在所有系统上一致工作; 例如, 考虑运行在 32-位模式 的一个用户进程的 64-位 系统. 结果, 有很大的压力来实现混杂的控制操作, 只通过任 何其他的方法. 可能的选择包括嵌入命令到数据流(本章稍后我们将讨论这个方法)或者使 用虚拟文件系统, 要么是 sysfs 要么是设备特定的文件系统. (我们将在 14 章看看 sysfs). 但是, 事实是 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 声明它们. 用户程序必须, 当然, 包含那个头文件来存取这些符号.

最新文章

  1. Calendar获取星期
  2. 如何在 IIS 上搭建 mercurial server
  3. 输入的全角字符转换成半角字符--css、js、ASP.NET
  4. BootStrap2学习日记14----导航
  5. Spring(3.2.3) - Beans(7): 延迟实例化
  6. Visual C#每一次新版本的变化
  7. servlet容器开发要点
  8. JVM-6.即时编译器
  9. JSON的新方法--parse()和stringify()
  10. oracle中rownum的使用
  11. 如何做好Puppet Modules管理
  12. B-树、B+树
  13. ios 懒加载详解
  14. C和指针第七章第五题
  15. Python3.5 学习五
  16. kmp java implement--转
  17. 在使用Hibernate save()方法的时候 报错: org.hibernate.exception.ConstraintViolationException:could not perform addBath
  18. Android中将一个图片切割成多个图片[转]
  19. 统计时间段内周分类SQL语句
  20. [转]mybatis 的简单使用

热门文章

  1. echarts radar 一些会用到了的功能记录
  2. nginx+tomcat集群+redis(memcache)session共享!
  3. Failed to delete access_log
  4. oracle怎么捕获表上的DML语句(不包括select)语句)
  5. 【To Read】LeetCode | Jump Game II(转载)
  6. 简单线性回归(梯度下降法) python实现
  7. Zabbix清理历史数据库,缩减表大小
  8. ACM:树的变换,依据表达式建立表达式树
  9. Spring集成Hessian1
  10. Android SwipeActionAdapter结合Pinnedheaderlistview实现复杂列表的左右滑动操作