S3C6410 按键驱动(二) ---按键中断的基本流程

时间:2021-03-01 19:33:12

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]);