资料视频来自B站《嵌入式之内核及驱动开发(初级课程)》。
韦东山第二期驱动视频。
正点原子。
以下重要笔记整理记录:
文件 io模型有:
1.非阻塞(没有数据,我就退出内核);
2.阻塞(没有数据休眠在内核等待);
3.多路复用——select/poll(同时监控多个文件的读写出错操作);
4异步(有数据的时候通过信号通知用户再来读取)。
1.阻塞:
当进程在读取的外部设备的资源(数据),资源没有准备好,进程就会休眠。linux应用中,大部分的接口函数都是阻塞,
scanf();
read();
write();
accept()等。
驱动中需要调用
1.将当前进程加入到等待队列头中。
add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait)
2.将当前进程状态设置成TASK_INTERRUPTIBLE
set_current_state(TASK_INTERRUPTIBLE)
3.让出调度–休眠
schedule(void)
但我们在写驱动程序时,有更智能化的API接口帮我们完成上面三个任务
wait_event_interruptible(wq,condition)
驱动中如何去写代码:
1.等待队列头
wait_queue_head_t
init_waitqueue_head(wait_queue_head_t *q);
也可以使用宏 DECLARE_WAIT_QUEUE_HEAD 来一次性完成等待队列头的定义的初始化
2.在中断处理函数中
ev_press = 1; /* 表示中断发生了 /
wake_up_interruptible(&button_waitq); / 唤醒休眠的进程 /
3.在驱动 read()函数中
/ 如果没有按键动作, 休眠 /
wait_event_interruptible(button_waitq, ev_press);
/ 如果有按键动作, 返回键值 */
copy_to_user(buf, &key_val, 1);
ev_press = 0;
2.非阻塞
笔记见华清远见视频
3.多路复用
对多个文件操作要么单线程poll/select,要么多线程。
如果用户应用程序以非阻塞的方式访问设备,设备驱动程序就要提供非阻塞的处理方式,也就是轮询select/poll
应用程序中:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);