开发板:tiny6410
内核版本:linux2.6.38
要想写出案件驱动:需要复习的知识:1、混杂设备的使用原理 2、系统调用驱动函数的原理 3、中断处理机制 4、阻塞性设备驱动的书写规范
1、混杂设备的注册和使用比较简单,以前也复习过,这里不再复习
3、中断处理机制 也有博客内容中断处理机制博客链接
4、阻塞型字符驱动的书写规则:
实现read和write函数的时候可能会出现阻塞的情况。因此,在这种情况下,我们的驱动程序应该(默认)阻塞该进程,将其置入休眠状态直到请求可以继续。
等待队列,在内核里面,等待队列是有很多用处的,尤其是在中断处理,进程同步、定时等场合,可以通过等待队列来实现阻塞进程的唤醒。它是以队列为基础数据结构、与进程调度机制紧密结合,能够用于实现内核中的异步事件通知机制,同步对系统资源的访问等。
等待队列的类型在内核源代码的头文件 include/linux/wait.h
struct_wait_queue_head
{
spinlock_t lock;
struct list_head task_list;
};
typedef struct_wait_queue_head wait_queue_head_t;
使用内核等待队列的步骤:
1、定义内核等待队列
2、初始化内核等待队列
3、等待事件
4、唤醒队列
分别使用什么函数实现着这四个步骤:
1、定义内核等待队列
wait_queue_head_t my_queue;//定义等待队列
2、初始化内核等待队列
init_waitqueue_head(&my_queue);//初始化内核等待队列
以上两步:可以并作一步来实现,定义并初始化 使用一个宏函数来直接实现内核等待队列的定义和初始化。
3、等待事件
等待时间通常由如下编程接口来实现:
wait_event(queue,condition);//但是使用这个函数结构,进程将被置于非中断休眠-------所以通常不适用这个接口函数
当condition(bool变量) 为真时,立即返回。否则将当前进程放入等待队列queue中,并将该进程的状态设置为TASK_INTERRUPTEIBLE(可中断的睡眠模式)
通常使用的事件接口函数:
wait_event_interruptible(queue,condition);//这个函数接口可以被某个信号中断
4、唤醒队列
唤醒队列的函数接口:
有两个函数供调用:
wake_up(wait_queue_t *q);//唤醒等待队列的所有进程
wake_up_interruptible(wait_queue_t *q);//唤醒等待队列中进程状态为TASK_INTERRUPTIBLE的所有进程。
在阻塞型驱动中,read实现方式如下:如果进程调用read,但设备没有数据或数据不足,则进程阻塞。当新数据到达后,唤醒被阻塞的进程。