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

现在发现一个问题,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)

觉得还可以的朋友请点个赞,下篇我将详细说说Linux下的按键驱动

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章