現在發現一個問題,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下的按鍵驅動