紅外
本章節旨在讓用戶自定義紅外遙控功能,需要有板載紅外接收的板卡。
12.1.?獲取紅外遙控鍵值
由于不同遙控器廠家定義的按鍵鍵值不一樣,所以配置不通用,需要獲取實際按鍵對應的鍵值。
1 2 3 4 5 6 | #設置輸出等級 echo '7 4 1 7'> /proc/sys/kernel/printk #開啟打印 echo 1 > /sys/module/rockchip_pwm_remotectl/parameters/code_print#此時按下按鍵串口終端就會有打印USERCODE和鍵值 |
提示
如果是ssh或者桌面終端不會直接打印信息到終端,需要執行 dmesg 命令進行查看
以野火紅外遙控器為例:
遙控器資料鏈接:?野火【紅外遙控_1838】模塊
對著板卡按下按鍵,每按下一個按鍵就會打印USERCODE和鍵值到串口終端。
記錄USERCODE值和按鍵對應的RMC_GETDATA值,后續需要修改鍵值對應的事件。
12.2.?修改設備樹紅外按鍵事件
需要修改內核源碼板卡對應的設備樹,如果不確定設備樹是哪個的,可以執行?ls -l /boot?看 rk-kernel.dtb軟連接到哪個dtb,改對應的dts即可。
以魯班貓1的dts為例:
找到紅外對應的pwm ir節點,魯班貓1對應的是pwm3,修改ir_key_lubancat部分
-
將實際的USERCODE值改到 rockchip,usercode = <0xff00>;
-
將鍵值和需要配置事件改到rockchip,key_table表里面。
對應的事件可以從?內核源碼/include/dt-bindings/input/linux-event-codes.h?中取。linux-event-codes.h文件定義了輸入事件的類型和代碼,用于描述和標識各種輸入設備(如鍵盤、鼠標、觸摸屏等)生成的事件。
例如,遙控器上面的電源按鍵需要配置為板卡的電源開關機鍵,那么可以從linux-event-codes.h找到的事件KEY_POWER。
例如,遙控器上面的按鍵1要對應鍵盤上的1,那么可以從linux-event-codes.h找到的事件KEY_1。
依次從linux-event-codes.h中找到按鍵對應的事件后,將按鍵值和實際一一對應,修改得到以下內容:
123456789 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ir_key_lubancat{rockchip,usercode = <0xff00>;rockchip,key_table =<0xba KEY_POWER>, //電源按鍵<0xb8 KEY_MENU>, //菜單按鍵<0xbc KEY_BACK>, //返回按鍵<0xbb KEY_HOME>, //home鍵按鍵<0xea KEY_PLAY>, //播放按鍵<0xbf KEY_VOLUMEUP>, //音量加按鍵<0xe6 KEY_VOLUMEDOWN>, //音量鍵按鍵<0xf6 KEY_FASTFORWARD>, //快進按鍵<0xf8 KEY_FASTREVERSE>, //快退按鍵<0xf2 KEY_BACKSPACE>, //BaskSpace按鍵<0xf3 KEY_1>, //按鍵1<0xe7 KEY_2>,<0xa1 KEY_3>,<0xf7 KEY_4>,<0xe3 KEY_5>,<0xa5 KEY_6>,<0xbd KEY_7>,<0xad KEY_8>,<0xb5 KEY_9>,<0xe9 KEY_0>; //按鍵0}; |
注意
按鍵對應的事件是自定義的,事件可根據實際需求確定
12.3.?修改設備樹事件頭文件
默認使用了rk定義的事件頭文件,該文件不全面,使用內核通用的事件頭文件linux-event-codes.h,如果不注釋rk的頭文件會報重復定義的警告。
1 2 | //#include <dt-bindings/input/rk-input.h> #include <dt-bindings/input/linux-event-codes.h> |
12.4.?編譯并替換設備樹
參考驅動篇:?編譯設備樹章節
12.5.?測試
編譯并替換設備樹后,可進行測試,按下電源按鍵就會彈出關機窗口,打開桌面終端,按下按鍵1、2等數字按鍵,命令行也會同步輸入相應數字,與鍵盤無異。
因為驅動使用的是輸入子系統,可以檢測輸入事件的方法檢測按鍵事件。
1 2 | #確認紅外對應的事件 ls /dev/input/by-path/ -l |
找到pwm-event對應的事件就是紅外的事件。
可以通過以下程序監測輸入事件。
123456789 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h>int main(int argc, char *argv[]) {struct input_event in_ev = {0};int fd = -1;int pulse_count=0;/* 校驗傳參 */if (2 != argc) {fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);exit(-1);}/* 打開文件 */if (0 > (fd = open(argv[1], O_RDONLY))) {perror("open error");exit(-1);}for ( ; ; ) {/* 循環讀取數據 */if (sizeof(struct input_event) !=read(fd, &in_ev, sizeof(struct input_event))) {perror("read error");exit(-1);}printf("type:%d code:%d value:%d\n",in_ev.type, in_ev.code, in_ev.value);} } |
創建buttons.c并將以上內容添加buttons.c,編譯并運行
1 2 3 4 5 | #編譯 gcc buttons.c -o buttons#運行,需要指定實際的pwm-event sudo ./buttons /dev/input/event0 |
以下是按下按鍵1的情況,對應事件KEY_1。
可見,打印的code值為2,對應linux-event-codes.h中的 “#define KEY_1 2”,也即可以通過code值區分事件,value可確定按鍵是否按下。