1.应用程序打算执行完后,打印出点亮或者熄灭的小灯,相当于按键一下,打印一下
2.驱动程序:
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
irq:表示发生的中断源
handler:表示中断服务程序,发生中断后执行的程序
flag:产生中断的原因,比如下降沿,上升沿,或者两个都产生中断
ssize_t key_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
if (size != 1)
return -EINVAL;
// 根据判断ev_press的值,看是否有按键发生
/* 如果没有按键动作, 休眠 */
wait_event_interruptible(button_waitq, ev_press);
/* 如果有按键动作, 返回键值 */
copy_to_user(buf, &key_val, 1);
ev_press = 0;
return 1;
}
我们在应用程序里边等待发生中断:
wait_event_interruptible(button_waitq, ev_press);
就是这一段,如果没有发生中断,我们会一直停在此处。
二. 下面总结一下使用按键中断点亮小灯。
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* 中断事件标志, 中断服务程序将它置1,key_drv_read将它清0 */
static volatile int ev_press = 0;
使用DECLARE_WAIT_QUEUE_HEAD(button_waitq);声明一个等待队列头,等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒它们。
这里提到当某一条件为真时,那这条件指什么:
wait_event_interruptible(button_waitq, ev_press);
就是这个地方,如果ev_press为真,那么内核就唤醒这个进程。