按键驱动+中断

(1)中断服务程序(ISR);

在按键没有被按下的时候,线程处在阻塞状态,等待着资源的到来,而当按键被按下的时候,首先产生一个中断,这个时候中断服务子程序会保存按键的值,并且唤醒阻塞的线程。

 中断阻塞函数:

wait_event_interruptible(button_waitq, ev_press);

当env_press == 0时,中断程序在阻塞睡眠状态:

当env_press == 1时,中断程序被唤醒。

唤醒函数:

wake_up_interruptible(&button_waitq)
extern unsigned int ev_press;

(2)注册中断(中断号,中断服务程序)

int request_irq( unsigned int irq,irq_handler_t handler, unsigned long flags, constchar *name, void *dev);

handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它 

flags说明:设置了flag之后就知道ISR什么时候被调用了。

#define IRQF_TRIGGER_NONE    0x00000000
#define IRQF_TRIGGER_RISING    0x00000001        /* 上升沿触发 */
#define IRQF_TRIGGER_FALLING    0x00000002       /* 下降沿触发 */
#define IRQF_TRIGGER_HIGH    0x00000004          /* 高电平触发 */
#define IRQF_TRIGGER_LOW    0x00000008           /* 低电平触发 */
#define IRQF_TRIGGER_MASK    (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE    0x00000010
int open(struct inode* inode,struct file* file)
{
    int ret = request_irq(IRQ_INT0,ISR,FLAG1,"up",(void*)0x01);

     ret = request_irq(IRQ_INT1,ISR,FLAG1,"down",(void*)0x02);
    
    return ret;
}

中断服务子程序:irq_handler_t handler如下

unsigned int press_key = 0;

extern int get_gpio_value(unsigned int kid,unsigned int* gpioValue)

void ISR(int irq,void* value)
{
    unsigned int key_value =0;
    unsigned int key_id = (unsigned int)*value;//那个按键
    get_gpio_value(key_id, &key_value);
    
    //最高位
    if(key_value)
    {
        press_key = key_id | 0x80;
    }
    else
    {
        press_key = key_id ;
    }

    ev_Press = 1;

    wake_up_interruptible(&button_waitq);//有动作产生,唤醒
}
int release(struct inode* inode,struct file* file)
{
    free_irq(IRQ_INT0,(void*)0x01);
    free_irq(IRQ_INT1,(void*)0x02);
    return 0;

}
int read(struct file* file,char __user* buf,size_t count,loff_t* f_pos)
{
    wait_event_interruptible(button_waitq, ev_press);
    ret = copy_to_user(buf,&press_value,1);
    en_press = 0;
    return 0;
}

ev_press == 1时,表示有动作产生,即是我们从中断服务程序中可以看到key_action = 1 ;

ev_press == 0会阻塞,即是press_value没有发生改变

当没有按键时,没有电平相关触发事件产生,所以中断没有被触发。而当按键被按下时,中断处理函数ISR就被调用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值