前言:最近很疑惑,当我们点击一个按键时,从底层到上层整个流程是怎样的,想要弄清楚这个,我们得先掌握一些必要的基础知识。
一、使用adb命令查看按键事件
当我们点击一个按键时,会产生中断,通过adb命令查看相关信息
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代表按了哪个按键呢?
按键码的定义在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
其中会编译生成 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,也就是音量减
另外,除了系统编译生成配置文件,还可以手动生成
点击Gen Code按钮 dws生成许多文件,其中就包含cust_kpd.dtsi
打开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文件
以keypad文件为例子,我们可以看到上图dws文件中,点击VOLUMEUP,有很多选项,这些选项怎么来的,如果我们要增加一个选项应该怎么办呢?
实际上,当我们用DrvGen.exe工具打开dws文件时,里面的这些选项都是根据文件夹下面的cmp文件来读取的,
以Keypad_YuSu.cmp为例子 【用txt或者notpad++打开即可】
可以看到,这里的值,对应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