linux gpio key 实现方式

本文深入探讨Linux GPIO Key驱动的实现方式与原理,介绍两种实现方法:单个GPIO作为input event上报和定义GPIO key,分别适用于键较少和较多的情况。详细解析gpio-keys驱动代码结构,包括dts配置示例,以及按键事件读取方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux gpio key 实现方式

linux gpio key可以实现两种方式,如果key比较少的话,(1)可以选择单个的gpio作为一个input event来上报,这样的方式的优点是按键比较独立,缺点是如果key比较多会生成比较多的input event (2) 正常的话可以定义gpio key, 给不同的gpio选择不同的键值,个人觉得这种方式比较正规,包括遥控按键的上报也是用这种方式。无论使用那种方式,通常只需要修改dts就可以了.

gpio-key 实现原理

gpio-key是基于input架构实现的通用gpio按键驱动,该驱动是基于platform_driver架构,实现了驱动和设备的分离,符合linux设备驱动模型的基本思想。

代码的驱动部分:
drivers/input/keyboard/gpio_keys.c
这里基本不需要我们修改,只需要我们了解其中的实现流程就好。
代码的dts部分:
主要修改的部分是dts部分,借用网上通用代码。
第一种方式dts的写法

107     key-home {                                                                                                                             
108         compatible = "gpio-keys";                                                                                                          
109         autorepeat;                                                                                                                        
110                                                                                                                                            
111         pinctrl-names = "default";                                                                                                         
112         pinctrl-0 = <&home_key>;                                                                                                           
113                                                                                                                                            
114         home {                                                                                                                             
115             label = "GPIO Home";                                                                                                           
116             linux,code = <KEY_HOME>;                                                                                                       
117             gpios = <xxxx>;                                                                                       
118             debounce-interval = <15>;                                                                                                      
119         };                                                                                                                                 
120     };                                                                                                                                     
121                                                                                                                                            
122     key-xxx{                                                                                                                            
123         compatible = "gpio-keys";                                                                                                          
124         autorepeat;                                                                                                                        
125                                                                                                                                            
126         pinctrl-names = "default";                                                                                                         
127         pinctrl-0 = <&xxx_key>;
128 
129         reset {
130             label = "GPIO xxxx";
131             linux,code = <KEY_1>;
132             gpios = <&xxxxx_ACTIVE_LOW>;
133             debounce-interval = <15>;
134         };
135     };


776 &pinctrl {
777 
778     pinctrl-names = "default";
781     buttons {
782         home_key: home-key {
783             rockchip,pins = <xxxx  &pcfg_pull_up>;
784         };
785         pwr_key: pwr-key {
786             rockchip,pins = <xxxx &pcfg_pull_up>;
787         };
790         };


第二种dts写法

 gpio-keys {                                                                                                                            
          compatible = "gpio-keys";                                                                                                          
          autorepeat;                                                                                                                        
                                                                                                                                             
          pinctrl-names = "default";                                                                                                         
          pinctrl-0 = <&s8_keys>;                                                                                                            
                                                                                                                                             
          power {                                                                                                                            
              gpios = <XXXXXX GPIO_ACTIVE_LOW>;                                                                                       
              linux,code = <KEY_POWER>;                                                                                                      
              label = "GPIO Key Power";                                                                                                      
              debounce-interval = <20>;                                                                                                      
          };                                                                                                                                 
                                                                                                                                             
         home {                                                                                                                             
              gpios = <YYYYY GPIO_ACTIVE_LOW>;                                                                                       
              linux,code = <KEY_HOME>;                                                                                                       
              label = "GPIO Key Home";                                                                                                       
              debounce-interval = <20>;                                                                                                      
          };                                                                                                                                 
      };

 &pinctrl {
     pinctrl-names = "default";    
     buttons {
         s8_keys: s8-keys {
             rockchip,pins = <XXXX &pcfg_pull_up>,                                                                         
                     <XXXXXXXX &pcfg_pull_up>;
         };
        }

1、节点名字为“gpio-keys”。
2、gpio-keys 节点的 compatible 属性值一定要设置为“gpio-keys”。
3、所有的 KEY 都是 gpio-keys 的子节点,每个子节点可以用如下属性描述自己:
gpios:KEY 所连接的 GPIO 信息。
interrupts:KEY 所使用 GPIO 中断信息,不是必须的,可以不写。
label:KEY 名字
linux,code:KEY 要模拟的按键可以直接填数字
可以直接填数字
gpio-key,wakeup:可以被唤醒
debounce-interval:消抖时间

以上就在linux driver端使能了key,接下来可以在hal层读取/dev/
/dev/input/eventX 读取key event的事件了

具体hal读取按键的几种方式,可看我的git源码
网上的 应用代码,没有select

#define RECOVERY_KEY "/dev/input/event2"
#define RECOVERY_KEY_CODE 115
#define RECOVERY_KEY_PRESS 0
void recovery_key_press_timer(int sig)
{
 if(SIGALRM == sig)
 {
  printf("alarm 6s.\n");
 }
 return;
}
static void read_recovery_key_event()
{
 int fd = -1, ret = -1;
 struct input_event ev;
 fd = open(RECOVERY_KEY, O_RDONLY);
 if (fd < 0)
 {
  printf("open RECOVERY_KEY event failed.\n");
  return;
 }
 memset(&ev, 0, sizeof(struct input_event));
 ret = read(fd, &ev, sizeof(struct input_event));
 if (ret != sizeof(struct input_event))
 {
  printf("read RECOVERY_KEY event failed.\n");
  close(fd);
 }
 if( (RECOVERY_KEY_CODE == ev.code) && (RECOVERY_KEY_PRESS == ev.value) )
 {
  printf("recovery-key press.\n");
  alarm(6);
 }
 else
 {
  printf("recovery-key release.\n");
  alarm(0);
 }
 close(fd);
}
int main(int argc, char **argv)
{
    int rc = 0;
 signal(SIGALRM, recovery_key_press_timer);
 while(1)
 {
  read_recovery_key_event();
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值