刚接触RK3128平台的红外遥控功能时,我也以为就是简单配几个键值的事。直到实际调试智能盒子项目时,才发现从硬件DTS到Android应用层需要打通整整四个关键环节。这就像组装乐高玩具,少拼一块积木整个系统就跑不起来。下面我就用踩坑经验,带你走通这条"DTS→内核→Android→Uboot"的完整链路。
先看整体流程框架:
每个环节都有隐藏的"坑点"。比如我曾遇到遥控器能操作但无法唤醒设备,最后发现是Uboot配置漏了PWM唤醒参数。接下来我们逐个击破这些技术点。
DTS文件相当于硬件的"身份证",告诉内核红外接收器接在哪个PWM通道上。这是最基础的配置模板:
dts复制&remotectl {
status = "okay";
handle_cpu_id = <1>; // 指定处理中断的CPU核
ir_key1 {
rockchip,usercode = <0xfe01>; // 遥控器厂商代码
rockchip,key_table =
<0xaa KEY_POWER>, // 红外码转Linux键值
<0xbb KEY_MENU>,
<0xcc KEY_BACK>;
};
};
关键参数说明:
handle_cpu_id:建议设为1,避免主核被中断频繁打断usercode:必须与遥控器厂商提供的编码一致key_table:第一列是红外原始码,第二列对应input.h中的键值宏当遥控器按键无响应时,用这个组合拳排查:
bash复制adb shell
echo 1 > /sys/module/rockchip_pwm_remotectl/parameters/code_print
cat /proc/kmsg
这时按遥控器按键,会看到类似输出:
code复制[ 125.660000] USERCODE=0xfe01
[ 125.663000] key=0xaa
记录下每个按键的原始码,填入DTS的key_table。注意十六进制转换,比如0xaa要写成170。
dts复制rockchip,repeat_delay = <120>;
rockchip,repeat_period = <40>;
&pwm3节点是否被其他设备占用DTS配置好比建立了遥控器到Linux内核的通信协议,而.kl文件则是Android系统的"翻译官"。这个文件在/system/usr/keylayout/目录下,命名规则是厂商ID_设备ID.kl。
通过这个命令找到你的设备ID:
bash复制getevent -l
输出示例:
code复制/dev/input/event2: 20050030.pwm
那么对应的kl文件名就是20050030_pwm.kl。
kl文件内容格式很简单:
code复制key <LINUX键值> <Android功能名>
对照示例:
kl复制key 116 POWER // 电源键
key 158 BACK // 返回键
key 217 ASSISTANT // 语音助手
特殊功能键需要Android系统支持,比如TV设备特有的:
kl复制key 388 TV_INPUT // 信号源切换
bash复制adb shell input keyevent KEYCODE_HOME
bash复制adb shell dumpsys window | grep mCurrentFocus
KEYCODE_CUSTOM_1,然后在应用层监听要让红外遥控能唤醒设备,必须配置PMIC的唤醒源:
dts复制&rockchip_suspend {
rockchip,wakeup-config = <
RKPM_GPIO_WKUP_EN |
RKPM_PWM3_WKUP_EN // 启用PWM3唤醒
>;
};
特别注意:
用万用表测量红外接收器在休眠时的电流:
Uboot需要镜像内核的键值映射,修改路径:
u-boot/board/rockchip/common/rkloader/pwm_remotectl.c
添加你的遥控器配置:
c复制static struct rkxx_remote_key_table remote_key_table_fe01[] = {
{0xaa, KEY_POWER}, // 必须与DTS配置完全一致
{0xbb, KEY_MENU},
};
struct rkxx_remotectl_button remotectl_button[] = {
{
.usercode = 0xfe01,
.key_table = remote_key_table_fe01,
.nbuttons = 2,
}
};
重新编译Uboot后,测试关机状态下:
当整个流程跑不通时,按照这个顺序排查:
cat /proc/kmsg查看内核是否收到原始码getevent查看事件是否传递到应用层记得在DTS、KL、Uboot三处的键值配置必须完全一致。有次调试两天才发现是KL文件把116写成161,一个小数点就能让整个系统瘫痪。