11. 红外#
本章节旨在让用户自定义红外遥控功能,需要有板载红外接收的板卡。
注意
目前野火量产的板卡均没有贴红外接收器,无红外接收器的板卡无法使用红外功能。
11.1. 获取红外遥控键值#
由于不同遥控器厂家定义的按键键值不一样,所以配置不通用,需要获取实际按键对应的键值。
1#设置输出等级
2echo '7 4 1 7'> /proc/sys/kernel/printk
3#开启打印
4echo 1 > /sys/module/rockchip_pwm_remotectl/parameters/code_print
5
6#此时按下按键串口终端就会有打印USERCODE和键值
提示
如果是ssh或者桌面终端不会直接打印信息到终端,需要执行 dmesg 命令进行查看
以野火红外遥控器为例:
遥控器资料链接: 野火【红外遥控_1838】模块
对着板卡按下按键,每按下一个按键就会打印USERCODE和键值到串口终端。
记录USERCODE值和按键对应的RMC_GETDATA值,后续需要修改键值对应的事件。
11.2. 修改设备树红外按键事件#
需要修改内核源码板卡对应的设备树,如果不确定设备树是哪个的,可以执行 ls -l /boot 看 rk-kernel.dtb软连接到哪个dtb,改对应的dts即可。
以鲁班猫3的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中找到按键对应的事件后,将按键值和实际一一对应,修改得到以下内容:
1 ir_key_lubancat{
2 rockchip,usercode = <0xff00>;
3 rockchip,key_table =
4 <0xba KEY_POWER>, //电源按键
5 <0xb8 KEY_MENU>, //菜单按键
6 <0xbc KEY_BACK>, //返回按键
7 <0xbb KEY_HOME>, //home键按键
8 <0xea KEY_PLAY>, //播放按键
9 <0xbf KEY_VOLUMEUP>, //音量加按键
10 <0xe6 KEY_VOLUMEDOWN>, //音量键按键
11 <0xf6 KEY_FASTFORWARD>, //快进按键
12 <0xf8 KEY_FASTREVERSE>, //快退按键
13 <0xf2 KEY_BACKSPACE>, //BaskSpace按键
14 <0xf3 KEY_1>, //按键1
15 <0xe7 KEY_2>,
16 <0xa1 KEY_3>,
17 <0xf7 KEY_4>,
18 <0xe3 KEY_5>,
19 <0xa5 KEY_6>,
20 <0xbd KEY_7>,
21 <0xad KEY_8>,
22 <0xb5 KEY_9>,
23 <0xe9 KEY_0>; //按键0
24 };
注意
按键对应的事件是自定义的,事件可根据实际需求确定
11.3. 修改设备树事件头文件#
默认使用了rk定义的事件头文件,该文件不全面,使用内核通用的事件头文件linux-event-codes.h,如果不注释rk的头文件会报重复定义的警告。
1//#include <dt-bindings/input/rk-input.h>
2#include <dt-bindings/input/linux-event-codes.h>
11.4. 编译并替换设备树#
参考驱动篇: 编译设备树章节
11.5. 测试#
编译并替换设备树后,可进行测试,按下电源按键就会弹出关机窗口,打开桌面终端,按下按键1、2等数字按键,命令行也会同步输入相应数字,与键盘无异。
因为驱动使用的是输入子系统,可以检测输入事件的方法检测按键事件。
1#确认红外对应的事件
2ls /dev/input/by-path/ -l
找到pwm-event对应的事件就是红外的事件。
可以通过以下程序监测输入事件。
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <linux/input.h>
8
9int main(int argc, char *argv[])
10{
11 struct input_event in_ev = {0};
12 int fd = -1;
13 int pulse_count=0;
14
15 /* 校验传参 */
16 if (2 != argc) {
17 fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
18 exit(-1);
19 }
20
21 /* 打开文件 */
22 if (0 > (fd = open(argv[1], O_RDONLY))) {
23 perror("open error");
24 exit(-1);
25 }
26
27 for ( ; ; ) {
28
29 /* 循环读取数据 */
30 if (sizeof(struct input_event) !=
31 read(fd, &in_ev, sizeof(struct input_event))) {
32 perror("read error");
33 exit(-1);
34 }
35
36 printf("type:%d code:%d value:%d\n",
37 in_ev.type, in_ev.code, in_ev.value);
38 }
39}
创建buttons.c并将以上内容添加buttons.c,编译并运行
1#编译
2gcc buttons.c -o buttons
3
4#运行,需要指定实际的pwm-event
5sudo ./buttons /dev/input/event0
以下是按下按键1的情况,对应事件KEY_1。
可见,打印的code值为2,对应linux-event-codes.h中的 "#define KEY_1 2",也即可以通过code值区分事件,value可确定按键是否按下。