随笔分类 -  liunx设备驱动程序

上一页 1 ··· 5 6 7 8 9 10 11 下一页
个人学习使用,所有收集仅供参考。
摘要:如果我们深入 <linux/wait.h>, 你见到在 wait_queue_head_t 类型后面的数据结构是非 常简单的; 它包含一个自旋锁和一个链表. 这个链表是一个等待队列入口, 它被声明做 wait_queue_t. 这个结构包含关于睡眠进程的信息和它想怎样被唤醒. 使一个进程睡眠的第一步 阅读全文
posted @ 2019-07-06 10:38 樊伟胜 阅读(960) 评论(0) 推荐(0) 编辑
摘要:最后, 我们看一个实现了阻塞 I/O 的真实驱动方法的例子. 这个例子来自 scullpipe 驱 动; 它是 scull 的一个特殊形式, 实现了一个象管道的设备. 在驱动中, 一个阻塞在读调用上的进程被唤醒, 当数据到达时; 常常地硬件发出一个中断 来指示这样一个事件, 并且驱动唤醒等待的进程作 阅读全文
posted @ 2019-07-06 10:36 樊伟胜 阅读(735) 评论(0) 推荐(0) 编辑
摘要:在我们看全功能的 read 和 write 方法的实现之前, 我们触及的最后一点是决定何时使 进程睡眠. 有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去. 有时还有调用进程通知你他不想阻塞, 不管它的 I/O 是否继续. 明确的非阻塞 I/O 由 filp->f_fla 阅读全文
posted @ 2019-07-06 10:31 樊伟胜 阅读(2668) 评论(0) 推荐(0) 编辑
摘要:当一个进程睡眠, 它这样做以期望某些条件在以后会成真. 如我们之前注意到的, 任何睡 眠的进程必须在它再次醒来时检查来确保它在等待的条件真正为真. Linux 内核中睡眠的 最简单方式是一个宏定义, 称为 wait_event(有几个变体); 它结合了处理睡眠的细节和 进程在等待的条件的检查. wa 阅读全文
posted @ 2019-07-06 10:30 樊伟胜 阅读(580) 评论(0) 推荐(0) 编辑
摘要:对于一个进程"睡眠"意味着什么? 当一个进程被置为睡眠, 它被标识为处于一个特殊的状 态并且从调度器的运行队列中去除. 直到发生某些事情改变了那个状态, 这个进程将不被 在任何 CPU 上调度, 并且, 因此, 将不会运行. 一个睡着的进程已被搁置到系统的一边, 等待以后发生事件. 对于一个 Lin 阅读全文
posted @ 2019-07-06 10:29 樊伟胜 阅读(2711) 评论(0) 推荐(0) 编辑
摘要:有时控制设备最好是通过写控制序列到设备自身来实现. 例如, 这个技术用在控制台驱动 中, 这里所谓的 escape 序列被用来移动光标, 改变缺省的颜色, 或者进行其他的配置任 务. 这样实现设备控制的好处是用户可仅仅通过写数据控制设备, 不必使用(或者有时候 写)只为配置设备而建立的程序. 当设备 阅读全文
posted @ 2019-07-06 10:28 樊伟胜 阅读(252) 评论(0) 推荐(0) 编辑
摘要:ioctl 的 scull 实现只传递设备的配置参数, 并且象下面这样容易: switch(cmd) { case SCULL_IOCRESET: scull_quantum = SCULL_QUANTUM; scull_qset = SCULL_QSET; break; case SCULL_IO 阅读全文
posted @ 2019-07-06 10:26 樊伟胜 阅读(634) 评论(0) 推荐(0) 编辑
摘要:在看 scull 驱动的 ioctl 代码之前, 我们需要涉及的另一点是如何使用这个额外的参数. 如果它是一个整数, 就容易: 它可以直接使用. 如果它是一个指针, 但是, 必须小心些. 当用一个指针引用用户空间, 我们必须确保用户地址是有效的. 试图存取一个没验证过的 用户提供的指针可能导致不正确 阅读全文
posted @ 2019-07-06 10:25 樊伟胜 阅读(1807) 评论(0) 推荐(0) 编辑
摘要:尽管 ioctl 系统调用最常用来作用于设备, 内核能识别几个命令. 注意这些命令, 当用 到你的设备时, 在你自己的文件操作被调用之前被解码. 因此, 如果你选择相同的号给一 个你的 ioctl 命令, 你不会看到任何的给那个命令的请求, 并且应用程序获得某些不期望 的东西, 因为在 ioctl 阅读全文
posted @ 2019-07-06 10:24 樊伟胜 阅读(429) 评论(0) 推荐(0) 编辑
摘要:在为 ioctl 编写代码之前, 你需要选择对应命令的数字. 许多程序员的第一个本能的反 应是选择一组小数从0或1 开始, 并且从此开始向上. 但是, 有充分的理由不这样做. ioctl 命令数字应当在这个系统是唯一的, 为了阻止向错误的设备发出正确的命令而引起 的错误. 这样的不匹配不会不可能发生 阅读全文
posted @ 2019-07-06 10:12 樊伟胜 阅读(1462) 评论(0) 推荐(0) 编辑
摘要:大部分驱动需要 -- 除了读写设备的能力 -- 通过设备驱动进行各种硬件控制的能力. 大 部分设备可进行超出简单的数据传输之外的操作; 用户空间必须常常能够请求, 例如, 设 备锁上它的门, 弹出它的介质, 报告错误信息, 改变波特率, 或者自我销毁. 这些操作常 常通过 ioctl 方法来支持, 阅读全文
posted @ 2019-07-06 10:11 樊伟胜 阅读(1541) 评论(0) 推荐(0) 编辑
摘要:atomic_t 类型在进行整数算术时是不错的. 但是, 它无法工作的好, 当你需要以原子方 式操作单个位时. 为此, 内核提供了一套函数来原子地修改或测试单个位. 因为整个操作 在单步内发生, 没有中断(或者其他处理器)能干扰. 原子位操作非常快, 因为它们使用单个机器指令来进行操作, 而在任何时 阅读全文
posted @ 2019-07-06 10:10 樊伟胜 阅读(817) 评论(0) 推荐(0) 编辑
摘要:内核包含了一对新机制打算来提供快速地, 无锁地存取一个共享资源. seqlock 在这 种情况下工作, 要保护的资源小, 简单, 并且常常被存取, 并且很少写存取但是必须要快. 基本上, 它们通过允许读者释放对资源的存取, 但是要求这些读者来检查与写者的冲突而 工作, 并且当发生这样的冲突时, 重试 阅读全文
posted @ 2019-07-06 10:10 樊伟胜 阅读(283) 评论(0) 推荐(0) 编辑
摘要:有时, 一个共享资源是一个简单的整数值. 假设你的驱动维护一个共享变量 n_op, 它告 知有多少设备操作目前未完成. 正常地, 即便一个简单的操作例如: n_op++; 可能需要加锁. 某些处理器可能以原子的方式进行那种递减, 但是你不能依赖它. 但是一 个完整的加锁体制对于一个简单的整数值看来过 阅读全文
posted @ 2019-07-06 10:09 樊伟胜 阅读(959) 评论(0) 推荐(0) 编辑
摘要:内核提供了一个自旋锁的读者/写者形式, 直接模仿我们在本章前面见到的读者/写者旗标. 这些锁允许任何数目的读者同时进入临界区, 但是写者必须是排他的存取. 读者写者锁有 一个类型 rwlock_t, 在 <linux/spinlokc.h> 中定义. 它们可以以 2 种方式被声明和被 初始化: rw 阅读全文
posted @ 2019-07-06 10:08 樊伟胜 阅读(234) 评论(0) 推荐(0) 编辑
摘要:我们已经看到 2 个函数, spin_lock 和 spin_unlock, 可以操作自旋锁. 有其他几个函 数, 然而, 有类似的名子和用途. 我们现在会展示全套. 这个讨论将带我们到一个我们无 法在几章内适当涵盖的地方; 自旋锁 API 的完整理解需要对中断处理和相关概念的理解. 实际上有 4 阅读全文
posted @ 2019-07-06 10:01 樊伟胜 阅读(480) 评论(0) 推荐(0) 编辑
摘要:自旋锁原语要求的包含文件是 <linux/spinlock.h>. 一个实际的锁有类型 spinlock_t. 象任何其他数据结构, 一个 自旋锁必须初始化. 这个初始化可以在编译时完成, 如下: 自旋锁原语要求的包含文件是 <linux/spinlock.h>. 一个实际的锁有类型 spinloc 阅读全文
posted @ 2019-07-06 09:48 樊伟胜 阅读(366) 评论(0) 推荐(0) 编辑
摘要:内核编程的一个普通模式包括在当前线程之外初始化某个动作, 接着等待这个动作结束. 这个动作可能是创建一个新内核线程或者用户空间进程, 对一个存在着的进程的请求, 或 者一些基于硬件的动作. 在这些情况中, 很有诱惑去使用一个旗标来同步 2 个任务, 使 用这样的代码: struct semaphor 阅读全文
posted @ 2019-07-06 09:47 樊伟胜 阅读(388) 评论(0) 推荐(0) 编辑
摘要:旗标为所有调用者进行互斥, 不管每个线程可能想做什么. 然而, 很多任务分为 2 种清 楚的类型: 只需要读取被保护的数据结构的类型, 和必须做改变的类型. 允许多个并发读 者常常是可能的, 只要没有人试图做任何改变. 这样做能够显著提高性能; 只读的任务可 以并行进行它们的工作而不必等待其他读者退 阅读全文
posted @ 2019-07-06 09:46 樊伟胜 阅读(323) 评论(0) 推荐(0) 编辑
摘要:旗标机制给予 scull 一个工具, 可以在存取 scull_dev 数据结构时用来避免竞争情况. 但是正确使用这个工具是我们的责任. 正确使用加锁原语的关键是严密地指定要保护哪个 资源并且确认每个对这些资源的存取都使用了正确的加锁方法. 在我们的例子驱动中, 感 兴趣的所有东西都包含在 scull 阅读全文
posted @ 2019-07-06 09:36 樊伟胜 阅读(198) 评论(0) 推荐(0) 编辑

上一页 1 ··· 5 6 7 8 9 10 11 下一页