在xxx_open函数中注册中断函数:
request_irq的最后参数是dev_id,我的理解是他可以像次设备号一样,可以由我们自己定义他是什么含义。
写真正的中断处理函数:
当中断发生时会调用这个函数,传入的参数是 相应的中断号 和 注册中断时传入的dev_id
按键驱动程序中,为了描述一个引脚,声明了pin_desc结构体,并初始化了一个结构体数组:
把&pins_desc[n]作为dev_id传入中断处理程序,就能根据传入的pin_desc->pin成员,直接调用如下函数获得引脚的状态,非常方便:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
当测试程序打开/dev/bottons设备文件并读取按键时,会循环调用:
如果不在驱动程序中的bottons_read函数中做处理,这样循环读取按键状态会一直占用cpu的资源,因此在bottons_read中做了如下处理:
wait_event_interruptible(queue, condition)会根据condition的状态判断是否要把当前进程休眠:
condition == 0-->休眠,并且不返回,等待条件成立(condition == 1)继续执行
condition == 1-->不休眠,继续执行
在上文的中断处理函数中,会有如下操作:
使condition == 1,从而让bottons_read返回,测试程序就能得到按键值了。
整个执行过程如下:
测试程序在死循环中调用read函数,内核调用bottons_read函数,执行wait_event_interruptible时发现ev_press == 0,这时测试程序就休眠了,进入等待队列,不占用cpu。
这时候按下按键,产生中断,在中断函数中读取引脚的高低电平获得按键状态,使condition(ev_press) == 1
bottons_read函数得以从wait_event_interruptible返回,把中断中获得的按键状态通过copy_to_user告诉测试程序,read函数得以返回按键状态。