liunx驱动----按键中断

liunx 中断

  1. 先设置异常入口
  2. 异常向量

void __init trap_init(void) 构造了异常向量

  1. vector_irq+offset
 
 
 
按下按键:
  1. cpu自动进入异常模式
注册中断 使用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]);

猜你喜欢

转载自www.cnblogs.com/hjxzjp/p/10466681.html