Andorid 按键处理一(基础知识)

前言:最近很疑惑,当我们点击一个按键时,从底层到上层整个流程是怎样的,想要弄清楚这个,我们得先掌握一些必要的基础知识。

一、使用adb命令查看按键事件

当我们点击一个按键时,会产生中断,通过adb命令查看相关信息


Andorid 按键处理一(基础知识)_第1张图片
按键事件
type(事件类型) code(事件代码) value(事件的值)
0001 0072 00000001
0001 0072 00000000

1.type 事件类型

路径:/usr/include/linux/input.h
type:是事件类型 在input.h中有定义
如EV_KEY按键事件类型
事件类型可以设置为:
#defineEV_SYN          0x00    表示设备支持所有的事件  哨兵事件,当驱动层一个事件的
所有数据包都发送完了,就会发送一个哨兵事件表示这次的事件处理完成
#defineEV_KEY          0x01    键盘或者按键,表示一个键码  
#define EV_REL         0x02    鼠标设备,表示一个相对的光标位置结果
#defineEV_ABS          0x03    手写板产生的值,其是一个绝对整数值
#define EV_MSC         0x04    其他类型
#define EV_LED         0x11    LED灯设备
#defineEV_SND          0x12    蜂鸣器,输入声音
#define EV_REP         0x14    允许重复按键类型
#define EV_PWR         0x16    电源管理事件
#define EV_FF_STATUS 0x17
#define EV_MAX 0x1f
#define EV_CNT (EV_MAX+1)

2.code 事件代码

路径:/usr/include/linux/input.h
code :是事件代码 在input.h中有定义
当事件类型是EV_KEY的时候,code为设备键盘码 0~127为键盘上的按键
 #define KEY_TAB            15
#define KEY_Q               16
#define KEY_W               17
#define KEY_E               18
#define KEY_R               19
#define KEY_T               20
#define KEY_Y               21
#define KEY_U               22
#define KEY_I               23
#define KEY_O               24
#define KEY_P               25
#define KEY_LEFTBRACE       26
#define KEY_RIGHTBRACE      27
#define KEY_ENTER           28
#define KEY_LEFTCTRL        29
#define KEY_A               30
#define KEY_S               31
#define KEY_D               32
#define KEY_F               33
#define KEY_G               34
#define KEY_H               35
#define KEY_J               36
#define KEY_K               37
#define KEY_L               38
#define KEY_SEMICOLON       39
#define KEY_APOSTROPHE      40
#define KEY_GRAVE           41
#define KEY_LEFTSHIFT       42
#define KEY_BACKSLASH       43
#define KEY_Z               44 

3.value 事件的值

Type为EV_KEY时,value: 0表示按键抬起。1表示按键按下。
Type为EV_REL时,value: 表明移动的值和方向(正负值)。
Type为EV_ABS时,code表示绝对位置。等待

因此 当我们点击一个按键(以音量下键为例)时,上报以下信息,意义为:
0001 0072 00000001
0000 0000 00000000
0001 0072 00000000
0000 0000 00000000
0001:代表按键事件
0072:按键代码 这里是16进制 转化成10进制为114
00000001:代表按下
0000 0000 00000000:代表驱动已经发出了一个完整的事件
也就是说:
0001 0072 00000001
0000 0000 00000000 代表按下按键
0001 0072 00000000
0000 0000 00000000代表松开按键

源码中
路径:kernel-3.18/drivers/input/keyboard/mediatek/kpd.c
static void kpd_keymap_handler(unsigned long data){
  //上报 0001 0072 00000001
  input_report_key(kpd_input_dev, linux_keycode, pressed);
 
  input_sync(kpd_input_dev); //上报 0000 0000 00000000
}

另外 还有一个疑问?
0072:按键代码 这里是16进制 转化成10进制为114
这里的114代表按了哪个按键呢?


Andorid 按键处理一(基础知识)_第2张图片
dws文件

按键码的定义在dws文件中,系统会根据配置的dws文件最终生成dtsi文件,里面会有一个keypad节点

路径:out/target/product/timovi8735m1_9013/obj/PRELOADER_OBJ/inc/cust_kpd.dtsi
&keypad{
 mediatek,kpd-key-debounce = <1024>;
 mediatek,kpd-sw-pwrkey = <116>;
 mediatek,kpd-hw-pwrkey = <8>; 
 mediatek,kpd-sw-rstkey = <114>;
 mediatek,kpd-hw-rstkey = <17>;
 mediatek,kpd-use-extend-type = <0>; 

 mediatek,kpd-hw-map-num = <72>;
 mediatek,kpd-hw-init-map = <115 114 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 >; 
 mediatek,kpd-pwrkey-eint-gpio = <0>; 
 mediatek,kpd-pwkey-gpio-din = <0>; 
 mediatek,kpd-hw-dl-key0 = <0>; 
 mediatek,kpd-hw-dl-key1 = <1>; 
 mediatek,kpd-hw-dl-key2 = <8>; 
 status = "okay";
}; 
其中 mediatek,kpd-sw-pwrkey = <116>;代表电源键 十六进制74
Andorid 按键处理一(基础知识)_第3张图片
dws部分截图

其中会编译生成 mediatek,kpd-hw-init-map节点,
kpd-hw-init-map为硬件扫描的矩阵列表,跟具体硬件接法相关。即为linux_code

 mediatek,kpd-hw-init-map = <115 114 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 >;

115(73)代表VOLUMEUP
114(72)代表VOLIUMEDOWN

到这里,我们就弄清楚了114(72)代表VOLIUMEDOWN,也就是音量减

另外,除了系统编译生成配置文件,还可以手动生成


Andorid 按键处理一(基础知识)_第4张图片
image.png

点击Gen Code按钮 dws生成许多文件,其中就包含cust_kpd.dtsi


Andorid 按键处理一(基础知识)_第5张图片
手动生成

打开cust_kpd.dtsi文件 可以看到
Andorid 按键处理一(基础知识)_第6张图片
cust_kpd.dtsi

二.DWS文件以及tool工具的路径

dws文件路径:
【kernel】
kernel-3.18/drivers/misc/mediatek/dws/{平台}/{项目名}.dws
【vendor】
1.vendor/mediatek/proprietary/bootable/bootloader/
            lk/target/{项目名}/dct/dct/codegen.dws
2.vendor/mediatek/proprietary/bootable/bootloader/
            preloader/custom/{项目名}/dct/dct/codegen.dws
3.vendor/mediatek/proprietary/custom/{项目名}/kernel/dct/dct/codegen.dws
DrvGen.exe工具路径(用来打开dws文件)
kernel-3.18/tools/dct/old_dct
vendor/mediatek/proprietary/bootable/bootloader/lk/scripts/dct/old_dct
vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/dct/old_dct

三.CMP文件

Andorid 按键处理一(基础知识)_第7张图片
dct文件夹
Andorid 按键处理一(基础知识)_第8张图片
dws

以keypad文件为例子,我们可以看到上图dws文件中,点击VOLUMEUP,有很多选项,这些选项怎么来的,如果我们要增加一个选项应该怎么办呢?
实际上,当我们用DrvGen.exe工具打开dws文件时,里面的这些选项都是根据文件夹下面的cmp文件来读取的,
以Keypad_YuSu.cmp为例子 【用txt或者notpad++打开即可】


Andorid 按键处理一(基础知识)_第9张图片
Keypad_YuSu.cmp

可以看到,这里的值,对应dws文件中的选项,
因此,如果想自己添加新的按键定义等,就必须在Keypad_YuSu.cmp中添加

同样的道理还有EINT_YuSu.cmp、GPIO_YuSu.cmp、I2C_YuSu.cmp等文件

到此,我们需要了解的一些基础知识就分享完毕了。

Stay hungry,Stay foolish!
荆轲刺秦王

参考文档:
1.https://blog.csdn.net/leesagacious/article/details/50190747
2.https://blog.csdn.net/u013604527/article/details/53432623
3.https://blog.csdn.net/oyhb_1992/article/details/77606856
4.https://blog.csdn.net/richu123/article/details/51381015?locationNum=6&fps=1

你可能感兴趣的