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 整体流程

先看一张流程图,帮你理解网络启动的完整链路:

RK3568 网络启动流程 PC 开发机 Ubuntu 20.04 TFTP 服务 传输内核 + DTB NFS 服务 共享根文件系统 提供文件 共享目录 RK3568 目标板 U-Boot 引导 tftp 获取 kernel nfs 挂载 rootfs 说明: 1. 板子上电后 U-Boot 通过 TFTP 获取内核镜像 (Image) 和设备树 (DTB) 2. 内核启动后通过 NFS 挂载根文件系统,所有修改即时生效

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 验证环境

环境配好之后,验证一下是否正常工作:

  1. 板子上电,串口输出 U-Boot 启动信息
  2. U-Boot 通过 TFTP 获取 Image 和 rk3568-evb.dtb
  3. 内核启动,挂载 NFS 根文件系统
  4. 进入系统后,执行 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 挂载成功了。嗯,到这里开发环境就搭好了,可以开始写驱动了。