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下的按鍵驅動

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