全志科技
直播中

红旧衫

9年用户 744经验值
擅长:可编程逻辑 电源/新能源 制造/封装 EDA/IC设计
私信 关注
[问答]

怎样去解决gpio-keys驱动自动上报两次按键弹起的input事件呢

  • tina全部版本中,选用gpio-keys驱动,在系统上电时从log信息发现gpio-keys驱动自动上报了两次按键弹起的input事件。
    上报两次input事件的原因一共有两个,分别如下所示:
    1.由中断状态机误报一次中断。在gpio-keys驱动在初始化时,设置了软件上拉GPIO(或者是在硬件中上拉),对于中断状态机来说,外部GPIO已经是属于高电平了。在request_irq时,中断检测电路开始初始化,当前中断状态机的移位寄存器为0000(PS:中断检测电路用4bit来表示当前的中断触发方式,比如说0000认为外部是低电平,触发低电平中断)。
    当GPIO的功能寄存器设置为中断功能,中断状态机开始移位检测。因为当前GPIO为高电平,两个CLK时钟周期后,中断状态机的移位寄存器会出现0011的情况,这时候,即使未出现上升沿,也会认为触发了一次上升沿中断。
    这是中断误报属于硬件寄存器的问题,无法取消,只能规避。不过这个只会误报一次,后续驱动正常工作下不会再次误报的。除非设置改GPIO的复用功能为非中断功能,然后再设置GPIO为中断功能,这时候中断状态机又会重新初始化和误报一次中断。
  • 怎样去解决gpio-keys驱动自动上报两次按键弹起的input事件呢?

回帖(1)

杨季赟

2021-12-29 10:35:56
解决方法:


  • 在配置GPIO复用功能之后,等待一段时间,清一遍pending,去除第一次误触发中断。另外,在使用过程中,不要动态切换GPIO的复用功能。
  • 在gpio-keys驱动中,定义一些变量,强行让中断处理函数不去处理第一次中断事件。

2.由gpio-keys的gpio_keys_open()函数上报的:



static int gpio_keys_open(struct input_dev *input)
{
        struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
        const struct gpio_keys_platform_data *pdata = ddata->pdata;
        int error;


        if (pdata->enable) {
                error = pdata->enable(input->dev.parent);
                if (error)
                        return error;
        }


        /* Report current state of buttons that are connected to GPIOs */
        gpio_keys_report_state(ddata);


        return 0;
}
gpio_keys_report_state()函数来上报按键当前状态。在驱动probe函数和resume函数都会运行该函数。
这个函数是否需要运行主要取决于应用层的工作逻辑,不想在probe或者resume上报当前按键状态的话,也可以在代码中注释掉该函数。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分