中断方式获取按键值

先总结一下中断的处理过程:

/首先要着重强调一点,irq_desc这个结构体很重要/

在trap_init()中,完成对异常向量的复制,Linux中是复制到0xffff0000。当发生异常时,CPU会自动跳转到这里,再跳转到执行更复杂的代码,比如调用异常处理函数。
当执行中断处理函数时,会首先调用asm_do_IRQ(),同时会传入中断号irq,然后根据中断号调用irq_desc[irq],这是一个结构体数组,在handle.c中定义。其中有一个handler_irq的函数指针,指向中断处理函数的入口。即会调用irq_desc[irq].handler_irq,然后入口函数会先清除中断,在调用在action链表中注册的中断处理函数action.handler。
需要特别注意的是,handler_irq只是入口函数,对于电平触发的中断是handler_level_irq,边缘触发的中断是handler_edge_irq,真正的中断处理函数在action链表中的action.handler。

所以,如果我们想要增加一个中断处理函数,就需要在action链表中注册,所需要借助对的函数是request_irq(irq,handler,irqflags, *devname, *dev_id)。在request_irq中会首先构造一个irqaciton结构,然后通过setup_irq将这个结构放到action链表中。
具体来说,setup_irq实现了三个功能,第一,将irqaction结构放入action链表;第二,把对应的引脚设置为中断模式;第三,使能中断。同样的,想要卸载一个中断处理函数,需要用到的是free_irq(irq, *dev_id),dev_id的作用就在于此。free_irq使用中断号定位irq_desc[]里的action链表,再使用dev_id定位action链表中要卸载的表项(因为共用中断时必须要用不同的dev_id来区分不同的中断处理函数)。

接下来总结一下具体的实现过程:

首先是配置中断,自然是要在third_drv_open函数中加入request_irq(irq,handler,irqflags, *devname, *dev_id),查阅原理图可以得到,需要用到的IRQ_EINT13、IRQ_EINT14、IRQ_EINT15,handler即为中断处理函数,暂且写为buttons_irq(),具体实现稍后再写,标志设为IRQT_BOTHEDGE双边沿触发,名字起为“K1”,dev_id的设置则需要考虑一下。
然后是再考虑释放中断的问题,因此需要在file_operation结构里添加:.release= third_drv_close,在这个函数里要使用free_irq(irq,dev_id)。

接下来考虑dev_id的问题。我们目前只是知道中断号,而不知道具体是哪个中断。所以我们可以把引脚和值封装起来,定义一个引脚描述的结构体:
struct pin_desc{
unsigned int pin;
unsigned int key_val;
};
再定义一个数组:
struct pin_desc pins_desc[3]={
{S3C2410_GPG5,0x01},
{S3C2410_GPG6,0x02},
{S3C2410_GPG7,0x03},
};
这样,我们可以把这个数组的一项作为dev_id,当产生中断时,request_irq把这个dev_id传到中断处理函数中,再解析出来引脚和值。

这样,我们就解决“找到中断产生位置”的目的。由于按下和松开都会产生中断,所以我们还需要得到这个按键究竟是被按下还是松开,于是我们需要用到s3c2410_gpio_getpin(),如果被按下,则输出0,松开则输出1。通过解析出来的引脚:假如是S3C2410_GPG5被按下,则会输出0x01,否则输出0x81;假如是S3C2410_GPG6被按下,则会输出0x02,否则输出0x82;假如是S3C2410_GPG7被按下,则会输出0x03,否则输出0x83。

完成这些之后,将中断事件标志置1,唤醒休眠的进程(在应用程序执行read时,在没有中断产生之前一直处于休眠状态)。然后返回third_drv_read()中使用copy_to_user把键值拷贝给应用程序。

进程的休眠与唤醒需要用到wait_event_interruptible和wake_up_interruptible,使用之前需要定义一个队列static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值