官方Android11 Box系统的OrangePi 3B新增红外模块教程
教程已更新,更新日期:2026-01-23
前言
打算把手上的OrangePi 3B刷成电视盒子给家里用,但是OrangePi 3B没有板载红外模块,于是从官方店铺下单了外置红外模块和遥控器,结果到手发现官方并没有进行适配,没办法只能自己适配了
Tips:本篇教程有点长,并且不适合小白使用
准备环节
Tips:不要买OrangePi官方店铺的那个红外传感器,那是红外光电二极管 (IR Photodiode),不是集成红外接收头 (Integrated IR Receiver)!!!
下载工具
进入OrangePi官网 http://www.orangepi.cn/
进入OrangePi 3B的下载页面 http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-3B.html
Tips:OrangePi官方发布的各种资料目前基本上都在百度网盘上,建议提前准备一个SVIP账户
找到“官方工具”,打开链接,需要下载的有:
Android和Linux镜像烧录工具-RKDevTool和驱动程序
下载该文件夹内所有内容。
下载 Android Image Kitchen 用于打包和解包镜像:https://xdaforums.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/
下载文档
下载最新的用户手册
下载镜像
下载最新带有“Android11-box”字样的镜像
下载并解压Android源码
下载总共25G+的Android源码分卷压缩包
校验文件md5:
1
md5sum -c RK356X_Android11.tar.gz.md5sum
解压压缩包
1
cat RK356X_Android11.tar.gz0* | sudo tar -xvzf - -C /目标/目录
准备编译环境
准备一个空余硬盘空间至少有200G+的硬盘
准备Linux编译环境,建议Ubuntu22.04,当然也可以是更新的系统,只是编译脚本会用到python2之类的,到时候也能改脚本
按照用户手册中“Android11 源码的编译方法”这节,配置好编译依赖
1
2
3
4
5
sudo apt-get update
sudo apt-get install -y git gnupg flex bison gperf build-essential \
zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 \
lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache \
libgl1-mesa-dev libxml2-utils xsltproc unzip liblz4-tool
如果系统较新,可能有些软件包已失效,我使用Debian13编译,替换了部分软件包:
liblz4-tool -> lz4
libncurses5 -> libncurses6 (或 libncurses-dev)
python -> python3 + python-is-python3
1
2
3
4
5
6
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y git gnupg flex bison gperf build-essential \
zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
libncurses-dev lib32ncurses-dev x11proto-dev libx11-dev lib32z1-dev ccache \
libgl1-mesa-dev libxml2-utils xsltproc unzip lz4 python3 python-is-python3 libssl-dev
开始
OrangePi官方并没有对红外模块进行适配,因此需要自行编译,不过仅用编译内核,不用编译Android本体,单次编译时间压缩至2~3分钟。
安装系统
这里我们采用修补boot的方式,所以首先需要安装完整系统。
按照用户手册中“烧录 Android 镜像到 TF 卡中的方法”这节方法,安装对应驱动,使用RKDevTool将官方原版镜像烧录OrangePi 3B中。
烧录完成后启动OrangePi 3B,插入显示器,确保系统已经能正常启动。
开启开发者模式
像普通手机那样,在设置里找到版本号多次快速点击开启开发者模式,进入开发者模式菜单,为了方便起见,这里使用网络ADB而不是USB ADB
解包官方镜像
使用RKDevTool中“高级功能”内的“解包”功能,将boot.img从官方镜像中分离,重命名为boot-official.img备用
准备红外模块
红外模块一般是三个引脚,分别是VCC,GND和Signal
官方店铺的红外模块是红外光电二极管 (IR Photodiode),不是集成红外接收头 (Integrated IR Receiver),请勿购买!!!请自行在淘宝上购买TSOP38238等集成红外接收头元件。
我使用的OrangePi官方的红外模块描述写的是VCC接3.3V,但是实测下来3.3V貌似有问题无法正常工作,需要接到5V
Signal则是按照描述接在PIN37,也就是引脚图上的GPIOO3_D3脚(后面的教程均按该引脚来写)
GND引脚随便找个GND PIN就行
修改前准备
处理环境变量
1
2
3
export BOARD=orangepi3b
source build/envsetup.sh
lunch rk356x_box-userdebug
修改内核设备树 (DTS)
如果你使用的OrangePi官方的遥控器,可以尝试直接使用我给出的键值,避免重新编译,具体内容在制作Keymap一节
在kernel/arch/arm64/boot/dts/rockchip/中找到rk3566-orangepi-3b.dts打开
在/ {...}内部新增下面配置:
1
2
3
4
5
6
7
8
9
ir: ir-receiver {
compatible = "gpio-ir-receiver";
gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&ir_int>;
pinctrl-1 = <&ir_int>;
wakeup-source;
status = "okay";
};
在&pinctrl{...}中新增下面配置:
1
2
3
4
5
ir {
ir_int: ir-int {
rockchip,pins = <3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
修改菜单配置
加载默认配置
1
cd kernel
1
make ARCH=arm64 rockchip_defconfig
进入菜单配置页面
1
make ARCH=arm64 menuconfig
进入Device Drivers
进入Remote Controller support(这一项本身需要打星 *)
进入Remote controller decoders
建议全部勾选(或者至少勾选 Enable IR raw decoder, NEC protocol, RC-6 protocol)或者你知道你的遥控器是什么协议,官方的遥控器经测试是NEC
进入Remote Controller devices
找到GPIO IR remote control打星 *
按右方向键选择<Save>,回车保存为.config(默认名即可)
按<Exit>一路退出。
编译
因为官方build.sh会使用默认编译config覆盖,因此我们这里覆盖默认的config
首先备份默认配置
1
mv arch/arm64/configs/rockchip_defconfig arch/arm64/configs/rockchip_defconfig.bak
覆盖配置
1
cp .config arch/arm64/configs/rockchip_defconfig
开始编译
1
2
cd ..
./build.sh -K
编译完成后,找到如下文件:
Image 位于kernel/arch/arm64/boot/
resource.img 位于kernel/
关闭AVB校验
首先在源码里找到avbtool
1
find . -name "avbtool"
通常是external/avb/avbtool
然后生成禁用AVB校验的img
1
2
chmod +x external/avb/avbtool
python3 external/avb/avbtool make_vbmeta_image --flag 2 --padding_size 4096 --output vbmeta_disabled.img
不过这个源码里带的avbtool是用python2写的,如果你的编译环境是python2没什么问题,如果是python3则会出现一些错误,可以将报错信息询问AI修改脚本解决
最后会在当前目录下生成一个几KB大小的vbmeta_disabled.img文件
制作boot镜像
回到Windows,将boot-official.img拖到Android Image Kitchen的unpackimg.bat文件上进行解包
解包完成后当前目录会多出ramdisk和split_img两个文件夹
进入split_img文件夹,按照下面对应表进行重命名后替换
Image -> boot-official.img-kernel
resource.img -> boot-official.img-second
然后用记事本打开boot-official.img-board文件,填入orangepi3b保存
最后双击repackimg.bat进行打包,得到image-new.img新boot镜像
制作Misc镜像(可选)
如果进入Android Recovery模式次数过多,可能会导致直接进入Android Recovery模式,可以通过擦除Misc分区解决
生成空白misc_wipe.img:
1
fsutil file createnew misc_wipe.img 49152
刷入boot.img镜像
启动RKDevTool,和之前一样,跟着用户手册让OrangePi 3B进入MaskRom模式
将MiniLoaderAll烧录至SPINOR,然后切换存储至SD卡
进入“下载镜像”标签页,勾选“Boot”分区,并点击一下最右边方框,选择之前制作的image-new.img,然后右键空白处,选择添加项,在名字一栏写Vbmeta并勾选,同样的选择vbmeta_disabled.img
如果制作了misc_wipe.img想要擦除Misc分区,同样的右键新建项,名字一栏写Misc并勾选,选择misc_wipe.img即可
接着点击“设备分区表”按钮,读取设备分区地址信息,这里会有几个分区没有匹配到地址,例如Resource,Kernel,System分区,这是正常现象,只要Boot分区和Vbmeta分区(Misc分区可选)的地址能正常读出即可
最后点击“执行”按钮刷入镜像
调试
如果系统顺利启动,就已经成功一半了
确保开启了开发者模式并打开了网络ADB
如果电脑没有安装ADB,源码里的RKTool文件夹里也有ADB工具
和OrangePi 3B处于同一局域网下,连接ADB设备
不用进行配对,直接连接就行
1
adb connect <OrangePi 3B的IP地址>
连接上后进入shell
1
adb shell
切换至root
1
su
首先检查内核配置
1
zcat /proc/config.gz | grep -i "CONFIG_IR_GPIO_CIR"
正确情况下会输出CONFIG_IR_GPIO_CIR=y,代表内核已经启用
然后查看设备节点是否有红外设备
1
ls -d /sys/firmware/devicetree/base/ir*
正确情况下会输出ir-receiver之类的设备文件夹
进入该文件夹,读取compatible和status
1
2
3
4
cat compatible
# 输出应该是 gpio-ir-receiver
cat status
# 输出应该是 okay
如果满足上方两个条件,查看ir事件
1
getevent -l
一般会有类似下面的输出,包含gpio_ir_recv输入
1
2
3
4
5
6
7
8
9
10
11
12
13
rk356x_box:/ $ getevent -l
add device 1: /dev/input/event1
name: "gpio_ir_recv"
add device 2: /dev/input/event2
name: "rk-headset"
add device 3: /dev/input/event0
name: "rk805 pwrkey"
执行cat /sys/kernel/debug/gpio | grep "gpio-123"也会有下面输出,表示正在使用的GPIO是哪个驱动
1
gpio-123 ( |ir-receiver ) in hi
如果你已经事先配置好了Keymap一节,那就可以不用手动启用协议了
然后开始选择ir协议
1
cd /sys/class/rc/rc0/protocols
会看到当前支持的所有协议,选择要监听的协议
1
echo "+nec" > /sys/class/rc/rc0/protocols
当然也可以开启一堆协议
1
echo "+rc-5 +rc-6 +jvc +sony +sanyo +sharp +mce_kbd +xmp +imon" > /sys/class/rc/rc0/protocols
开启的协议会用[]包围。
执行getevent -l用遥控器对着红外设备按下键,正常情况下会有类似下面的输出:
1
2
3
4
/dev/input/event1: EV_MSC MSC_SCAN 0000045c
/dev/input/event1: EV_SYN SYN_REPORT 00000000
/dev/input/event1: EV_MSC MSC_SCAN 0000045c
/dev/input/event1: EV_SYN SYN_REPORT 00000000
如果满足上面所有情况,则代表硬件已经设置正确并且系统能正常读取解析来自遥控器的信号
Tips:这里建议明确出遥控器使用的是哪种协议,因为后面会使用到
制作Keymap
最后,需要制作Keymap用于将遥控器信号解析出来的十六进制的键值码映射到对应的按键上
同样是执行getevent -l,然后将遥控器上所有的按键按一遍,并记录对应的键值码,只用记录后三位,例如45c
经测试,OrangePi官方的遥控器键值码如下:
按键键值码
电源键41a
TV44d
VOD443
音量-419
音量+445
menu45d
mouse41b
上444
左41c
OK45c
右448
下41d
home41f
return40a
1413
2410
3411
440f
540c
640d
740b
8408
9409
TV-SYS458
0447
SETUP453
拿到对应的键值码后,开始编写keymap文件
回到Linux编译环境,在kernel/drivers/media/rc/keymaps/下新建一个文件叫rc-orangepi-ir.c
写入下方内容:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 文件路径: kernel/drivers/media/rc/keymaps/rc-orangepi-ir.c
#include <media/rc-map.h>
#include <linux/module.h>
static struct rc_map_table orangepi_ir_table[] = {
{ 0x41a, KEY_POWER }, // 电源键
{ 0x445, KEY_VOLUMEUP }, // 音量+
{ 0x44d, KEY_TV }, // TV
{ 0x443, KEY_VIDEO }, // VOD (映射为 VIDEO)
{ 0x419, KEY_VOLUMEDOWN }, // 音量-
{ 0x45d, KEY_MENU }, // menu
{ 0x41b, KEY_SWITCHVIDEOMODE }, // mouse (通常映射为切换鼠标模式,或 KEY_FN)
{ 0x444, KEY_UP }, // 上
{ 0x41c, KEY_LEFT }, // 左
{ 0x45c, KEY_ENTER }, // OK (Android 确定键通常用 ENTER)
{ 0x448, KEY_RIGHT }, // 右
{ 0x41d, KEY_DOWN }, // 下
{ 0x41f, KEY_HOME }, // home
{ 0x40a, KEY_BACK }, // return
{ 0x413, KEY_1 }, // 1
{ 0x410, KEY_2 }, // 2
{ 0x411, KEY_3 }, // 3
{ 0x40f, KEY_4 }, // 4
{ 0x40c, KEY_5 }, // 5
{ 0x40d, KEY_6 }, // 6
{ 0x40b, KEY_7 }, // 7
{ 0x408, KEY_8 }, // 8
{ 0x409, KEY_9 }, // 9
{ 0x447, KEY_0 }, // 0
{ 0x458, KEY_TV2 }, // TV-SYS (映射为 TV2 或其他功能键)
{ 0x453, KEY_SETUP }, // SETUP
};
static struct rc_map_list orangepi_ir_map = {
.map = {
.scan = orangepi_ir_table,
.size = ARRAY_SIZE(orangepi_ir_table),
.rc_proto = RC_PROTO_NEC, // 这里指定协议为 NEC
.name = "rc-orangepi-ir", // 名字必须和 DTS 里的 linux,rc-map-name 一致
}
};
static int __init init_rc_map_orangepi(void)
{
return rc_map_register(&orangepi_ir_map);
}
static void __exit exit_rc_map_orangepi(void)
{
rc_map_unregister(&orangepi_ir_map);
}
module_init(init_rc_map_orangepi)
module_exit(exit_rc_map_orangepi)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("OrangePiUser");
接着在kernel/drivers/media/rc/keymaps/Makefile中按照格式接上rc-orangepi-ir.o
然后修改设备树 (DTS)
回到kernel/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dts,在ir-receiver{...}内添加一条:
1
linux,rc-map-name = "rc-orangepi-ir";
保险起见,完全重新生成boot
1
2
cd kernel
make distclean
最后从修改前准备这节重新编译内核和制作boot.img
测试
重新刷入boot.img等镜像后,开机测试红外功能,这会应该能正常使用遥控器遥控了
同样的使用getevent -l查看ir事件
这会可以看到有下面之类的事件出现:
1
2
/dev/input/event1: EV_KEY KEY_DOWN DOWN
/dev/input/event1: EV_KEY KEY_DOWN UP
禁止深睡
因为官方固件深睡模式好像有问题,深睡下无法用红外唤醒,并且唤醒后系统会出现,因此需要禁止系统深睡。
首先准备一个叫wake_lock.rc的脚本文件,内容为:
1
2
on property:sys.boot_completed=1
write /sys/power/wake_lock stay_awake
打开终端连接adb,准备推送文件
1
2
3
4
5
adb root
adb remount
adb push wake_lock.rc /vendor/etc/init/
adb shell chmod 644 /vendor/etc/init/wake_lock.rc
adb reboot
后记
OrangePi官方的红外模块貌似有点不好用,遥控器稍微远一点信号质量就急剧下降,S脚点位拉不下来,识别不到,这会手上没电阻电容,不方便处理,只能等之后再玩了。
更新:继续和Gemini聊了一会,才知道tmd那玩意是红外光电二极管 (IR Photodiode),不是用来接收遥控器信号的“接收头”🤣,虽然也是被我用来当信号接收器了,我说怎么tm那么难用,遥控器离30cm以上就收不到信号了。。。应该是买集成红外接收头 (Integrated IR Receiver)。。。不过教程没问题,有问题的是那个逆天硬件🤣