liunx 中断
void __init trap_init(void) 构造了异常向量
按下按键:
注册中断 使用request_irq(irq,handler,flags,name,dev_id)
{
分配一个irqaction
把irqaction放入irq_desc[irq]
使能设置引脚
使能中断
}
释放中断使用 free_irq(irq,dev_id)
{
将中断脱出链表
禁止中断
}
exec 5</dev/buttons,打开/dev/buttons这个设备,定位到文件描述符fd5,挂载到5下,会调用open
使用命令,exec 5<&-,关闭文件描述符fd5,释放中断。(会调用release)
cat /proc/interrupts 查看中断
休眠与唤醒
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* 中断事件标志, 中断服务程序将它置1,buttons_drv_read将它清0 */
static volatile int ev_press = 0;
唤醒:
ev_press = 1; /* 表示中断发生了 */
wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
休眠:
/*如果没有按键动作发生,休眠*/
wait_event_interruptible(button_waitq,ev_press);
/*如果没有按键有动作发生,返回*/
copy_to_user(buf,&key_val,1);
中断处理函数:buttons_irq
static irqreturn_t buttons_irq (int irq, void *dev_id)
{
struct pin_desc * pindesc = (struct pin_desc *)dev_id;
unsigned int pinval;
pinval = s3c2410_gpio_getpin(pindesc->pin);
if(pinval)
{
//表示按键松开
key_val = 0x80 | pindesc->key_val;
}
else
{
//表示按键按下
key_val =pindesc->key_val;
}
ev_press = 1; /* 表示中断发生了 */
wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
return IRQ_HANDLED;
}
read函数调用
int buttons_drv_close (struct inode *inode, struct file *file)
int buttons_drv_close (struct inode *inode, struct file *file)
{
/*释放中断 */
free_irq(IRQ_EINT0,&pins_desc[0]);
free_irq(IRQ_EINT2,&pins_desc[1]);
free_irq(IRQ_EINT11,&pins_desc[2]);
free_irq(IRQ_EINT19,&pins_desc[3]);
return 0;
}
创建中断:
/*创建中断*/
request_irq(IRQ_EINT0,buttons_irq,IRQT_BOTHEDGE,"S2",&pins_desc[0]);//IRQT_BOTHEDGE 双边沿触发 1设备ID IRQ_EINT0中断号
request_irq(IRQ_EINT2,buttons_irq,IRQT_BOTHEDGE,"S3",&pins_desc[1]);//IRQT_BOTHEDGE 双边沿触发 1设备ID IRQ_EINT0中断号
request_irq(IRQ_EINT11,buttons_irq,IRQT_BOTHEDGE,"S4",&pins_desc[2]);//IRQT_BOTHEDGE 双边沿触发 1设备ID IRQ_EINT0中断号
request_irq(IRQ_EINT19,buttons_irq,IRQT_BOTHEDGE,"S5",&pins_desc[3]);//IRQT_BOTHEDGE 双边沿触发 1设备ID IRQ_EINT0中断号
rmmod 调用 static void buttons_drv_exit(void)
insmod 调用:static int buttons_drv_init(void)
释放中断:
/*释放中断 */
free_irq(IRQ_EINT0,&pins_desc[0]);
free_irq(IRQ_EINT2,&pins_desc[1]);
free_irq(IRQ_EINT11,&pins_desc[2]);
free_irq(IRQ_EINT19,&pins_desc[3]);