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

  • 相关阅读:
    LeetCode——面试题57
    翻译——5_Summary, Conclusion and Discussion
    LeetCode——114. 二叉树展开为链表
    LeetCode——1103. 分糖果 II
    LeetCode——337. 打家劫舍 III
    LeetCode——994. 腐烂的橘子
    Python——潜在会员用户预测
    Vue中div高度自适应
    webpack中使用vue-resource
    Mint UI组件库 和 Mui
  • 原文地址:https://www.cnblogs.com/hjxzjp/p/10466681.html
Copyright © 2020-2023  润新知