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 文件传输

传文件用scprsync。我个人偏爱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模型移植工作才能顺利开展。别急,慢慢来,环境搭好了,后面就快了。