最近完成了公司一个项目的红外透传,简单做下总结。

linux input子系统

linux输入设备种类繁杂,常见的包括触摸屏、键盘、鼠标、遥感等;linux将这些设备的共同特性抽象出来,linux input子系统就产生了。

 对于驱动编写者而言,不需要去关心应用层的事情,我们只需要按照要求上报这些输入事件即可。

一、软件架构

输入子系统是由设备驱动层(input driver)、输入核心层(input core)、输入事件处理层(input event handle)组成,具体架构如图。
在这里插入图片描述
(1)input设备驱动层:负责具体的硬件设备,将底层的硬件输入转化为统一的事件形式,向input核心层和汇报;
(2)input核心层:连接input设备驱动层与input事件处理层,向下提供驱动层的接口,向上提供事件处理层的接口;
(3)input事件处理层:为不同硬件类型提供了用户访问以及处理接口,将硬件驱动层传来的事件报告给用户程序。
所有的输入设备主设备号都是13,input-core通过次设备号来将输入设备进行分类。

二、input_dev结构体

struct input_dev {
     const char *name;
     const char *phys;
     const char *uniq;
     struct input_id id;

     unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];

     unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
     unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
     unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
     unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
     unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
     unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
     unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
     unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
     unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
     ........
};

evbit表示输入事件类型,可选事件类型定义在include/uapi/linux/input.h文件中,事件类型如下:
在这里插入图片描述

三、操作流程

申请初始化注册input_dev

1、使用input_allocate_device申请一个input_dev

struct input_dev *inputdev;
inputdev= input_allocate_device();  //申请input_dev
inputdev->name = "test_inputdev";  //设置input_dev名字

2、初始化input_dev的事件类型以及事件值

第一种设置键值的方法:

__set_bit(EV_KEY,inputdev->evbit);//设置产生按键事件
__set_bit(EV_REP,inputdev->evbit);//重复事件
__set_bit(KEY_0,inputdev->keybit);

第二种设置事件值的方法:

input_set_capability(input, EV_KEY, KEY_0);

3、使用input_register_device注册

input_register_device(inputdev);

注销 :

input_unregister_device(inputdev);

4、上报事件

上报事件,调用input_event()函数,

void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
{
      unsigned long flags;
 
      if (is_event_supported(type, dev->evbit, EV_MAX)) {
          spin_lock_irqsave(&dev->event_lock, flags);
          input_handle_event(dev, type, code, value);
          spin_unlock_irqrestore(&dev->event_lock, flags);
      }
}

该函数四个参数:
dev:上报事件的设备
type:事件总类型
code:事件子类型
vlaue:事件值。

input_event(inputdev, EV_KEY, keycode, 1);
input_sync(inputdev);//同步

getevent用法

getevent指令用于获取input输入事件,比如获取按键上报信息、获取触摸屏闪报信息等。
指令源码路径: