RV1106 编写基于input 子系统的按键驱动程序遇到的问题总结

一、背景描述

1. 处理器与Linux 版本

  • ROCKCHIP RV1106
  • Linux 5.10.110

2. 按键对应的IO口

gpio1_pd1

3. 检测算法

按键按下

按键被按下时,按键IO 产生下降沿中断,在中断处理函数中,开启定时器进行防抖处理,防抖时间结束,按键还是保持低电平状态,则用input 子系统的上报按键按下事件。

按键弹起

按键弹起时,按键IO 产生上升沿中断,在中断处理函数中,开启定时器进行防抖处理,防抖时间结束,按键还是保持高电平状态,则用input 子系统的上报按键弹起事件。

二、修改设备树

1. 添加 pinctrl 子节点

&pinctrl{
          gpio1-pd1 {
                gpio1_pd1:gpio1-pd1{
                        rockchip,pins = <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
};

2. 添加gpio 子节点

gpios = <&gpio1 RK_PD1 GPIO_ACTIVE_LOW>;

3.中断相关的设备树属性

interrupts-parent = <&gpio1>;
interrupts = <RK_PD1 IRQ_TYPE_EDGE_BOTH>;

4. 按键对应的IO 节点的定义如下

gpio1pd1:gpio1pd1{
        compatible = "gpio1_pd1";
        pinctrl-names = "default";                                                                                                                                                                             pinctrl-0 = <&gpio1_pd1>;
        regulator-name ="gpio1_pd1";
        gpios = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
        interrupts-parent = <&gpio1>;                                                                                                                                                                          interrupts = <RK_PD1 IRQ_TYPE_EDGE_FALLING>;
        regulator-always-on;
};     

三、遇到的问题

1. 按键按下时,能响应中断处理函数,但是开启定时器进行防抖时,定时器超时中断没执行

在中断处理函数中,调用 mod_timer 函数修改超时时间并开启定时器时,第二个参数理解出错,当时是这样写的:

mod_timer( &g_key.timer,  20  );

mcu 程序时,软件定时器的超时时间一般是ms 为单位,现在切换到Linux 驱动程序,没切换过来,还想着填入一个20 ms 作为超时时间。

实际上,mod_timer 函数的第二个参数描述的是在系统节拍为 expires 时,调用超时处理函数。所以,应该改成下面所示:

mod_timer( &g_key.timer, jiffies + msecs_to_jiffies( 20 ) );

2. 驱动层在防抖结束之后,使用input 子系统上报了事件,但是应用层没读到上报的事件(或者经常没读到上报的事件)

上报事件代码

定时器超时处理函数如下,在超时函数中上报按键事件。

void key_drv_timer_handler( struct timer_list *timer )
{
    if ( !gpio_get_value( g_key.gpio_num ) )
        input_report_key( g_key.input_device, KEY_0, 0 );
    else
        input_report_key( g_key.input_device, KEY_0, 1 );
    input_sync( g_key.input_device );
}

原因

在调用 request_irq 申请中断时,只使能了下降沿中断(IRQF_TRIGGER_FALLING ),没有使能上升沿中断(IRQF_TRIGGER_RISING)。每次都是上报了按键为低的情况,input 子系统可能会以为按键的状态一直都是拉低,没弹起。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdut_llkkyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值