☰
RK3399嵌入式开发实战:从uboot移植到NPU调用全链路指南
2026/10/15 17:53:16 网站建设 项目流程

1. 为什么一块2016年的开发板至今还有人学

第一次接触RK3399是在一个做边缘计算设备的项目里,当时团队要选一颗能跑双屏异显、还要带NPU做轻量推理的主控。翻了一圈市面上的方案,全志H6性能够但接口少,树莓派4还没出,最后锁定在RK3399上。这颗芯片是瑞芯微2016年发布的,六核big.LITTLE架构,双核Cortex-A72加四核Cortex-A53,GPU是Mali-T860MP4,放到今天看参数不算亮眼,但它的接口丰富程度和资料沉淀,让它在工控、商显、教育硬件这些领域一直有生命力。

很多人学RK3399是被"逼"的——公司项目要用,或者买了一块板子想跑通某个外设。但学着学着就发现,这颗芯片能讲的东西太多了:从uboot移植、kernel裁剪、设备树配置,到GPU驱动、VPU硬解、NPU调用,再到Android和Linux双系统的适配,几乎涵盖了嵌入式Linux的完整链路。它不像那些"一键烧录就能跑"的玩具板,你想改点东西就得真正理解启动流程和驱动模型。

这篇内容适合三类人:一是刚拿到RK3399开发板、不知道从哪下手的新手;二是做过其他ARM平台、想迁移到RK3399的工程师;三是需要评估RK3399是否适合自己项目的技术选型者。我会从整体思路讲到具体实操,把踩过的坑和验证过的方案都摊开说,尽量让你少走弯路。

2. 学习RK3399之前必须想清楚的几件事

2.1 你到底要学哪个层面

RK3399的学习路径分叉很早,你得先明确目标。如果只是想在板子上跑个应用,那学会烧录固件、配置网络、交叉编译就够了,一两天能上手。但如果要做板级支持包开发,比如换一块屏幕、加一个传感器、改一个电源管理策略,那就得深入uboot和kernel。再往上,如果要做系统级定制,比如裁剪Android、适配新的文件系统、优化启动速度,那涉及的面就更广了。

我见过不少人一上来就啃TRM(技术参考手册),两千多页的PDF看到第三章就放弃了。正确的做法是带着问题去查手册,而不是通读。比如你要配置一个I2C设备,那就去查I2C控制器的寄存器章节和时钟树部分,其他章节暂时不用管。

2.2 硬件选型的几个关键点

市面上的RK3399板子五花八门,选板子的时候有几个参数必须看:

参数项推荐配置原因
内存4GB LPDDR42GB跑Android会紧张,4GB是甜点
存储eMMC 16GB以上比SD卡稳定,读写速度快一个量级
调试口板载USB转串口省去额外买调试线的麻烦
电源支持DC和Type-C供电调试时Type-C方便,量产用DC
扩展接口40pin排针+PCIe方便接外设和做扩展实验

有些板子为了压缩成本省掉了调试串口,这个对新手很不友好。串口是你看启动日志的唯一窗口,没有它你连uboot跑到哪一步都不知道。

2.3 开发环境的搭建逻辑

RK3399的开发环境分两部分:主机端和目标板端。主机端建议用Ubuntu 18.04或20.04,太新的版本有些老工具链会出兼容问题。需要装的工具包括:

sudo apt-get install repo git-core gitk git-gui gcc-arm-linux-gnueabihf \ u-boot-tools device-tree-compiler gcc-aarch64-linux-gnu mtools parted \ libudev-dev libssl-dev python3 python3-pip

这里有个细节:RK3399是64位芯片,但uboot阶段可能用到32位工具链,所以两个架构的交叉编译器都要装。另外repo工具是拉取SDK用的,瑞芯微的SDK用repo管理多个git仓库,手动clone会漏掉依赖。

目标板端就是你的开发板本身,需要准备一张至少8GB的TF卡做启动盘,以及一根USB Type-A转Type-C的数据线用于烧录。有些板子支持Maskrom模式,按住恢复键上电就能进入烧录状态,这个后面实操部分会细说。

3. 从零跑通第一个系统的完整流程

3.1 获取SDK与目录结构解读

瑞芯微官方SDK通过repo管理,拉取命令大致是这样:

mkdir rk3399-sdk && cd rk3399-sdk repo init -u https://github.com/rockchip-linux/manifests -b master repo sync -j8

同步完成后你会看到一堆目录,新手容易懵。核心目录就几个:

  • u-boot/:引导程序源码,负责初始化DDR、加载kernel
  • kernel/:Linux内核源码,驱动都在这里
  • buildroot/或debian/:根文件系统构建脚本
  • device/rockchip/:板级配置,包括分区表、打包脚本
  • rkbin/:预编译的二进制,比如DDR初始化固件、BL31

rkbin这个目录特别重要,里面是闭源的DDR训练固件和ARM Trusted Firmware。很多人编译报错就是因为rkbin没同步全,或者版本和uboot不匹配。

3.2 编译uboot的关键配置

进入u-boot目录后,先选配置:

make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- rk3399_defconfig

然后根据你的板子修改configs/rk3399_defconfig,常见的改动点包括:

  • CONFIG_DEFAULT_DEVICE_TREE:指定设备树文件名
  • CONFIG_SYS_MMC_ENV_DEV:环境变量存在哪个设备
  • CONFIG_BOOTDELAY:启动延时,调试时设长一点方便进命令行

编译命令:

make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

生成的u-boot.bin和u-boot.itb在根目录下。注意RK3399用的是FIT格式的uboot镜像,u-boot.itb才是最终烧录的文件,u-boot.bin只是中间产物。

注意:如果你改了DDR频率或者时序,必须同步更新rkbin里的DDR初始化固件,否则uboot阶段就会挂死,串口没有任何输出。

3.3 内核编译与设备树修改

内核编译相对标准化:

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rockchip_defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3399-evb.dtb make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

设备树文件在arch/arm64/boot/dts/rockchip/下面,你的板子对应哪个dtb要看具体型号。改设备树是RK3399开发中最频繁的操作,比如要加一个I2C传感器,就在对应的i2c节点下添加子节点:

&i2c4 { status = "okay"; clock-frequency = <100000>; mysensor: mysensor@48 { compatible = "myvendor,mysensor"; reg = <0x48>; interrupt-parent = <&gpio1>; interrupts = <RK_PC5 IRQ_TYPE_LEVEL_LOW>; }; };

这里clock-frequency设100kHz是保守值,长走线或者多设备挂载时建议先用100k调通再往上提。中断引脚要查原理图确认GPIO编号,RK_PC5这种宏定义在include/dt-bindings/pinctrl/rockchip.h里。

3.4 打包与烧录的实操细节

瑞芯微的打包脚本在device/rockchip/rk3399/下面,执行:

./build.sh kernel ./build.sh

最终生成rockdev/目录下的update.img,这是一个包含uboot、kernel、rootfs的完整固件包。烧录工具有Windows版的RKDevTool和Linux版的upgrade_tool,我习惯用Linux版:

sudo upgrade_tool uf update.img

烧录前板子要进入Maskrom模式:断开电源,按住恢复键,插入Type-C线,等两秒松开。upgrade_tool ld能列出设备就说明识别成功了。

实操心得:第一次烧录建议用TF卡启动而不是直接写eMMC。TF卡刷坏了重新写就行,eMMC刷坏了可能得拆机短接。等TF卡启动验证没问题了,再用dd命令把镜像写到eMMC。

4. 外设调试与性能优化的实战经验

4.1 GPIO与中断调试的常见陷阱

RK3399的GPIO分5组,每组32个引脚,命名规则是GPIO0到GPIO4。在sysfs里操作GPIO:

echo 138 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio138/direction echo 1 > /sys/class/gpio/gpio138/value

138这个编号怎么来的?计算公式是组号*32 + 组内偏移。比如GPIO4_C6,组号是4,C6对应偏移是2*8+6=22,所以编号是4*32+22=150。这个计算经常有人搞错,尤其是B组和C组的偏移。

中断调试更容易出问题。设备树里配了中断但驱动收不到,先检查三个地方:一是引脚复用有没有配成中断功能,二是触发方式(上升沿/下降沿/电平)和硬件是否匹配,三是中断控制器有没有使能。用cat /proc/interrupts能看到中断计数,如果数字不涨说明硬件层面就没触发。

4.2 双屏异显的配置方法

RK3399支持HDMI和DP同时输出,也可以HDMI加MIPI DSI。配置双屏要在设备树里把两个显示通道都使能:

&hdmi { status = "okay"; }; &dp { status = "okay"; }; &vopb { status = "okay"; }; &vopl { status = "okay"; };

VOPB和VOPL是两个视频输出处理器,大分辨率屏建议接VOPB。然后在uboot的cmdline里加video=HDMI-A-1:1920x1080@60 video=DP-1:1280x800@60。如果两个屏分辨率不同,要确认带宽是否够,4K加2K同时输出可能会丢帧。

4.3 NPU调用的入门路径

RK3399本身不带NPU,但很多板子外挂了RK1808或者通过PCIe接了算力卡。如果只是用CPU跑推理,建议用NCNN或者TFLite,量化到int8后MobileNet跑一帧大概几十毫秒。要用硬件加速的话,瑞芯微提供了RKNN工具链,流程是:

  1. 在PC上用RKNN-Toolkit把模型转成.rknn格式
  2. 把.rknn文件和推理程序放到板子上
  3. 调用rknn_init、rknn_run、rknn_outputs_get完成推理

转换时要注意输入尺寸和归一化参数必须和训练时一致,否则精度会掉得厉害。我遇到过一次转换后精度从75%掉到30%,查了半天发现是均值方差填反了。

5. 问题排查速查与避坑清单

5.1 启动失败的分层排查法

RK3399启动失败时,串口日志是唯一线索。按阶段排查:

现象可能原因排查方法
串口无输出DDR初始化失败检查rkbin版本,换DDR固件
卡在BL31ATF配置错误确认BL31二进制和芯片版本匹配
uboot能进但kernel起不来设备树或cmdline错误对比官方evb的dts
kernel起来但挂载rootfs失败分区表或文件系统类型不对检查parameter.txt和mkfs参数
系统起来但外设不工作驱动未编译或设备树未使能看dmesg和/sys下的设备节点

5.2 编译报错的典型场景

repo sync卡住不动,多半是网络问题,可以加--force-sync重试。编译uboot报dtc版本过低,升级device-tree-compiler就行。内核编译报undefined reference,通常是defconfig里漏了某个驱动选项,用make menuconfig搜一下补上。

还有一个坑是Python版本。老版SDK的打包脚本是Python2写的,Ubuntu 20.04默认Python3,需要手动装Python2或者改脚本。我建议直接改脚本,Python2已经停止维护了。

5.3 性能调优的几个抓手

CPU调频用cpufreq子系统,查看当前策略:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

默认是interactive,跑计算密集型任务可以改成performance锁最高频。GPU调频在/sys/class/devfreq/下面,Mali-T860的可用频率档位有200MHz到800MHz。

散热是个容易被忽视的问题。RK3399满载功耗能到5W以上,不加散热片跑十分钟就会降频。实测加一个20x20mm的铝散热片,持续编译时CPU频率能稳定在1.8GHz不降。

避坑提醒:改CPU频率前先确认供电能力。有些板子的PMIC余量不足,锁最高频会导致系统不稳定甚至重启。用cat /sys/kernel/debug/regulator/regulator_summary能看到各路电源的负载情况。

6. 后续可以深入的方向

跑通系统只是起点,RK3399能玩的东西还很多。想往底层走可以研究uboot的启动流程,从BootROM到TPL到SPL再到uboot proper,每一级做了什么、怎么传递参数,搞清楚了整个ARM启动链路就通了。想往应用走可以研究GStreamer硬编解码,RK3399的VPU支持H.264/H.265的4K编解码,用mpp库能直接调用硬件单元,比软编快一个数量级。

我个人在实际操作中的体会是,RK3399的学习曲线前陡后平。刚开始配环境、烧固件、调串口会觉得处处是坑,但一旦系统跑起来,后面加外设、改驱动、做优化都是在这个框架里填内容。关键是别怕看日志,串口输出的每一行都有意义,看懂了日志就看懂了系统在干什么。另外建议养成记录的习惯,每次改了什么配置、报了什么错、怎么解决的,记下来。RK3399的坑很多是重复的,下次遇到翻记录比重新查快得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询