Linux驱动之按键驱动长按检测

    技术2022-07-11  103

    现在发现一个问题,Linux下的按键驱动,增加了长按检测。但是在长按的时候不往应用层上报长按的值,很奇怪先做个记录待以后分析。现在的模式是,周一到周五发现问题,到周末才会专心写博客填坑了。

    =================================================================

    问题已经解决,是因为原来是按键抬起后开启定时器判断,超时一段时间后就上报长按按键值。问题有两点:

    1.开启定时器检测按键长按的电平状态条件判断不对。

    2.定时器超时一段时间后就上报长按,但是上报长按的电平状态条件判断也不对。

    注:

    我这个按键,是按下高电平,抬起低电平

    贴上原来的代码如下:

    void gpio_keys_ctimer(unsigned long data) { if(! gpio_active) { //错误代码,抬起后开启开启定时器显然不对 timerouts += 1; //高电平开启定时器计数 } mod_timer(&ctimer, msecs_to_jiffies(50)); } static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) { const struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; //timer_flag = gpio_active; if(button->long_press) { gpio_active = state; } if (type == EV_ABS) { if (state) { input_event(input, type, button->code, button->value); } } else { if((button->long_press) && (timerouts*bdata->timer_debounce > 800) && state) { //错误代码,定时器超时并且按键为高电平的时候上报。 input_event(input, type, button->code, (!!state)|TOUCH_HOLD);//上报,TOUCH_HOLD=0x2 } else { input_event(input, type, button->code, !!state); } } input_sync(input); timerouts=0; }

    判断按键长按的正确思路应该是:

    按键按下后判断保持高电平的时间,超时一段时间后视为长按。抬起后上报的键值由0改为2

    所以正确代码应该是:

    if(!gpio_active)

    改为if(!! gpio_active) 

    if((button->long_press) && (timerouts*bdata->timer_debounce > 800) && state)

    改为if((button->long_press) && (timerouts*bdata->timer_debounce > 800) && !state)

     

    Processed: 0.009, SQL: 9