9. 红外¶
本章节旨在让用户自定义红外遥控功能,需要有板载红外接收的板卡。
9.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值,后续需要修改键值对应的事件。
9.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 2 3 4 5 6 7 8 9 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
};
|
注意
按键对应的事件是自定义的,事件可根据实际需求确定
9.3. 修改设备树事件头文件¶
默认使用了rk定义的事件头文件,该文件不全面,使用内核通用的事件头文件linux-event-codes.h,如果不注释rk的头文件会报重复定义的警告。
1 2 | //#include <dt-bindings/input/rk-input.h>
#include <dt-bindings/input/linux-event-codes.h>
|

9.5. 测试¶
编译并替换设备树后,可进行测试,按下电源按键就会弹出关机窗口,打开桌面终端,按下按键1、2等数字按键,命令行也会同步输入相应数字,与键盘无异。

因为驱动使用的是输入子系统,可以检测输入事件的方法检测按键事件。
1 2 | #确认红外对应的事件
ls /dev/input/by-path/ -l
|

找到pwm-event对应的事件就是红外的事件。
可以通过以下程序监测输入事件。
1 2 3 4 5 6 7 8 9 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可确定按键是否按下。