3、开发环境搭建:交叉编译工具链安装、SSH远程开发配置、Docker环境准备
好,咱们正式开始动手了。
这一章,说白了就是给你的电脑装上「翻译官」和「传送门」。你想想看,嵌入式设备那么小,跑不动IDE,也跑不动编译器。我们得在强大的PC上写好代码,然后翻译成设备能懂的机器语言,再传过去。这就是交叉编译和远程开发的本质。
我个人习惯把环境搭建分成三步走:工具链、SSH、Docker。每一步都有坑,我踩过不少,今天一并告诉你。
3.1 交叉编译工具链:给代码装上「方言翻译器」
什么是交叉编译?
你的PC是x86架构,嵌入式设备通常是ARM或RISC-V。就像一个人说普通话,一个人说粤语,中间得有个翻译。交叉编译工具链就是这个翻译。
核心概念:在宿主机(x86)上编译出目标机(ARM)能运行的可执行文件。
3.1.1 获取工具链
我建议直接从芯片厂商官网下载。比如你用瑞芯微RK3588,就去瑞芯微的官方SDK里找。用全志的芯片,就去全志的「资料下载」页面。
为什么?因为官方提供的工具链,针对他们的芯片做过优化。我在项目中遇到过用Linaro通用工具链编译出来的程序,跑在RK芯片上莫名其妙段错误,换成官方的就好了。嗯,这里要注意。
常见的工具链命名规则:
arm-linux-gnueabihf-—— ARM架构,硬浮点aarch64-linux-gnu-—— 64位ARM架构riscv64-linux-gnu-—— RISC-V架构
3.1.2 安装步骤
以ARM64为例,我一般这样做:
# 1. 下载工具链(假设下载到~/Downloads)
cd ~/Downloads
wget https://developer.arm.com/.../gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 2. 解压到指定目录
sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
# 3. 配置环境变量(写入~/.bashrc)
echo 'export PATH=$PATH:/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin' >> ~/.bashrc
source ~/.bashrc
# 4. 验证安装
aarch64-none-linux-gnu-gcc --version
小技巧:我个人习惯在/opt下建一个toolchains文件夹,把所有工具链都放进去。这样方便管理,也方便在Docker里挂载。
3.1.3 避坑指南
我曾经犯过一个低级错误:工具链的glibc版本和板子上的系统版本不匹配。编译出来的程序一运行就报FATAL: kernel too old。后来我学乖了,先查板子的glibc版本:
# 在板子上执行
ldd --version
然后选择对应或更低版本的工具链。记住,工具链的glibc版本要 <= 板子的glibc版本。
3.2 SSH远程开发配置:让PC和板子「心有灵犀」
工具链装好了,接下来得让PC能跟板子通信。SSH是最常用的方式。
为什么不用串口?串口太慢了,传个模型文件得等到天荒地老。SSH基于网络,速度快,还能传文件、跑命令,一举多得。
3.2.1 板子端配置
拿到一块新板子,我第一件事就是开SSH:
# 检查SSH服务是否运行
ps -ef | grep sshd
# 如果没有,安装并启动
sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable ssh
sudo systemctl start ssh
# 查看IP地址
ip addr show
记下IP地址,比如192.168.1.100。
3.2.2 PC端配置
PC端就简单了,一条命令连上去:
ssh root@192.168.1.100
但每次都输密码太烦了。我建议配置SSH密钥登录:
# 在PC上生成密钥(如果还没有)
ssh-keygen -t rsa -b 4096
# 把公钥传到板子上
ssh-copy-id root@192.168.1.100
# 现在可以直接登录,不用密码了
ssh root@192.168.1.100
个人经验:我习惯在~/.ssh/config里配置别名,这样连板子只需要输入ssh rk3588:
Host rk3588
HostName 192.168.1.100
User root
Port 22
IdentityFile ~/.ssh/id_rsa
3.2.3 文件传输
传文件用scp或rsync。我个人偏爱rsync,因为它支持断点续传,传大模型文件时特别有用:
# 从PC传到板子
rsync -avz ./yolov8n.pt rk3588:/root/models/
# 从板子传到PC
rsync -avz rk3588:/root/logs/ ./logs/
3.3 Docker环境准备:让开发环境「一次构建,到处运行」
你想想看,团队里每个人用的Ubuntu版本不一样,装的库版本也不一样。今天你编译通过了,明天同事拉下来就报错。这种痛苦,我经历过太多次了。
Docker就是来解决这个问题的。把整个开发环境打包成一个镜像,谁用都一样。
3.3.1 安装Docker
PC上安装Docker很简单:
# 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
3.3.2 构建Yolo开发镜像
我通常会准备一个Dockerfile,把交叉编译工具链、Yolo依赖库都装好:
FROM ubuntu:20.04
LABEL maintainer="your-email@example.com"
LABEL description="Yolo模型交叉编译环境"
# 避免交互式安装
ENV DEBIAN_FRONTEND=noninteractive
# 安装基础工具
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
wget \
vim \
ssh \
rsync \
python3 \
python3-pip \
libopencv-dev \
&& rm -rf /var/lib/apt/lists/*
# 安装Python依赖
RUN pip3 install --no-cache-dir \
numpy \
opencv-python \
onnx \
onnxruntime
# 复制交叉编译工具链
COPY gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu /opt/toolchains/
# 设置环境变量
ENV PATH="/opt/toolchains/bin:${PATH}"
ENV CROSS_COMPILE=aarch64-none-linux-gnu-
WORKDIR /workspace
CMD ["/bin/bash"]
构建镜像:
docker build -t yolo-cross-env:1.0 .
3.3.3 使用Docker进行开发
启动容器,挂载代码目录:
docker run -it --rm \
-v $(pwd):/workspace \
-v /dev:/dev \
--privileged \
yolo-cross-env:1.0
注意:--privileged参数给了容器访问宿主机设备的权限。如果你需要烧录固件或访问USB设备,这个参数是必须的。但要注意安全,生产环境慎用。
3.3.4 避坑指南
我曾经在Docker里编译Yolo模型,编译了整整两个小时,结果发现容器空间不够了。Docker默认的存储驱动是overlay2,镜像层叠起来占空间很快。
我的建议:
- 定期清理无用的镜像和容器:
docker system prune -a - 把大的数据集和模型文件放在宿主机,通过
-v挂载进去,不要复制到镜像里 - 使用
--shm-size=8g参数增加共享内存,OpenCV多线程处理时不会报错
3.4 环境验证:跑一个Hello World
环境搭好了,得验证一下。我习惯写一个简单的C程序,交叉编译后传到板子上跑:
// hello.c
#include <stdio.h>
int main() {
printf("Hello from Yolo on ARM!\n");
printf("交叉编译环境搭建成功!\n");
return 0;
}
编译和运行:
# 在PC上交叉编译
aarch64-none-linux-gnu-gcc hello.c -o hello
# 查看文件信息,确认是ARM架构
file hello
# 输出: hello: ELF 64-bit LSB executable, ARM aarch64, ...
# 传到板子
scp hello root@192.168.1.100:/root/
# 在板子上运行
ssh root@192.168.1.100 ./hello
看到Hello from Yolo on ARM!,说明你的环境搭建成功了。
总结一下:
- 工具链是翻译官,把x86代码翻译成ARM代码
- SSH是传送门,让PC和板子无障碍通信
- Docker是保险箱,保证开发环境的一致性
这三样东西配齐了,后面的Yolo模型移植工作才能顺利开展。别急,慢慢来,环境搭好了,后面就快了。