第二章:部署环境搭建——交叉编译工具链安装、目标板系统烧录、SSH与串口连接配置、文件传输与远程调试环境搭建

各位同学,欢迎来到第二章。上一章我们聊了边缘AI芯片的整体选型思路,今天咱们要动真格的了——把开发环境真正搭起来。

说实话,我见过太多工程师,算法模型写得漂漂亮亮,一到部署环节就卡在环境搭建上。工具链装不上、系统烧录失败、串口没反应……这些坑我几乎都踩过。今天我就把这几年的实战经验掰开揉碎,带你一步步搞定。

本章核心目标:在宿主机(你的PC/服务器)上搭建完整的交叉编译环境,让目标板(边缘AI设备)能跑起来,并且能通过SSH和串口与你愉快地通信。

2.1 交叉编译工具链安装——为什么不能直接在目标板上编译?

你可能会问:为什么不在目标板上直接编译?原因很简单——目标板的算力太弱了。你想想看,一个Cortex-A53的CPU,编译一个Linux内核可能要几个小时,而你的PC几分钟就搞定了。

交叉编译,说白了就是在你的PC上生成目标板能运行的二进制文件。这里的关键是工具链的选择。

2.1.1 工具链的三种获取方式

方式 适用场景 我的建议
芯片厂商官方SDK自带 大部分商业芯片(瑞芯微、全志、海思等) 首选,兼容性最好
Linaro预编译工具链 ARM架构通用开发 适合开源板卡(树莓派、Jetson Nano等)
Buildroot/Yocto自行构建 深度定制系统 高手向,新手慎入

我个人习惯用官方SDK自带的工具链。为什么?因为芯片厂商对自己的硬件最了解,他们提供的工具链往往做了针对性优化。我曾经在某个项目里用Linaro通用工具链编译了一个神经网络推理库,结果在目标板上跑起来总是段错误,折腾了两天,换成官方工具链后一次通过。

2.1.2 安装步骤(以瑞芯微RK3588为例)

嗯,这里我以瑞芯微的RK3588为例,其他芯片流程大同小异。

# 1. 下载官方SDK(通常包含工具链)
wget https://example.com/rk3588_sdk.tar.gz
tar -xzf rk3588_sdk.tar.gz

# 2. 找到工具链路径
cd rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/
ls -la
# 你会看到类似 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu 的目录

# 3. 设置环境变量(建议写入 ~/.bashrc)
export PATH=$PATH:/path/to/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
export CROSS_COMPILE=aarch64-none-linux-gnu-
export ARCH=arm64

# 4. 验证安装
aarch64-none-linux-gnu-gcc --version
# 输出类似:aarch64-none-linux-gnu-gcc (GCC) 10.3.0

小技巧:我习惯在 ~/.bashrc 里加一个函数,方便切换不同工具链:

function set_toolchain() {
    export PATH=$1/bin:$PATH
    export CROSS_COMPILE=$2
    echo "Toolchain set: $2"
}
# 使用:set_toolchain /opt/gcc-arm-10.3 aarch64-none-linux-gnu-

2.2 目标板系统烧录——SDK/固件的正确打开方式

工具链装好了,接下来得让目标板跑起来。系统烧录这一步,说白了就是把操作系统写到目标板的存储介质里(eMMC、SD卡、NAND Flash等)。

不同的芯片,烧录方式天差地别。我整理了一个表格,你对照着看:

芯片类型 烧录工具 烧录方式 注意事项
瑞芯微(RK系列) RKDevTool USB线刷(Loader模式) 按住RECOVERY键上电
全志(Allwinner) PhoenixCard / PhoenixSuit SD卡烧录 / USB线刷 注意FEL模式进入方式
海思(HiSilicon) HiTool 网口烧录 / 串口烧录 需要配置TFTP服务器
NVIDIA Jetson SDK Manager Host PC通过USB直连 需要NVIDIA账号

2.2.1 以RK3588为例的烧录实战

我记得第一次烧录RK3588时,卡在Loader模式进不去,折腾了半小时才发现是USB线的问题。这里给你避坑指南:

  1. 准备工作:下载官方固件(通常是一个 .img 文件),安装驱动(DriverAssitant)
  2. 进入Loader模式:按住板子上的RECOVERY键不放,再按一下RESET键,然后松开RECOVERY键
  3. 检查连接:在PC上执行 lsusb,应该能看到 2207:350a 类似的设备ID
  4. 开始烧录:打开RKDevTool,选择固件,点击「执行」

警告:烧录过程中千万不要拔掉USB线!我曾经有一次手贱,烧到一半拔了线,结果板子变砖了。后来用短接Flash引脚才救回来。烧录时建议用带屏蔽的USB线,数据线越长越容易出问题。

2.3 SSH与串口连接配置——远程调试的左右手

系统烧好了,板子跑起来了,接下来怎么跟它交流?两个途径:SSH(网络)和串口(物理连接)。

我个人的习惯是:串口用来救急,SSH用来干活。为什么?串口稳定可靠,哪怕网络没配好也能用;SSH效率高,能传文件、能开多个终端。

2.3.1 串口连接——最后的救命稻草

串口连接其实很简单,但很多人第一步就错了——波特率没设对。常见的边缘AI板子,串口波特率一般是115200或1500000。

# 1. 安装串口工具(以minicom为例)
sudo apt-get install minicom

# 2. 查看串口设备
ls /dev/ttyUSB*   # USB转串口
ls /dev/ttyACM*   # 原生串口

# 3. 配置minicom
sudo minicom -s
# 进入配置菜单:
# - 串口设备:/dev/ttyUSB0
# - 波特率:115200
# - 数据位:8
# - 停止位:1
# - 无校验

# 4. 连接(更推荐用screen,更轻量)
sudo screen /dev/ttyUSB0 115200

避坑指南:我曾经遇到过串口只输出乱码的情况。排查步骤:

  • 检查波特率是否匹配(最常见原因)
  • 检查TX/RX是否接反(交叉连接)
  • 检查地线是否连接(GND必须接)
  • 检查电平是否匹配(3.3V vs 1.8V)

2.3.2 SSH配置——远程工作的标配

板子连上网络后,第一件事就是配SSH。这里我建议你配成静态IP,不然每次重启IP变了,你还要去接串口查。

# 在目标板上执行(通过串口或已连接的SSH)

# 1. 配置静态IP(以Ubuntu/Debian为例)
sudo vim /etc/netplan/01-netcfg.yaml

# 内容如下:
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      gateway4: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8, 114.114.114.114]

# 2. 应用配置
sudo netplan apply

# 3. 启动SSH服务
sudo systemctl enable ssh
sudo systemctl start ssh

# 4. 在PC上测试连接
ssh root@192.168.1.100

重要:第一次SSH连接时,如果提示「Host key verification failed」,那是因为板子系统重刷过,密钥变了。执行 ssh-keygen -R 192.168.1.100 清除旧密钥即可。

2.4 文件传输与远程调试环境搭建——让开发效率翻倍

环境搭好了,怎么把编译好的程序传到板子上?怎么在PC上调试板子上的程序?这里我分享几个我常用的方案。

2.4.1 文件传输三板斧

工具 适用场景 命令示例
scp 小文件、偶尔传输 scp test_app root@192.168.1.100:/home/
rsync 大文件、增量同步 rsync -avz --progress ./build/ root@192.168.1.100:/app/
nfs 开发阶段频繁修改 挂载PC目录到板子,实时同步

我个人最推荐 rsync。为什么?因为它只传变化的部分。我有个项目,每次编译完要传200MB的库文件到板子上,用scp要等2分钟,换成rsync后,如果只改了几个源文件,传输时间缩短到5秒以内。

2.4.2 NFS挂载——真正的远程调试体验

如果你像我一样,一天要修改几十次代码然后测试,那NFS挂载是终极方案。说白了,就是把PC上的一个目录直接挂到板子上,板子运行的就是PC上的文件,改完代码重新编译,板子上立刻生效。

# 在PC上(作为NFS服务器)
# 1. 安装NFS服务器
sudo apt-get install nfs-kernel-server

# 2. 配置共享目录
sudo vim /etc/exports
# 添加一行:
/home/user/project/build 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

# 3. 重启NFS服务
sudo systemctl restart nfs-kernel-server

# 在目标板上(作为NFS客户端)
# 1. 安装NFS客户端
apt-get install nfs-common

# 2. 挂载
mount -t nfs 192.168.1.10:/home/user/project/build /mnt/nfs

# 3. 验证
ls /mnt/nfs
# 应该能看到PC上的文件

注意:NFS挂载时,no_root_squash 这个选项很重要。如果不加,板子上的root用户对挂载目录没有写权限。我曾经因为这个选项,调试了整整一个下午才发现问题。

2.4.3 GDB远程调试——断点跟踪的利器

文件能传了,但程序跑起来出错了怎么办?打日志?太慢了。我建议你直接用GDB远程调试。

# 在目标板上启动gdbserver
gdbserver :2345 ./test_app

# 在PC上连接(交叉编译版本的gdb)
aarch64-none-linux-gnu-gdb test_app
(gdb) target remote 192.168.1.100:2345
(gdb) b main
(gdb) c
# 程序会在main函数处停下
(gdb) n  # 单步执行
(gdb) p variable_name  # 打印变量值

小技巧:如果你觉得命令行GDB不好用,可以用VS Code的Remote Development插件。配置好SSH后,直接在VS Code里打开板子上的代码,设置断点,就像在本地调试一样。我现在的项目基本都是这么干的。

2.5 本章知识体系总览

说了这么多,我画了一张图帮你理清思路。这张图展示了从宿主机到目标板的完整工具链和数据流:

部署环境搭建知识体系 宿主机(PC/服务器) 目标板(边缘AI设备) 交叉编译工具链 NFS服务器 / 文件系统 GDB调试器(交叉编译版) SSH客户端 / 串口终端 烧录工具(RKDevTool等) 目标系统(Linux内核+根文件系统) NFS客户端 / 挂载点 gdbserver(调试代理) SSH服务端 / 串口输出 Bootloader + 固件镜像 USB烧录 SSH(网络) 串口(物理) NFS挂载(网络) GDB远程调试 烧录 SSH 串口 NFS GDB

这张图把今天讲的内容串起来了。你看,宿主机这边负责编译、存储、调试控制,目标板那边负责运行、挂载、响应。中间的连接方式根据场景灵活选择——烧录是一次性的,SSH和串口是常开的,NFS和GDB是开发调试时用的。

好了,环境搭建这部分就讲到这里。你按照这个流程走一遍,应该不会出大问题。如果遇到什么奇怪的错误,先别慌,检查一下我提到的那些坑——波特率对不对?USB线好不好?权限够不够?八成就是这些细节问题。


专注资料整理