驱动程序
1、函数 wake_up_interruptible (wait_queue_head_t *q);
功能:唤醒注册到等待队列上的进程
原型:
#include
void wake_up_interruptible (wait_queue_head_t *q);
说明:
唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。
变量:
q : 等待队列变量指针。
最近在学习驱动时有一个问题始终想不明白,为什么wait_event_interruptible(button_waitq, ev_press)需要一个全局变量来记住中断的发生?
在驱动中实现读取操作时,使用了
- wait_event_interruptible(button_waitq, ev_press);
在中断函数中使用了如下语句唤醒:
- ev_press = 1; //表示中断发生了
- wake_up_interruptible(&button_waitq); //唤醒休眠的进程
这样的话,中断能正确读取到。我分别尝试了屏蔽ev_press = 1;和wake_up_interruptible(&button_waitq);代码,发现中断不能正常产生。
2、函数 wait_event_interruptible(kwait, key_press);
,该函数修改task的状态为TASK_INTERRUPTIBLE,意味着该进程将不会继续运行直到被唤醒,然后被添加到等待队列wq中。
在wait_event_interruptible()中首先判断key_press是不是已经满足,如果条件满足则直接返回0,否则调用__wait_event_interruptible(),并用__ret来存放返回
wait_event_interruptible()将本进程置为可中断的挂起状态,反复检查key_press是否成立,如果成立则退出休眠,如果不成立则继续休眠;条件满足后,即把本进程运行状态置为运行态(此时如果不执行下面的函数 wake_up_interruptible,上面wait_event_interruptible还会继续休眠),并将wait从等待队列中清除掉,从而进程能够调度运行。如果进程当前有异步信号(POSIX的),则返回-ERESTARTSYS。
- //唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。
- wake_up_interruptible (wait_queue_head_t *q);
我是这样考虑的:read 调用wait_event_interruptible(button_waitq),我觉得一个参数就够了。不判断什么条件,直接休眠,下面用wake_up_interruptible(&button_waitq)直接唤醒。这样看起来很简单。
3、函数 free_irq(unsigned int irq, void *dev_id);
参数说明:
unsigned int irq:要卸载的中断号
void *dev_id:这个是要卸载的中断action下的哪个服务函数, 如果没有 设为NULL
4、函数 i