第二章:嵌入式平台搭建——选对硬件,少走半年弯路
做嵌入式视觉,第一步不是写代码,而是选平台。我见过太多团队,算法在PC上跑得飞起,一上板子就卡成PPT。说白了,平台选错了,后面所有优化都是白费力气。
这一章,我就把主流平台的血泪对比、交叉编译的坑、系统烧录的细节,一次性讲清楚。
2.1 主流平台对比:Jetson / RK3588 / 树莓派
先看一张我整理的对比表,这三大平台我都在项目里用过,各有各的脾气。
| 维度 | NVIDIA Jetson (Orin NX) | Rockchip RK3588 | 树莓派 5 |
|---|---|---|---|
| AI算力 | 100 TOPS (INT8) | 6 TOPS (NPU) | ≈0.5 TOPS (CPU) |
| 典型功耗 | 15W - 40W | 8W - 15W | 5W - 10W |
| 价格 | ¥4000 - ¥8000 | ¥800 - ¥1500 | ¥400 - ¥600 |
| 开发难度 | 中等(CUDA生态好) | 较高(文档分散) | 低(社区资源多) |
| 视觉接口 | CSI / USB / GMSL | MIPI-CSI / HDMI-IN / USB | CSI / USB |
| 适用场景 | 自动驾驶、机器人、高精度检测 | 边缘盒子、智能安防、工业视觉 | 原型验证、教学、轻量应用 |
我的建议:如果预算充足且需要跑大模型,直接上Jetson Orin系列。如果做量产产品,RK3588性价比极高——我在一个工业质检项目里就用它替代了Jetson,成本降了60%,帧率只掉了15%。树莓派嘛,适合做原型验证,别指望它跑实时推理。
2.2 交叉编译环境搭建
嵌入式开发绕不开交叉编译。你想想看,在x86的PC上编译ARM架构的代码,这中间有多少坑?
我个人习惯用Docker来管理交叉编译环境,干净、可复现。下面是我常用的一个配置流程。
2.2.1 安装交叉编译工具链
以RK3588为例,Rockchip官方提供了完整的SDK。
# 下载 RK3588 Linux SDK
git clone https://github.com/rockchip-linux/rk3588-linux.git
cd rk3588-linux
# 安装交叉编译工具链
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
# 验证安装
aarch64-linux-gnu-gcc --version
# 输出: aarch64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
避坑指南:我曾经在Ubuntu 20.04上装了默认的gcc-aarch64,结果编译出来的程序在RK3588上段错误。后来发现是glibc版本不匹配。建议用SDK里自带的工具链,或者用Linaro的官方版本。
2.2.2 使用CMake进行交叉编译
写一个工具链文件,让CMake知道目标平台的信息。
# toolchain_rk3588.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
然后编译你的视觉应用:
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain_rk3588.cmake
make -j4
嗯,这里要注意:如果你的代码依赖OpenCV,记得先交叉编译OpenCV for ARM。我一般用脚本一键搞定,后面章节会详细讲。
2.3 系统镜像烧录与配置
烧录系统听起来简单,但不同平台的操作差异很大。我踩过的坑,都列在下面了。
2.3.1 Jetson 刷机
Jetson用NVIDIA官方的SDK Manager,图形化界面,基本一路Next。但有个关键点:
- 选择JetPack版本:我建议用LTS版本,比如JetPack 5.1.1,稳定。
- 烧录模式:把Jetson进入Force Recovery模式(按住RECOVERY键,再按RESET,然后上电)。
- 网络:刷机时PC和Jetson要用USB线直连,别用WiFi,容易断。
警告:刷机过程中不要拔USB线!我有个同事刷到一半手贱拔了,结果Jetson变砖,最后用SD卡恢复模式才救回来。刷机时去喝杯咖啡,别碰它。
2.3.2 RK3588 烧录
Rockchip的烧录工具叫RKDevTool,在Windows上跑。步骤稍微繁琐:
- 按住RK3588板子上的MASKROM键,上电进入烧录模式。
- 打开RKDevTool,选择Loader文件和系统镜像(通常是update.img)。
- 点击"执行",等待进度条走完。
我个人习惯用Linux下的upgrade_tool命令行工具,适合批量烧录。
# 安装 upgrade_tool
sudo apt-get install libusb-1.0-0-dev
git clone https://github.com/rockchip-linux/rkdeveloptool.git
cd rkdeveloptool && make
# 烧录系统
sudo ./rkdeveloptool db rk3588_loader.bin
sudo ./rkdeveloptool wl 0x0 rk3588_image.img
sudo ./rkdeveloptool rd
2.3.3 树莓派烧录
树莓派最简单,用Raspberry Pi Imager,选系统、选SD卡、点写入。但我建议:
- 用Raspberry Pi OS Lite(无桌面版),省资源。
- 烧录前在Imager里预配置SSH和WiFi,省得插键盘显示器。
2.4 外设驱动安装
系统跑起来了,但摄像头不工作?驱动没装对。嵌入式视觉的外设驱动,主要分三类。
2.4.1 摄像头驱动
以最常见的USB摄像头和MIPI-CSI摄像头为例。
| 摄像头类型 | 驱动方式 | 验证命令 |
|---|---|---|
| USB摄像头 (UVC) | 内核自带,即插即用 | ls /dev/video* 或 v4l2-ctl --list-devices |
| MIPI-CSI (IMX219) | 需要设备树覆盖 (dtoverlay) | dmesg | grep imx219 |
| GMSL摄像头 | 需要加载MAX9296/9295驱动 | i2cdetect -y 0 检查I2C地址 |
在树莓派上启用MIPI摄像头,需要编辑/boot/config.txt:
# 启用摄像头
start_x=1
gpu_mem=128
# 指定摄像头型号
dtoverlay=imx219
然后重启,用raspistill -o test.jpg测试。如果报错,八成是排线松了——我遇到过三次,都是这个原因。
2.4.2 显示与编码驱动
做摄像头工程,经常需要把视频流显示出来或者编码成H.264。这时候硬件编解码驱动就很重要。
- Jetson:NVIDIA的V4L2驱动和GStreamer插件都预装了,直接用
nvarguscamerasrc。 - RK3588:Rockchip的MPP(Media Process Platform)需要单独编译。我建议用
rkmpp库,支持硬件编解码。 - 树莓派:用
libcamera驱动,取代了旧的raspicam。
小技巧:在RK3588上测试硬件编码,可以用这个命令:gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,width=1920,height=1080 ! mpph264enc ! filesink location=test.h264。如果报错,检查/dev/dri下有没有renderD128节点。
2.4.3 GPIO与I2C外设
有时候需要控制补光灯、云台或者读取传感器。GPIO和I2C驱动是基本功。
# 在树莓派上控制GPIO
# 安装 wiringPi
sudo apt-get install wiringpi
# 点亮LED (GPIO 17)
gpio mode 17 out
gpio write 17 1
# 读取I2C设备 (地址0x48)
i2cget -y 1 0x48
在Jetson上,GPIO操作通过/sys/class/gpio文件系统,或者用Jetson.GPIO Python库。我个人更喜欢用Python写测试脚本,调试快。
2.5 平台搭建知识体系总览
下面这张图,把整个嵌入式平台搭建的流程串起来了。你可以把它当作检查清单。
这张图从左到右、从上到下,就是搭建一个嵌入式视觉平台的完整路径。你每完成一步,就打个勾。我当年带团队时,就用这个清单来检查新人的进度,效率很高。
核心要点:平台选型决定上限,交叉编译决定下限,烧录和驱动决定能不能跑起来。这三步走扎实了,后面的算法部署才有意义。别急着调模型,先把板子玩透。