2、开发环境搭建:交叉编译工具链安装、目标板连接与调试、必备工具(ADB、SSH、串口)
好,咱们正式开始动手了。
这一章,说白了就是“把家伙事儿备齐”。你想想看,做嵌入式AI推理,代码是在PC上写,但跑是在开发板上跑。这中间差着十万八千里呢。怎么让PC上的代码变成板子能跑的东西?怎么跟板子说话?怎么把模型塞进去?这些就是本章要解决的问题。
我个人习惯,先把环境搭得干干净净再写代码。否则后面出个bug,你都不知道是代码问题还是工具链问题,那才叫一个头两个大。
2.1 交叉编译工具链:让PC为ARM打工
咱们的PC通常是x86架构,而目标板(比如树莓派、RK3588、Jetson Orin)大多是ARM架构。x86的二进制文件,ARM不认识。反过来也一样。
所以我们需要一个“翻译官”——交叉编译工具链。它运行在PC上,但生成的目标代码是ARM的。
2.1.1 工具链的选择
市面上工具链很多,我列几个常用的:
| 目标架构 | 推荐工具链 | 备注 |
|---|---|---|
| ARMv7 (32位) | arm-linux-gnueabihf- | 老派板子,比如树莓派3B |
| ARMv8 (64位) | aarch64-linux-gnu- | 主流,RK3588、树莓派4/5 |
| ARM Cortex-M | arm-none-eabi- | 裸机或RTOS,不带Linux |
我个人建议,新手直接选 aarch64-linux-gnu-。为什么?因为现在64位ARM是主流,你买个新板子基本都是这个架构。我在项目中遇到过,有人图省事装了32位工具链,结果板子是64位的,编译出来的程序一运行就报错,折腾了半天。
2.1.2 安装步骤(以Ubuntu为例)
其实很简单,一条命令的事:
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
装完之后,验证一下:
aarch64-linux-gnu-gcc --version
看到版本号,就说明装好了。
arm64v8/ubuntu 系列。我习惯在Docker里搞一套干净的环境,避免污染宿主机。
2.1.3 第一个交叉编译程序
写个最简单的hello world:
// hello.c
#include <stdio.h>
int main() {
printf("Hello from ARM!\n");
return 0;
}
编译:
aarch64-linux-gnu-gcc -o hello hello.c
用 file 命令看看:
file hello
# 输出: ELF 64-bit LSB executable, ARM aarch64, ...
嗯,看到“ARM aarch64”就对了。这个文件在PC上跑不了,得扔到板子上跑。
2.2 目标板连接与调试:怎么跟板子“说话”
工具链装好了,代码也编译了。怎么把程序弄到板子上?怎么调试?
这里我介绍三种方式:SSH、ADB、串口。它们各有各的用处。
2.2.1 SSH:最常用的远程登录
SSH是嵌入式开发中最常用的方式。只要板子和PC在同一个局域网,就能用。
首先,确保板子开了SSH服务。一般Linux板子默认都开了,没开的话:
sudo systemctl start sshd
sudo systemctl enable sshd
然后,在PC上连接:
ssh username@板子IP地址
比如:
ssh root@192.168.1.100
输入密码,就连上了。之后你就可以像操作本地终端一样操作板子。
~/.ssh/authorized_keys 里。这样每次连接就不用输密码了,省事。
2.2.2 ADB:Android板子的好帮手
如果你的板子跑的是Android系统(比如一些带屏幕的开发板),那ADB是首选。
安装ADB:
sudo apt-get install adb
连接板子(通过USB线):
adb devices
看到设备列表,就说明连上了。然后可以:
adb shell— 进入板子的shelladb push 本地文件 板子路径— 把文件推到板子上adb pull 板子路径 本地文件— 从板子拉文件
我曾经在一个Android电视盒子上做AI推理,就是用ADB把模型和程序推上去的。比SSH还方便,因为不需要配网络。
2.2.3 串口:最后的救命稻草
串口是嵌入式开发中最原始、也最可靠的方式。当板子网络不通、系统起不来的时候,串口是你唯一的希望。
你需要一根USB转串口线(比如CH340、CP2102)。接线方式:
- 板子的TX接串口线的RX
- 板子的RX接串口线的TX
- GND接GND
然后在PC上安装串口工具:
sudo apt-get install minicom
或者用 screen:
sudo screen /dev/ttyUSB0 115200
这里的 /dev/ttyUSB0 是串口设备名,115200 是波特率。具体数值看你的板子手册。
2.3 必备工具:ADB、SSH、串口的使用场景
这三个工具各有千秋,我总结一下:
| 工具 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| SSH | Linux板子,网络正常 | 方便,支持文件传输 | 依赖网络 |
| ADB | Android板子,USB连接 | 不需要网络,功能强大 | 只支持Android |
| 串口 | 所有板子,底层调试 | 最可靠,不依赖任何上层 | 速度慢,只能传文本 |
我个人习惯,平时用SSH。如果板子没网,就用ADB。如果板子连系统都起不来,那就只能上串口了。
2.4 实战:把交叉编译的程序传到板子上
好,咱们来走一遍完整流程。
假设你已经在PC上交叉编译好了 hello 这个程序。现在要把它传到板子上并运行。
方法一:通过SSH
scp hello username@板子IP:/home/username/
ssh username@板子IP
./hello
方法二:通过ADB
adb push hello /data/local/tmp/
adb shell
cd /data/local/tmp
./hello
方法三:通过串口
串口传文件比较麻烦,一般用 rz 或 sz 命令。但说实话,我很少用串口传文件,太慢了。串口主要用来调试系统启动。
2.5 避坑指南
最后,分享几个我踩过的坑:
- 工具链版本不匹配: 板子的glibc版本和工具链的glibc版本不一致,会导致程序运行时报错。解决办法:用板子自带的工具链,或者用静态编译。
- 权限问题: 传到板子上的程序没有执行权限。记得
chmod +x。 - 路径问题: 板子的文件系统和PC不一样。别把PC的绝对路径硬编码到程序里。
嗯,环境搭建就到这里。下一章,咱们开始真正接触AI推理框架。准备好了吗?