MT9630/9632 遥控器配置

目录

遥控器码值映和开发构思

9632 遥控器架构介绍

IR 简介

1.1. IR 框架介绍

1.2. 疑问: decoder list 和 map list 怎么来的?

1.3. IR 目录结构

​编辑

2 ir_config.ini 介绍

2.1. 配置 kernel

2.2. Ir_config.ini 的格式分析

2.3. 支持公版 ir 的 ini 文件

有时候拿到客户的平台,没有给客户的遥控器,可以替换这个 ini 来支持公版的遥控。这个也可以给到客户那边进行参考,怎么配置 ir_config.ini

3. 配置 MT9632 项目遥控

3.2. input-event-codes.h 配置

3.3. input_keys_available.h 配置

3.4. Vendor_3697_Product_0001.kl 配置

3.4.1 Kl 文件的介绍(Android 平台)

3.4.2 使用的 Kl 文件查询

3.4.3 KL 格式分析:

3.5. InputEventLabels.h 配置

DEFINE_KEYCODE(RP_SHUTDOWN_READY),DEFINE_KEYCODE(RP_ALT_TAB),DEFINE_KEYCODE(RP_SPACE),DEFINE_KEYCODE(RP_ALT_F4),DEFINE_KEYCODE(RP_RIGHT),DEFINE_KEYCODE(RP_PC),DEFINE_KEYCODE(RP_HDMI),DEFINE_KEYCODE(RP_TV),DEFINE_KEYCODE(RP_MEDIA),DEFINE_KEYCODE(RP_RESOLUTION),

3.6. keycodes.h 配置

3.7. attrs.xml 配置 

3.8. KeyEvent.java 配置

4 调试方法 

4.1. 开 debug log

 4.2. 借助 getevent

4.3 常见问题:


                      

                        遥控器码值映和开发构思

1 问题
        MT9632 延续了 Mstar-8386 的处理方式,直接在 frameworks 的 PhoneWindowManager 中
处理, 这样处理方式不仅导致调试不方便, 而且代码的管理, 可扩展性和后期维护比较困
难。

2 解决方案
        在 MT9632 方案开发中引入中间件技术开发,在中间件的 RPapi 和 RPService 中采用观察者
模式创建回调和监听机制,在 PhoneWindowManager 中转发传输到中间件中由
RPSystemService 的 KeyEventManager 统一处理按键和遥控器。

3 kernel 和 Android 自定义映射码值
Android 层码值涉及文件
Frameworks/base/core/java/android/view/KeyEvent.java
Frameworks/base/core/res/res/values/attrs.xml
Frameworks/native/include/android/keycodes.h
Frameworks/native/include/input/InputEventLabels.h
Kernel 层码值涉及文件:
kernel/fusion/mstar2/drv/ir_mirc/ir_dynamic_config/input_keys_available.h
kernel/fusion/4.9/include/uapi/linux/input-event-codes.h
MTK 架构涉及文件
vendor/mediatek/proprietary_tv/apollo/linux_core/misdk/mi/mi/platform/m7332/linux/board_c
fg/BD_MT165B_10AT_19055_4K/ir_config.ini
vendor/mediatek/proprietary_tv/open/product/m7332/preinstall/keylayout/
Vendor_3697_Product_0001.kl
目前自定义 73 个键值码, 开发者直接查阅 KeyEvent.java 文件

4 开发步骤
定义好键值映射关系之后,后期的开发中如果有新客户项目加入,对应遥控器的配置只需
要修改 MTK 架构涉及文件 Vendor_3697_Product_0001.kl 和 ir_config.ini 即可,这两个文件可
直接在线替换到机器上。除非新增 keycode,否则不会动其他文件。
替换路径:
Vendor_3697_Product_0001.kl: vendor/usr/keylayout/Vendor_3697_Product_0001.kl
ir_config.ini: vendor/tvconfig/config/ir_config.ini
接着到 RPSystemService 的 KeyEventManager 中处理 keycode 对应的逻辑, 编译之后直
接替换主板上是 RPSystemService.apk

                               9632 遥控器架构介绍

IR 简介


        拿来一个遥控器,我们需要拿到他对应的规格书,从规格书中我们可以知道他是什么协
议,头码是多少,每个按键的键值是多少?这些都表示遥控器的属性。
那我们怎么让系统识别遥控器的不同按键呢? 就需要 kernel 针对协议进行解析(ir
decoder),解析完后要告诉 kernel 这个键值映射成了什么功能(ir map),这样上层就知
道接下来要做什么了。
所以,配置一款遥控器重点在于 decoder + map。

1.1. IR 框架介绍


1. IR 框架分为四层: IR Driver 层, IR core 层, Decoder 层, Keymap 层。
2. IR Driver 层: 需要实现 IR Driver 的一些 init, interrupt 处理,
file_operations 操作等。
3. IR core 层:需要实现提供给 decoder 层, keymap 层的相关接口, raw 数据处理接
口, input 相关接口等。
4. Decoder 层:需要实现不同 protocols 的解析函数。
5. Keymap 层:需要实现针对不同 IR 的 keymap 映射关系。

上面的图中重要细节解释:
① 中断处理程序获取 register data 保存到 fifo, kthread 读取 fifo 数据。
② kthread 取 fifo 数据后送给 decoder 匹配协议解析过程
③ decoder 链表注册和销毁
④ 解析得到 keycode 匹配 keymap 的过程,这里用 keymapnumber 来匹配
⑤ keymap 链表注册和销毁
⑥ keycode 传给/dev/ir read 的过程,供上层 polling 方式取 key
⑦ keycode 传给 input 过程,以 event 的方式传递给 Android 层

1.2. 疑问: decoder list 和 map list 怎么来的?


从前面介绍,我们需要配置一款遥控器,需要有 decoder + map,所以 fusion 关于 ir
的配置就是要围绕 decoder list 和 map list 进行配置。
1. Ir_config.h 进行配置出来
2. Ir_config.ini 进行 parse 出来。
 

1.3. IR 目录结构

2 ir_config.ini 介绍
 

        Ir_config.ini 是用来动态配置系统用的遥控器的。比如,客户不需要编译 image,直接替换
ini 就可以使得遥控器可以正常工作。

2.1. 配置 kernel
 

         要想使用 ir_config.ini , Kernel config 需要选择 dynamic ir 配置,如下面 config 截图和
menuconfig 勾选。

CONFIG_IR_CONFIG_PATH="/vendor/tvconfig/config/ir_config.ini"
然后就可以把 dynamic ir 编译进 kernel, kernel 就可以从
/vendor/tvconfig/config/ir_config.ini 里面去 load ini 里面配置的 ir 信息了。
Fusion 项目
 

2.2. Ir_config.ini 的格式分析
 

MT9632 项目的 IR 的配置文件默认路径在:
vendor/mediatek/proprietary_tv/apollo/linux_core/misdk/mi/mi/platform/m733
2/linux/board_cfg/BD_MT165B_10AT_19055_4K/Ir_config.ini
内容总体分为[kernel],[mboot],[pm51]三个 section。
 

关于[Kernel]部分
[Kernel] 部分结构分为三级一级是[Kernel] section,序号指向各个遥控器的配置,二级是
[遥控器配置],内部的 Keymap 指向第三级键值和 scancode 对照表表。
首先 IR Kernel Module 会去找[kernel]这个 section,然后去里面找配置所在的 section
名字。


[Kernel]
0=KIR_CONFIG0 # ➔这里序号 0 代表第一组 IR Config, kernel 会去找名字为
KIR_CONFIG0 的 section
1=KIR_CONFIG1 # ➔这里序号 1 代表第一组 IR Config, kernel 会去找名字为
KIR_CONFIG1 的 section
2=KIR_CONFIG2 # ➔这里序号 2 代表第一组 IR Config, kernel 会去找名字为
KIR_CONFIG2 的 section

# ➔[Kernel]这部分最多可以写序号 0~14 共 15 种配置,从序号 0 开始,顺序要连续,
其中 KIR_CONFIG0 可以随意使用字母数字与下划线命名,但是[Kernel]这个 section 名
不可以更改。
[KIR_CONFIG0]

[KIR_CONFIG1]

[KIR_CONFIG2]

针对每把遥控器的配置 section 例如[IR_CONFIG0]的内容:
[KIR_CONFIG0]
Enable=true #➔这个 section 可以标识为 true/false 用于使能/关闭该配置
Protocol=0x01 # ➔protocol 目前可选范围为:
#NEC=0x01,
#RC5=0x02,
#RC6=0x03,
#RCMM=0x04,
#KONKA=0x05,
#HAIER=0x06,
#RCA=0x07,
#P7051=0x08,
#TOSHIBA=0x09
Header=0xBF #➔遥控器的头码 例如 0xBF
Keymap=IR_CONFIG0_Keymap #➔遥控器的 keymap 所在 section


针对每把遥控器的 keymap (keycode 与 scancode 的键值对应关系)的 section 例如
[IR_CONFIG0_Keymap]的内容:


[IR_CONFIG0_Keymap]
KEY_0 = 0x00
KEY_2 = 0x02
KEY_3 = 0x03
KEY_4 = 0x04

KEY_1/2/3 这些是对应的标准kernel input.h(fusion 4.9 的kernel 是在input-eventcodes.h;后面的16进制值对应的是客户遥控器的物理键值

如果需要新增的功能键 直接在input-event-codes.h中添加对这个 keycode 的map(避免键值
重复)。


关于[Mboot]部分:
[Mboot] 部分结构类似[Kernel],但因为 keymap 较少只保留了两级,一级是[Mboot],序号指
向二级各个遥控器的配置。

[Mboot]
0=MIR_CONFIG0
1=MIR_CONFIG1
[MIR_CONFIG0]

[MIR_CONFIG1]

[MIR_CONFIG0]
Enable=true #同 Kernel
Protocol=0x01 #同 Kernel
Header=0x807F #同 Kernel
RECOVERY_KEY=0x1B #例如(如果支持) recovery key
UPGRADEUSBOTA_KEY=0x07#例如(如果支持) usb ota key 的
FORCEUGRADE_KEY=0x16 #例如(如果支持) force upgrade
UPGRADEBOOTLOADER_KEY=0x15#例如(如果支持) upgrade mb
RECOVERYWIPEDATA_KEY=0x1F #例如(如果支持) recovery
0x1B
RECOVERYWIPECACHE_KEY=0x19 #例如(如果支持) recovery
0x1B
关于 PM51 部分:
[PM51]
0=PIR_CONFIG0
1=PIR_ CONFIG1

[PIR_CONFIG0]

[PIR_CONFIG1]

[PIR_CONFIG0]
Protocol=0x01 #同 Kernel
Header=0x807F #同 Kernel
Key=0x46 #例如唤醒的 key 的 scancode 为 0x46
 

2.3. 支持公版 ir 的 ini 文件


有时候拿到客户的平台,没有给客户的遥控器,可以替换这个 ini 来支持公版的遥控。这个也可以给到客户那边进行参考,怎么配置 ir_config.ini


3. 配置 MT9632 项目遥控
 

 3.1. Ir_config.ini 配置
Ir_config.ini 路径:
vendor\mediatek\proprietary_tv\apollo\linux_core\misdk\mi\mi\platform\m7332\linux
\board_cfg\BD_MT165B_10AT_19055_4K/Ir_config.ini

这里注意这个 Protocols 比如东芝的用东芝的协议
TOSHIBA=0x09
---》 Protocol=0x09
除此之外还需要在 pm 下打开相应的协议
vendor/mediatek/proprietary_tv/apollo/linux_core/misdk/pm/zenonia/Source/MstarApp/MApp_SWIR.c

Mboot 也要: bootable/bootloader/mboot-mtk/mboot/MstarCore/src/api/msAPI_Power.c

Ir_config.ini 格式见: 2.2. Ir_config.ini 的格式分析

注意: Keycode 是在 input-event-codes.h 中定义,如果需要添加新的按键,需要在 input-eventcodes.h 中重新定义,同时赋予的数值不能与已存在的数值重复

3.2. input-event-codes.h 配置


input-event-codes.h 路径:
kernel\fusion\4.9\include\uapi\linux\input-event-codes.h
添加定义 keycode 值:

3.3. input_keys_available.h 配置

 input_keys_available.h 路径:
kernel\fusion\mstar2\drv\ir_mirc\ir_dynamic_config\input_keys_available.h
input_keys_available.h 作用:
Ir_config.ini 文件在 ir_dynamic_config_main.c 进行处理加载,加载时会对 Ir_config.ini 中
的[KIR_ChinaMobile_Keymap]进行查表匹配, input_keys_available.h 充当表的作用:
KEYMAP_PAIR(KEY_RP_SHUTDOWN_READY),
KEYMAP_PAIR(KEY_RP_PICTURE_MODE), //按格式添加进去
KEYMAP_PAIR(KEY_RP_VOLUME_MODE),
KEYMAP_PAIR(KEY_RP_DISPLAY_MODE),
KEYMAP_PAIR(KEY_RP_DISPLAY_INFO),

 KEYMAP_PAIR(KEY_RP_WIFI),
KEYMAP_PAIR(KEY_RP_SOURCE),
KEYMAP_PAIR(KEY_RP_MENU),
KEYMAP_PAIR(KEY_RP_OPS),

3.4. Vendor_3697_Product_0001.kl 配置
 

3.4.1 Kl 文件的介绍(Android 平台)


想要让 Android 系统 inputmanger 知道上抛的 event 事件需要做什么动作,需要将 input
event 键值转换成 Android 键值。这个时候就需要对应一个 input—》 Android 的 kl mapping
文件,那用的是哪个 kl 文件呢?这是根据 input device 注册来决定的。
我们公版会在 kernel mstar_ir_register_device 注册 input device 的时候指定对应的
vendor、 product、 version 如下:
#define INPUTID_VENDOR 0x3697UL;
#define INPUTID_PRODUCT 0x0001;
#define INPUTID_VERSION 0x0001;
如果需要客制化改成客户的 kl 文件,那么需要客户自行修改这里。


3.4.2 使用的 Kl 文件查询


默认输入: dumpsys input 可以看到 IR 是用的下面的 kl 文件:

 

Vendor_3697_Product_0001.kl 路径:
vendor\mediatek\proprietary_tv\open\product\m7332\preinstall\keylayout\Vendor_369
7_Product_0001.kl


3.4.3 KL 格式分析:
 

 

3.5. InputEventLabels.h 配置
 

 InputEventLabels.h (KeycodeLabels.h)路径:
frameworks\native\include\input\InputEventLabels.h
InputEventLabels.h 负责对 DEFINE_KEYCODE(RP_SHUTDOWN_READY)进行宏链接,通
过宏链接#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }转换成
AKEYCODE_RP_SHUTDOWN_READY

DEFINE_KEYCODE(RP_SHUTDOWN_READY),
DEFINE_KEYCODE(RP_ALT_TAB),
DEFINE_KEYCODE(RP_SPACE),
DEFINE_KEYCODE(RP_ALT_F4),
DEFINE_KEYCODE(RP_RIGHT),
DEFINE_KEYCODE(RP_PC),
DEFINE_KEYCODE(RP_HDMI),
DEFINE_KEYCODE(RP_TV),
DEFINE_KEYCODE(RP_MEDIA),
DEFINE_KEYCODE(RP_RESOLUTION),


3.6. keycodes.h 配置
 

 keycodes.h 路径:
frameworks/native/include/android/keycodes.h

3.7. attrs.xml 配置
 

attrs.xml 路径:
frameworks/base/core/res/res/values/attrs.xml

3.8. KeyEvent.java 配置
 

KeyEvent.java 位置:
frameworks/base/core/java/android/view/KeyEvent.java

注意: keycodes.h、 attrs.xml、 KeyEvent.java 这三个文件中对 kecode 赋予的值必须是相同
的。
AKEYCODE_RP_SHUTDOWN_READY = 401,
<enum name="KEYCODE_RP_SHUTDOWN_READY" value ="401" />
public static final int KEYCODE_RP_SHUTDOWN_READY = 401;
最终我们会在通过调用 KeyEvent.java 中的 getKeyCode()截取上报的键值

4 调试方法
 

4.1. 开 debug log


首先要确定是否是新的 ir 框架。
su; echo 7 > /proc/sys/kernel/printk ===> 开 kernel 打印级别
find / -name IRDebug ===> 可以找到,是新的 ir 框架
echo 4 > xxx/IRDebug ===> xxx 是 find 到的路径
这个时候,如果正常情况,按遥控器,会出现打印的 log,解码完全的 log,上报 event
的 log 都会印出来。
如果出现异常情况,可以先对比 log 有什么异常。结合现象,初步定位为题是否在
kernel 阶段。
 

 4.2. 借助 getevent

4.3 常见问题:
 

1. 新增遥控器后,按键无响应
可以 getevent 排查,是 kernel 解码问题,还是上层 keymap 映射问题
==》有 event 消息,需要往上层查,首先可以查一下映射的 keymap 和 kl(kl 是否
走的是 default kl,查看 kl 对应关系,可以 dumpsys input 可以看到) 对应的关
系是否正确,其次再查 UI 或是 framework 没有响应此按键消息。
==》没有 event 消息,参考 5.1 打开 kernel ir log,看是否有错误 log
===》检查一下是否有把客户的遥控器加进 kernel config 或者 ini 里面。
===》是否有正确替换 kernel image
===》是否有正确 load ir_config.ini
===》解码的 log 是否正确
===》 ini 里面的 keymap 是否正确
 

2. 按键响应慢
可以用 getevent – tl 查看 event 响应的时间差。先了解上层响应是 event down 响
应还是 eventup 响应,如果是 up 响应,时间差比较大,可以改小 kernel 抛 up 的
timeout
==》 find / -name IRTimeout
==》 cat xxx/IRTimeout
如果这个值比较大,可以 echo 120 > xxx/IRTimeout 试试。
3. 按一下,光标移动几下
这种情况可以看到 getevent 是否会抛好多 event 消息。如果是,那么我们需要过滤
掉一些 ir event,因为每款遥控的灵敏度不同,有些遥控器按一下,会出现几个波
形。这个时候我们目的是响应一次,所以需要把其他的多的几次波形过滤掉。
==》 ir_config.ini 里面配置 speed=2,过滤 2 次波形
==》 ir_config.h 里面配置 speed =2 ,过滤 2 次波形
4. 长按键不流畅
Getevent – tl 看一下 event 的情况, 正常的长按键是只有按下的时候发出 down
event,松手的时候发出 upevent。如果不流畅,看看是否是一直发 down+up,而且中间
过程有时间间隔。如果是,往 kernel 里面查,如果不是,往上层 Android 去查。
 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑吧撸码兄弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值