1. RK平台概述:芯片家族、SDK架构与开发环境

各位同学,欢迎来到这门实战课。我是你们的老朋友,一个在嵌入式底层摸爬滚打了十几年的驱动工程师。今天咱们先不急着敲代码,把RK平台的家底摸清楚,后面调试起来才能心里有数。

1.1 RK芯片家族:从入门到旗舰

瑞芯微的芯片,说白了就是一颗颗高度集成的SoC(片上系统)。它们的内核都是ARM架构,但针对不同场景做了差异化设计。我个人习惯把RK芯片分成三大梯队:

梯队 代表型号 核心特点 典型应用
入门级 RK3128, RK3229 Cortex-A7四核,28nm工艺,成本敏感 入门平板、OTT盒子、智能显示
主流级 RK3288, RK3399 A17/A72+A53大小核,4K解码,接口丰富 广告机、POS机、NAS、中控
旗舰级 RK3588, RK3576 A76+A55大小核,8K视频,NPU 6TOPS+ 边缘计算、AI盒子、高端平板
我的经验: 选型时别只看主频。RK3399的A72大核虽然频率高,但RK3588的A76单核性能更强,而且多了NPU。做AI推理项目,我建议直接上RK3588系列,省得后面再外挂算力棒。

嗯,这里要特别提一下RK3588。它内部集成了4个Cortex-A76和4个Cortex-A55,还有独立的NPU、GPU、VPU。我在做边缘网关项目时,一个RK3588就能搞定视频采集、AI推理、网络转发三件事,这在以前至少需要三颗芯片。

1.2 RK SDK架构解析:别被目录吓到

第一次打开RK SDK的同学,可能会被那一堆文件夹搞晕。其实它的架构很清晰,我画了一张图帮你理解:

RK SDK 核心架构分层图 Application Layer (应用层) 用户程序、QT/Android应用、AI推理框架 Framework Layer (框架层) Rockchip RGA/MPP/DRM/RKNN API Kernel Layer (内核层) Linux内核 5.10/6.1,设备树,驱动模块 Boot Layer (启动层) U-Boot、Trusted Firmware-A、DDR初始化 Hardware Layer (硬件层) 驱动开发者主要工作区域

这张图你看懂了吗?我们驱动开发者的主战场在内核层和框架层。SDK里最重要的几个目录,我列出来:

  • kernel/:Linux内核源码,驱动模块都在这里。RK对内核做了大量定制,比如DMA-BUF、ION内存管理。
  • u-boot/:启动引导程序,负责初始化DDR、加载内核。我曾经在这里调过一整天DDR时序,就为了把频率从1600MHz提到1866MHz。
  • external/:第三方库和RK私有库,比如rga(图像处理)、mpp(视频编解码)、rknn(NPU推理)。
  • device/rockchip/:板级配置和设备树文件。每个开发板对应一个.dts文件,这是驱动移植的关键。
避坑指南: 我曾经在RK3399上移植一个I2C触摸屏驱动,死活调不通。最后发现是设备树里i2c频率写错了,RK的i2c控制器对时序要求很严格。所以,拿到SDK第一件事,先看对应板子的设备树文件,确认外设时钟和引脚复用配置。

1.3 开发环境搭建:工欲善其事

环境搭建其实不复杂,但有几个细节不注意,后面会浪费大量时间。我推荐用Ubuntu 20.04或22.04 LTS,64位系统。

1.3.1 安装必要工具链

RK平台主要用ARM GCC交叉编译器。官方SDK里通常自带预编译好的工具链,路径在 prebuilts/gcc/linux-x86/aarch64/ 下。你也可以手动安装:

# 安装基础依赖
sudo apt-get update
sudo apt-get install -y git make gcc g++ libncurses5-dev \
    flex bison libssl-dev bc python3 python3-pip

# 安装交叉编译器(以aarch64为例)
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

# 验证安装
aarch64-linux-gnu-gcc --version
我的习惯: 我不直接用系统自带的交叉编译器。RK SDK里自带的工具链是经过验证的,版本匹配最好。我一般把SDK里的工具链路径加到 ~/.bashrc 里,这样每次打开终端就能直接用。

1.3.2 编译SDK示例

以RK3588为例,完整编译一次SDK大概需要30分钟到1小时(取决于机器性能)。第一次编译建议用官方脚本:

# 进入SDK根目录
cd ~/rk3588_sdk

# 选择配置文件(对应你的板子)
./build.sh lunch
# 选择 rk3588-evb1-lp4-v10

# 全量编译
./build.sh -A

# 编译完成后,镜像在 rockdev/ 目录下

你想想看,如果每次改个驱动都要全量编译,那效率太低了。所以我建议只编译内核模块:

# 单独编译内核
./build.sh kernel

# 编译设备树
./build.sh dtb

# 编译某个驱动模块(以rk808为例)
make -C kernel/ M=drivers/mfd/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

1.3.3 烧录与调试工具

RK平台烧录工具主要有两种:

工具 适用场景 特点
RKDevTool Windows下烧录 图形化界面,支持分区烧录,适合量产
upgrade_tool Linux下烧录 命令行工具,适合自动化脚本
rkdeveloptool Linux下烧录(开源) 社区维护,功能与upgrade_tool类似

调试方面,我强烈建议你准备一根USB转串口线(TTL电平)。RK芯片默认的调试串口是UART2,波特率通常是1500000(1.5Mbps)。用minicom或putty连接:

# 安装minicom
sudo apt-get install minicom

# 配置串口(以ttyUSB0为例)
sudo minicom -D /dev/ttyUSB0 -b 1500000
核心要点: 驱动开发调试,串口日志是命根子。内核启动时加上 earlyprintk 和 console=ttyS2,1500000 参数,可以尽早看到内核日志。我遇到过很多次,驱动加载失败但没有任何提示,最后发现是串口参数没配对。

1.4 工具链配置:让编译飞起来

配置工具链其实就三步,但每一步都有坑。我直接给你一个经过验证的配置流程:

  1. 确认架构:RK3588是aarch64,RK3288是armv7。用 uname -m 查看目标板架构。
  2. 设置环境变量:在 ~/.bashrc 里添加:
    export ARCH=arm64
    export CROSS_COMPILE=aarch64-linux-gnu-
    export PATH=$PATH:/path/to/rk_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
  3. 验证编译:写一个简单的hello驱动,编译成.ko文件,看能不能加载到目标板上。
我曾经踩过的坑: 有次我用了Ubuntu 22.04自带的gcc-11交叉编译器,编译出来的内核模块在RK3588上加载时报 Unknown symbol 错误。查了两天才发现,是工具链版本和内核头文件不匹配。从那以后,我再也不敢乱换工具链版本了,老老实实用SDK自带的。