美文网首页
Andorid 按键处理一(基础知识)

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

作者: c枫_撸码的日子 | 来源:发表于2018-06-21 10:44 被阅读0次

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

    一、使用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文件中,系统会根据配置的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
    
    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,也就是音量减

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


    image.png

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


    手动生成
    打开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文件

    dct文件夹 dws

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


    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

    相关文章

      网友评论

          本文标题:Andorid 按键处理一(基础知识)

          本文链接:https://www.haomeiwen.com/subject/xfexyftx.html