红外
本章节旨在让用户自定义红外遥控功能,需要有板载红外接收的板卡。
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可确定按键是否按下。