高级字符驱动程序操作
来源:互联网 发布:淘宝店铺怎样实名认证 编辑:程序博客网 时间:2024/05/07 23:45
通过读/写来实现数据传输,但除了数据传输之外,还有请求设备锁门、弹出介质、报告错误信息等。
休眠:当一个进程所需要的资源得不到满足时,会标记为一种特殊状态,该状态就可以理解为休眠,休眠中的进程会被搁置在一边,等待将来的某个事件发生。
对于休眠需要记住三天规则:
1)、永远不要在原子上下文中进入休眠(原子上下文是指:执行多个步骤时,不能有任何的并发访问);
2)、当我们被唤醒时,我们永远无法知道休眠了多长时间,或者休眠期间都发生了什么事情;
3)、除非我们知道有其他人在其他地方唤醒我们,否则进程不能休眠。
static ssize_t scull_p_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos){struct scull_pipe *dev = filp->private_data;if (mutex_lock_interruptible(&dev->mutex))return -ERESTARTSYS;while (dev->rp == dev->wp) { /* nothing to read */mutex_unlock(&dev->mutex); /* release the lock */if (filp->f_flags & O_NONBLOCK)return -EAGAIN;PDEBUG("\"%s\" reading: going to sleep\n", current->comm);if (wait_event_interruptible(dev->inq, (dev->rp != dev->wp)))return -ERESTARTSYS; /* signal: tell the fs layer to handle it *//* otherwise loop, but first reacquire the lock */if (mutex_lock_interruptible(&dev->mutex))return -ERESTARTSYS;}/* ok, data is there, return something */if (dev->wp > dev->rp)count = min(count, (size_t)(dev->wp - dev->rp));else /* the write pointer has wrapped, return data up to dev->end */count = min(count, (size_t)(dev->end - dev->rp));if (copy_to_user(buf, dev->rp, count)) {mutex_unlock (&dev->mutex);return -EFAULT;}dev->rp += count;if (dev->rp == dev->end)dev->rp = dev->buffer; /* wrapped */mutex_unlock (&dev->mutex);/* finally, awake any writers and return */wake_up_interruptible(&dev->outq);PDEBUG("\"%s\" did read %li bytes\n",current->comm, (long)count);return count;}
分析scull_p_read是如何处理数据的:
while循环在拥有设备信号量时测试缓冲区,如果有数据,则立即将数据返回给用户而不需要休眠,这样整个循环就被跳过了。如果缓冲区为空,则需要释放信号量,必须进入休眠。释放信号量之后,快速检查用户请求是否是非阻塞I/O,如果是,则返回,否则调用wait_event_interruptible
异步通知:
使用异步通知,应用程序可以在数据可用时收到一个信号,而不需要不停地使用轮询来关注数据。
llseek实现:
适用于处理有明确定义的数据区,并不适用于只提供数据流(如串口和键盘)的设备,在open方法中通过调用nonseekable_open来通知内核设备不支持llseek。
1、如何使进程休眠(并唤醒)?
使进程休眠可以有三种方式:a、简单休眠 wait_event_interruptible(queue,condition)queue是值传递而不是指针,condition是任意一个布尔表达式,休眠前后都要多这个表达式进行求值;b、高级休眠首先是分配并初始化一个wait_queue_t结构,然后将其加入到对应的等待队列,接着设置进程的状态,将其标记为休眠,最后是检查休眠等待条件,成立则放弃处理器;c、手工休眠prepare_to_wait和finish_wait
2、如何实现非阻塞I/O?
显示的阻塞有filp->f_flags中的O_NONBLOCK标志决定。
3、设备可读取或写入时如何通知用户空间?
4、如何在驱动程序中实现几种不同的设备访问策略?
5、驱动程序怎样实现异步信号?
a、F_SETOWN被调用时对filp->f_owner赋值;b、在执行F_SETFL启用FASYNC时调用驱动程序的fasync方法;c、当数据到达时,所有注册为异步通知的进程都会被发送一个SIGIO信号。
- 高级字符驱动程序操作
- 其它高级字符驱动程序操作
- 高级字符驱动程序操作 -- 基本读写功能
- 高级字符驱动程序操作---增加ioctl功能
- 第六章:高级字符驱动程序操作
- 高级字符驱动程序操作——ioctl
- 高级字符驱动程序操作(poll机制)
- 第六章--高级字符驱动程序操作
- LDD高级字符驱动程序操作-异步通知
- 第六章:高级字符驱动程序操作
- 《Linux设备驱动程序》——高级字符驱动程序操作
- 高级字符驱动程序操作(Linux设备驱动程序)
- 高级字符驱动程序
- 高级字符驱动程序操作--增加了poll功能
- 高级字符驱动程序操作--增加了async功能
- 高级字符驱动程序操作之ioctl(理论篇)
- 高级字符驱动程序操作之ioctl(实践篇)
- 高级字符驱动程序操作之休眠(理论篇)
- 多线程编程-detach
- SDUT2088refresh的停车场
- Quartz(03) cron 表达式
- PHPExcel 基本用法详解
- 关于VS2013提示无法启动程序,找不到指定文件的解决方法
- 高级字符驱动程序操作
- 字符串计数(字典序)---- 美团2016研发工程师在线编程题
- Handler机制 与 ANR异常
- 多线程环境下单例模式(java23中设计模式)
- 数据结构实验之排序六:希尔排序
- QUST'S OJ problem 1778奖学金
- listview下拉刷新 上拉(滑动分页)加载更多
- 录制手机屏幕并转为gif
- java 删除链表中值为x的节点