别再只改DTS了!深入RK3568红外遥控驱动:从PWM捕获中断到Android KeyEvent的完整链路剖析
深入RK3568红外遥控驱动:从硬件中断到Android键值的全链路解析
红外遥控作为家电控制领域沿用数十年的经典技术,其背后的技术实现远比表面看到的按键触发复杂得多。当我们在RK3568平台上遇到键值乱跳、响应延迟等问题时,往往需要穿透Android应用层、HAL层、Linux输入子系统,直达PWM控制器硬件寄存器层面进行系统性排查。本文将完整揭示从红外光信号被PWM捕获,到最终转化为Android KeyEvent的整个技术链条。
1. 红外遥控的物理层与协议解析
红外遥控器发射的并非简单的光脉冲,而是经过载波调制的复合信号。典型的38kHz载波频率(周期约26.3μs)上叠加了NEC协议规定的数据帧。一个完整的NEC协议帧包含:
- 引导码:9ms高电平+4.5ms低电平
- 用户码:16位(用于区分不同设备)
- 键值码:16位(包含原码和反码)
- 结束码:560μs高电平
RK3568的PWM控制器在reference mode下,能够精确捕获这些高低电平的持续时间。通过配置remote_pwm_id和handle_cpu_id,PWM3控制器会:
- 检测到红外接收头的电平变化
- 触发中断并记录时间戳
- 将脉冲宽度数据存入
RMC_GETDATA寄存器
// 典型的中断处理逻辑(简化版) static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id) { u32 intsts = readl(pwm->regs + PWM_INTSTS); if (intsts & PWM_INTSTS_RISE) { rising_time = readl(pwm->regs + PWM_HRC); // 计算脉冲宽度... } if (intsts & PWM_INTSTS_FALL) { falling_time = readl(pwm->regs + PWM_LRC); // 解码逻辑... } writel(intsts, pwm->regs + PWM_INTSTS); return IRQ_HANDLED; }2. 设备树配置与内核驱动交互
正确的设备树配置是红外功能正常工作的基石。在&pwm3节点中,关键配置项包括:
| 配置项 | 作用 | 典型值 |
|---|---|---|
remote_pwm_id | 指定PWM通道 | 3 |
rockchip,usercode | 匹配遥控器厂商码 | 0x4040 |
rockchip,key_table | 键值映射表 | <0xf2 KEY_REPLY> |
调试时可使用以下命令验证驱动加载情况:
adb shell cat /proc/bus/input/devices # 查找包含"pwm"关键字的输入设备当出现键值异常时,首先应检查:
- GPIO复用配置(
pinctrl-0是否正确) - 用户码是否匹配(
USERCODE=0x4040) - 中断是否正常触发(
cat /proc/interrupts)
3. Linux输入子系统到Android HAL的转换
内核层获取的原始键值需要经过两次关键转换:
Linux输入事件码转换
通过rockchip_pwm_remotectl驱动将NEC协议码转换为标准Linux键值(定义在linux-event-codes.h):#define KEY_POWER 116 #define KEY_VOLUMEUP 115 #define KEY_VOLUMEDOWN 114Android键值映射
通过.kl(KeyLayout)文件将Linux键值映射为Android键值:key 116 POWER key 115 VOLUME_UP key 114 VOLUME_DOWN
关键调试命令:
adb shell getevent -l # 查看原始输入事件 adb shell dumpsys input # 查看Android输入系统状态4. 系统集成与调试技巧
在系统集成阶段,需要注意以下关键点:
文件部署路径
.kl文件应放置在/vendor/usr/keylayout/或/system/usr/keylayout/.idc文件需指定输入设备类型:device.internal = 1 audio.mic = 0
常见问题排查
- 按键无响应:检查
dmesg | grep remotectl输出 - 键值错误:确认
.kl文件中的映射关系 - 延迟过高:调整PWM中断处理线程的优先级
- 按键无响应:检查
自动化构建集成
在device.mk中添加:PRODUCT_COPY_FILES += \ device/rockchip/common/fdd70030_pwm.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/fdd70030_pwm.kl
对于特殊功能键(如长按Power键触发关机菜单),需要额外处理ACTION_DOWN和ACTION_UP事件,这通常需要在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java中实现自定义逻辑。
通过理解这个完整的信号链,开发者可以快速定位红外遥控相关问题,无论是硬件层面的中断异常,还是软件层的键值映射错误,都能有的放矢地进行排查和修复。
