1.将引脚设置为中断模式
void init_dev(void) { s3c_gpio_cfgpin(key_table[0],S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(key_table[1],S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(key_table[2],S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(key_table[3],S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(key_table[4],S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(key_table[5],S3C_GPIO_SFN(2)); unsigned int tmp; tmp = readl(S3C64XX_GPNCON); printk("%x\n",tmp); }
2.申请中断
ret = request_irq(key_irqs[num].irq,keys_interrupt,key_irqs[num].flags,key_irqs[num].name,(void*)&key_irqs[num]);
3.等待中断触发事件
wait_event_interruptible(key_waitq,ev_press);
当wake_up_interruptible()没有执行且ev_press没有改变时,将一直等待。
4.当中断发生时,调用中断处理函数
当外部中断发生时,request_irq()当中最后一个参数将提供给中断处理函数
中断处理函数
static irqreturn_t keys_interrupt(int irq,void *dev_id) { struct key_irq *key_irqs = (struct key_irq *)dev_id; int down; int number; unsigned tmp; number = key_irqs->number; printk("number = %d\n",number); switch(number) { case 0: case 1: case 2: case 3: case 4: case 5: tmp = readl(S3C64XX_GPNDAT); down = !(tmp & (1 << number)); break; default: down = 0; } if(down != (key_values[number] & 1)) { key_values[number] = '0' + down; ev_press = 1; wake_up_interruptible(&key_waitq); } printk("interrupt\n"); return IRQ_RETVAL(IRQ_HANDLED); }
5. 释放中断
free_irq(key_irqs[i].irq,(void*)&key_irqs[i]);