1.阻塞和非阻塞 IO 是 Linux 驱动开发里面很常见的两种设备访问模式,在编写驱动的时候一定要考虑到阻塞和非阻塞。
这里的“IO”并不是单片机的的“GPIO”(引脚)。
这里的 IO 指的是 Input/Output,也就是输入/输出,是应用程序对驱动设备的输入/输出操作。
2.当应用程序对设备驱动进行操作的时候,如果不能获取到设备资源,那么阻塞式 IO 就会将应用程序对应的线程挂起,直到设备资源可以获取为止。
应用程序调用 read 函数从设备中读取数据,当设备不可用或数据未准备好的时候就会进入到休眠态。等设备可用的时候就会从休眠态唤醒,然后从设备中读取数据返回给应用程序。
3.阻塞访问最大的好处就是当设备文件不可操作的时候进程可以进入休眠态,这样可以将CPU 资源让出来。
4.等待队列
4.1、等待队列头
wait_queue_head_t 需要定义一个。定义以后使用 init_waitqueue_head函数初始化。或者使用宏DECLARE_WAIT_QUEUE_HEAD。
4.2、等待队列项
wait_queue_t表四等待队列项,或者使用宏DECLARE_WAITQUEUE(name, tsk)。
4.3、添加队列项到等待队列头
add_wait_queue函数
4.4、移除等待队列项
资源可用的时候使用remove_wait_queue函数移除。
4.5、唤醒
wake_up唤醒
5.使用:
5.1 包含头文件:
#include <linux/wait.h>
#include <linux/ide.h>
5.2 定义等待队列头
wait_queue_head_t r_wait; /* 读等待队列头 */
5.3 初始化等待队列头
init_waitqueue_head(&imx6uirq.r_wait);
5.4 等待事件
/* 等待以 dev->r_wait 为等待队列头的等待队列被唤醒,前提是 condition 条件必须满足(为真),否则一直阻塞 。 */
wait_event_interruptible(dev->r_wait, atomic_read(&dev->releasekey)); /* 等待按键有效 */
5.5 唤醒进程
/* 当设备可以使用的时候就要唤醒进入休眠态的进程 */
if(atomic_read(&dev->releasekey)) {
wake_up(&dev->r_wait);
}