這兩天因為項目需求,需要在android系統(tǒng)增加兩個物理按鍵(WIFI/RESET (Pin Hole)).下面以WIFI鍵為例,我們開始分析Android系統(tǒng)增加按鍵流程:

說明:本篇文章主要分析Android 內(nèi)核部分
在介紹Android系統(tǒng)添加鍵值以前,先介紹INPUT子系統(tǒng)的流程.精簡流程圖如下

1.linux鍵值上報
1>linux-3.4/drivers/input/keyboard/sunxi-keyboard.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ->static irqreturn_t sunxi_isr_key(int irq, void *dummy)

從方法 input_report_key(sunxikbd_dev, sunxi_scankeycodes[scancode], 0) ,我們可以看到上報的值 sunxi_scankeycodes[scancode]
2>linux-3.4/drivers/input/keyboard/sunxi-keyboard.c

查看sunxi-keyboard.c源碼,我們可以看到scancode的值為 數(shù)組keypad_mapindex[64]中的值,對于該數(shù)組中0-7的理解:硬件上物理按鍵按下,電壓變換通過模數(shù)轉(zhuǎn)換,變成數(shù)字電壓,我們將這里的電壓變換范圍分成64份,每一份對應一個電壓值,假設每一份電壓值為0.2,那么可以認為0-1.4之間電壓變化時,我們就認為 key1 按下.
3>linux-3.4/drivers/input/keyboard/sun8i-keyboard.h

在 sunxi_scankeycodes[KEY_MAX_CNT] 數(shù)組中定義了內(nèi)核需要上報給系統(tǒng)的值,但是這些可以上報的值(比如:KEY_VOLUMEUP )定義在哪里呢?我們繼續(xù)查看 sun8i-keyboard.h 源碼
3>linux-3.4/include/linux/input.h

為了不讓篇幅過長,這里只截取了部分
至此, linux層按鍵上報流程就分析了.????????????????????????????????????????????????????????????????????????????????????????????????????
總結一下:
1.linux內(nèi)核通過掃碼,將硬件上按鍵按下電壓變換轉(zhuǎn)為數(shù)字電壓并且映射到數(shù)組下標? ? ? ? ? ? ?
2.通過 keypad_mapindex[64], sunxi_scankeycodes[KEY_MAX_CNT] 兩個數(shù)組關系轉(zhuǎn)化將按鍵映射到內(nèi)核中預定義的鍵值???????????????????????????????????????????????????????????????????????????????????????????????????????
3.最終linux內(nèi)核上報給上層的就是一個 整形值