1. RK3568 芯片概览与开发环境搭建
做嵌入式驱动开发,第一步不是写代码,而是搞清楚你手里的芯片到底能干什么。RK3568 这颗芯片我用了快三年,从最早的项目评估到现在量产落地,踩过不少坑,也积累了一些经验。今天咱们就从芯片特性开始,一步步把开发环境搭起来。
1.1 RK3568 芯片特性
RK3568 是瑞芯微推出的一款中高端 SoC,定位很明确——既要性能,又要性价比。我最早接触它是在一个工业平板项目上,当时对比了好几款芯片,最后选了它,原因很简单:接口够全,功耗可控,生态成熟。
| 参数项 | RK3568 | 常见竞品 |
|---|---|---|
| CPU | 4×Cortex-A55 @ 2.0GHz | 4×Cortex-A53 @ 1.8GHz |
| GPU | Mali-G52 EE | Mali-400 MP2 |
| NPU | 1 TOPS (可选) | 无 |
| 显示 | HDMI 2.0 / eDP / LVDS / MIPI-DSI | 单路 HDMI 1.4 |
| 网络 | 双千兆 GMAC + WiFi6 (外挂) | 单千兆 |
| 存储 | eMMC 5.1 / SD 3.0 / SATA 3.0 | eMMC 4.5 |
| 封装 | BGA 636, 21×21mm | BGA 628, 23×23mm |
你看这个表格,RK3568 的 CPU 是四核 A55,主频能到 2.0GHz。说实话,这个性能跑 Linux 桌面或者轻量级 AI 推理完全够用。GPU 是 Mali-G52,支持 OpenGL ES 3.2 和 Vulkan 1.1,做 UI 渲染没问题。
核心亮点:RK3568 内置了 1 TOPS 的 NPU,虽然算力不算高,但做简单的图像分类、人脸检测足够了。我在一个门禁项目里就用它跑轻量级模型,效果还不错。
1.2 应用场景
这颗芯片的应用场景其实挺广的。我简单列几个常见的:
- 工业控制:PLC、HMI、数据采集终端。RK3568 的工业级温度范围是 -40°C ~ 85°C,这点很关键。
- 商业显示:数字标牌、自助终端、收银机。双屏异显是它的强项。
- 边缘计算:智能网关、AI 盒子。NPU 在这里能派上用场。
- 教育/开发板:很多第三方开发板都基于它,比如 Firefly、友善之臂。
我个人觉得,RK3568 最适合的场景是「需要一定算力但预算有限」的项目。你想想看,如果只是做个简单的串口屏,用更低端的芯片就行;但如果要跑 Linux 桌面、做视频解码、接多个外设,RK3568 的性价比就出来了。
1.3 搭建交叉编译环境
驱动开发离不开交叉编译。说白了,就是在 PC 上编译出能在 ARM 板子上运行的代码。我刚开始做的时候,光配环境就折腾了两天,后来总结了一套流程,现在基本 10 分钟搞定。
1.3.1 下载工具链
瑞芯微官方提供了基于 GCC 的交叉编译工具链。我个人习惯用 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu 这个版本,稳定且兼容性好。
# 下载工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 解压到 /opt 目录
sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
# 添加环境变量
export PATH=$PATH:/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
小技巧:建议把环境变量写到 ~/.bashrc 里,这样每次打开终端就不用重新 export 了。我习惯在文件末尾加一行 export PATH=$PATH:/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin,然后 source ~/.bashrc。
1.3.2 验证工具链
配好之后,验证一下是否能用:
aarch64-none-linux-gnu-gcc --version
# 输出示例:
# aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07) 10.3.1 20210621
# Copyright (C) 2020 Free Software Foundation, Inc.
看到版本号就说明工具链装好了。嗯,这里要注意:如果你用的是 Ubuntu 20.04 或更新版本,可能需要安装一些 32 位库,否则会报 No such file or directory 的错误。我曾经在这个坑里卡了半小时。
sudo apt install libc6-i386 lib32stdc++6 lib32gcc-s1
1.4 配置 TFTP/NFS 网络启动
驱动开发过程中,最烦的就是反复烧写固件。每次改一行代码,就要重新编译、烧录、重启,太浪费时间了。所以我强烈建议用 TFTP + NFS 网络启动。这样代码在 PC 上编译好,板子通过网络加载内核和设备树,根文件系统也挂在 NFS 上,改完直接运行,效率翻倍。
1.4.1 整体流程
先看一张流程图,帮你理解网络启动的完整链路:
1.4.2 配置 TFTP 服务
TFTP 负责传输内核镜像和设备树。配置很简单:
# 安装 tftp-hpa
sudo apt install tftp-hpa tftpd-hpa
# 创建 TFTP 根目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件 /etc/default/tftpd-hpa
sudo vim /etc/default/tftpd-hpa
配置文件内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
然后重启服务:
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
注意:防火墙可能会拦截 TFTP 的 69 端口。如果你在虚拟机里跑,记得关掉防火墙或者放行端口。我曾经在客户现场调试时,发现板子一直拿不到内核,最后发现是防火墙没关,尴尬得很。
1.4.3 配置 NFS 服务
NFS 用来共享根文件系统。这样你在 PC 上修改驱动或应用,板子上立刻就能看到效果。
# 安装 NFS 服务
sudo apt install nfs-kernel-server
# 创建 NFS 共享目录(假设你的 rootfs 在 /opt/rootfs)
sudo mkdir -p /opt/rootfs
sudo chmod 777 /opt/rootfs
# 修改 /etc/exports
sudo vim /etc/exports
添加一行:
/opt/rootfs *(rw,sync,no_subtree_check,no_root_squash)
然后重启 NFS 服务:
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
1.4.4 U-Boot 启动参数
最后一步,在 U-Boot 里设置启动参数。进入 U-Boot 命令行,执行:
setenv ipaddr 192.168.1.100 # 板子 IP
setenv serverip 192.168.1.10 # PC IP
setenv gatewayip 192.168.1.1 # 网关
setenv netmask 255.255.255.0
setenv bootargs 'console=ttyS2,1500000 root=/dev/nfs nfsroot=192.168.1.10:/opt/rootfs rw ip=192.168.1.100:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off'
setenv bootcmd 'tftp 0x00a80000 Image; tftp 0x00f00000 rk3568-evb.dtb; booti 0x00a80000 - 0x00f00000'
saveenv
boot
这里有几个关键点:
serverip是 PC 的 IP,板子会从这里拿文件nfsroot参数指定了 NFS 共享路径booti命令用于启动 ARM64 的内核镜像
避坑指南:我曾经在设置 IP 时把板子和 PC 的 IP 写反了,结果板子一直 ping 不通。还有一次忘记设置网关,导致跨网段访问失败。建议先用 ping 确认网络通顺,再配置启动参数。
1.5 验证环境
环境配好之后,验证一下是否正常工作:
- 板子上电,串口输出 U-Boot 启动信息
- U-Boot 通过 TFTP 获取
Image和rk3568-evb.dtb - 内核启动,挂载 NFS 根文件系统
- 进入系统后,执行
ls /确认看到的是 PC 上共享的 rootfs
如果一切顺利,你会看到类似这样的输出:
## Flattened Device Tree blob at 00f00000
Booting using the fdt blob at 0x00f00000
Loading Device Tree to 00000000fdf00000, end 00000000fdf10fff ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050]
[ 0.000000] Linux version 5.10.160 (user@pc) (aarch64-none-linux-gnu-gcc (GCC) 10.3.1 20210621) #1 SMP Thu Jan 1 00:00:00 UTC 2024
...
[ 2.345678] VFS: Mounted root (nfs filesystem) on device 0:14.
[ 2.456789] Freeing unused kernel memory: 1024K
[ 2.567890] Run /sbin/init as init process
看到 Mounted root (nfs filesystem) 就说明 NFS 挂载成功了。嗯,到这里开发环境就搭好了,可以开始写驱动了。