3、开发环境搭建:交叉编译工具链安装、SSH远程连接配置、文件传输与同步(rsync)、系统镜像烧录与初始化

说实话,做嵌入式开发这么多年,我踩过最多的坑就是环境搭建。你想想看,代码写得再漂亮,编译不过去、烧录不进去、连不上板子,那都是白搭。这一章咱们就把这些基础活儿干利索,后面才能专心搞模型部署。

3.1 交叉编译工具链安装

交叉编译是什么?说白了就是在你的电脑上编译出能在ARM板子上跑的程序。你的电脑是x86架构,板子是ARM架构,编译器得知道怎么生成ARM的机器码。

我个人习惯用Linaro提供的工具链,稳定且社区支持好。以ARM Cortex-A72为例,咱们装aarch64版本。

核心要点:工具链版本必须与板子内核匹配,否则编译出来的程序可能跑不起来。

3.1.1 下载与解压

# 下载aarch64交叉编译工具链
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/

# 重命名方便管理
mv /opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu /opt/gcc-aarch64

3.1.2 配置环境变量

嗯,这里要注意。环境变量配不好,每次编译都得写绝对路径,烦得很。

# 编辑~/.bashrc,在末尾添加
export PATH=$PATH:/opt/gcc-aarch64/bin
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

# 使配置生效
source ~/.bashrc

# 验证安装
aarch64-linux-gnu-gcc --version

小技巧:我习惯把工具链路径写到Makefile里,而不是全局环境变量。这样不同项目可以用不同版本的工具链,互不干扰。

3.1.3 测试编译

写个简单的hello world试试水。

// test.c
#include <stdio.h>

int main() {
    printf("Hello from ARM board!\n");
    return 0;
}

// 编译
aarch64-linux-gnu-gcc test.c -o test_arm

// 查看文件信息
file test_arm
// 输出: ELF 64-bit LSB executable, ARM aarch64, ...

看到"ARM aarch64"就对了。我曾经有一次忘了加静态编译选项,结果板子上缺动态库,程序跑不起来。后来我习惯加个-static,省心。

3.2 SSH远程连接配置

板子一般没有显示器键盘,全靠SSH远程操作。我建议一开始就把SSH配好,后面调试会舒服很多。

3.2.1 板端SSH服务开启

大部分官方系统镜像默认开了SSH。如果没开,手动启动一下:

# 检查SSH服务状态
systemctl status sshd

# 如果没启动
systemctl start sshd
systemctl enable sshd  # 开机自启

3.2.2 网络连接方式

两种常见方式:

方式 优点 缺点
USB网卡共享 不需要路由器,即插即用 速度一般,配置稍复杂
以太网直连 速度快,稳定 需要网线,IP需手动设置

我个人偏爱以太网直连。把板子和电脑用网线连起来,设置同一网段即可。

# 电脑端设置静态IP
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0

# 板子端设置静态IP(通过串口或HDMI先登录)
ifconfig eth0 192.168.1.101 netmask 255.255.255.0

# 测试连通性
ping 192.168.1.101

3.2.3 SSH免密登录

每次输密码太烦了。我建议配个密钥对,一劳永逸。

# 电脑端生成密钥对
ssh-keygen -t rsa -b 4096

# 复制公钥到板子
ssh-copy-id root@192.168.1.101

# 测试登录
ssh root@192.168.1.101

注意:板子的root密码默认一般是空或123456。第一次登录后记得改密码,安全第一。

3.3 文件传输与同步(rsync)

做模型部署时,经常要往板子上传模型文件、代码、库文件。scp能用,但每次传整个文件太慢。rsync才是神器。

3.3.1 scp基础用法

# 上传文件
scp model.tflite root@192.168.1.101:/home/

# 下载文件
scp root@192.168.1.101:/home/log.txt ./

3.3.2 rsync增量同步

rsync只传变化的部分,第一次全量,后面就快了。我在项目中经常用它同步代码和模型文件。

# 基本用法
rsync -avz --progress ./deploy/ root@192.168.1.101:/home/deploy/

# 参数说明
# -a: 归档模式,保留权限和时间戳
# -v: 显示详细信息
# -z: 传输时压缩
# --progress: 显示进度

实战经验:我习惯写个同步脚本,每次改完代码直接运行脚本就同步到板子上了,省得手动敲命令。

#!/bin/bash
# sync_to_board.sh
rsync -avz --delete \
  --exclude='.git' \
  --exclude='__pycache__' \
  --exclude='*.o' \
  ./deploy/ \
  root@192.168.1.101:/home/deploy/

echo "同步完成!"

3.3.3 自动同步监控

如果你像我一样懒,可以用inotify实现自动同步。改完代码保存,板子上自动更新。

# 安装inotify-tools
sudo apt-get install inotify-tools

# 监控目录变化并自动同步
while inotifywait -r -e modify,create,delete ./deploy/; do
    rsync -avz ./deploy/ root@192.168.1.101:/home/deploy/
done

3.4 系统镜像烧录与初始化

拿到一块新板子,第一件事就是烧系统。不同板子烧录方式不同,但思路差不多。

3.4.1 烧录工具准备

板子类型 烧录工具 镜像格式
Raspberry Pi Raspberry Pi Imager / dd .img
Jetson Nano SDK Manager / balenaEtcher .img / .sdimage
RK3588系列 RKDevTool / rkdeveloptool .img / .raw

3.4.2 以树莓派为例烧录

# 查看SD卡设备名
lsblk

# 假设SD卡是/dev/sdb
# 使用dd命令烧录(注意:这会清空SD卡所有数据)
sudo dd if=raspios-arm64.img of=/dev/sdb bs=4M status=progress

# 同步缓存
sync

# 烧录完成后,拔卡插到板子上启动

警告:dd命令一定要确认设备名正确。我曾经手滑把电脑硬盘当成SD卡写了,那叫一个酸爽。建议用balenaEtcher这种带图形界面的工具,安全很多。

3.4.3 系统初始化配置

系统第一次启动后,建议做这几件事:

  1. 扩展文件系统:让系统用满SD卡全部空间
  2. 设置时区:避免日志时间对不上
  3. 配置网络:WiFi或以太网
  4. 更新软件源:apt update && apt upgrade
  5. 安装常用工具:vim, htop, git, cmake等
# 扩展文件系统(树莓派)
sudo raspi-config --expand-rootfs

# 设置时区
sudo timedatectl set-timezone Asia/Shanghai

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装常用工具
sudo apt install -y vim htop git cmake build-essential

3.4.4 验证环境

最后跑个简单的测试,确认环境没问题。

# 查看系统信息
uname -a
cat /proc/cpuinfo | grep "model name"

# 测试交叉编译的程序
# 在电脑上编译,传到板子上运行
aarch64-linux-gnu-gcc -static test.c -o test_arm
scp test_arm root@192.168.1.101:/home/
ssh root@192.168.1.101 "./test_arm"

# 输出: Hello from ARM board!

我的习惯:每次拿到新板子,我都会写一个初始化脚本,把上面这些步骤自动化。下次换板子或者重装系统,跑一遍脚本就完事了。

好了,环境搭建这块就到这儿。工具链能编译了,SSH能连上了,文件能同步了,系统也跑起来了。下一章咱们开始搞真正的模型部署,到时候这些基础工作就派上用场了。