3. 边缘终端开发环境搭建

在 TI Sitara 平台上做机器视觉边缘终端,开发环境不是“装个 IDE 就能写代码”那么简单。宿主机(通常是 x86_64 的 Ubuntu)负责编辑、交叉编译和构建根文件系统,目标板(如 AM62x、AM57x 等 Sitara 器件)负责运行视觉推理与图像采集程序。两者指令集不同、库版本不同、启动介质不同,因此环境搭建的核心是:让宿主机能产出目标板可执行的二进制与可启动的系统镜像,并建立稳定的调试与部署通道。

一、SDK 安装:先固定版本,再谈效率

TI 为 Sitara 提供 Processor SDK(Linux/RTOS),其中 Linux SDK 包含交叉编译器、目标板根文件系统、内核源码、U-Boot 源码以及预构建镜像。安装时建议把 SDK 放在独立目录,例如 /opt/ti/,避免与系统自带工具链混用。以 AM62x 为例,典型安装流程如下:

# 下载 SDK 安装包(示例文件名,实际以 TI 官网为准)
chmod +x ti-processor-sdk-linux-am62xx-evm-09.01.00.08-Linux-x86-Install.bin
./ti-processor-sdk-linux-am62xx-evm-09.01.00.08-Linux-x86-Install.bin

# 安装后目录结构
/opt/ti/processor-sdk-linux-am62xx-evm-09.01.00.08/
├── linux-devkit/          # 交叉编译工具链与 sysroot
├── board-support/         # 内核、U-Boot、设备树源码
├── filesystem/            # 预构建根文件系统
└── bin/                   # 环境配置脚本

安装完成后,每次打开终端先执行 source linux-devkit/environment-setup,该脚本会设置 CC、CXX、ARCH、CROSS_COMPILE 和 SDKTARGETSYSROOT。可以用 echo $CC 验证是否指向 aarch64-oe-linux-gcc。这一步看似简单,却是后续所有编译问题的分水岭:如果环境变量没生效,编译出来的可能是宿主机二进制,拷到板子上会报 Exec format error。

二、交叉编译工具链:从“能编”到“编得对”

交叉编译的关键不是记住 gcc 前缀,而是理解 sysroot。SDK 中的 linux-devkit/sysroots/aarch64-oe-linux/ 提供了目标板的头文件和库。编译一个使用 OpenCV 的视觉程序时,如果直接写 gcc main.cpp -o main,链接器会去宿主机 /usr/lib 找 x86 的 libopencv,必然失败。正确做法是让编译命令继承 SDK 环境,或显式指定 --sysroot:

# 方式一:source 环境后直接编译
source /opt/ti/processor-sdk-linux-am62xx-evm-09.01.00.08/linux-devkit/environment-setup
$CC main.cpp -o vision_app -I$SDKTARGETSYSROOT/usr/include/opencv4 \
    -L$SDKTARGETSYSROOT/usr/lib -lopencv_core -lopencv_imgproc

# 方式二:在 Makefile 中显式指定
CROSS_COMPILE = aarch64-oe-linux-
CC = $(CROSS_COMPILE)gcc
CFLAGS += --sysroot=$(SDKTARGETSYSROOT)
LDFLAGS += --sysroot=$(SDKTARGETSYSROOT) -Wl,-rpath-link,$(SDKTARGETSYSROOT)/usr/lib

编译完成后用 file vision_app 检查,输出应包含 ARM aarch64 字样。再用 aarch64-oe-linux-readelf -d vision_app 查看动态库依赖,确认没有指向宿主机路径。若依赖库在目标板上不存在,需要把对应 .so 一并部署,或改用静态链接。

三、Yocto/OpenEmbedded 构建:定制属于你的根文件系统

预构建根文件系统能跑通基础功能,但机器视觉项目往往需要额外的 GStreamer 插件、OpenCV 模块、Python 包或自定义守护进程。这时就要用 Yocto 构建自己的镜像。TI SDK 已经提供了 oe-layersetup 和 bitbake 环境,典型流程是:

# 初始化构建目录
./oe-layersetup.sh
source conf/setenv
bitbake-layers add-layer ../meta-custom

# 在 local.conf 中追加软件包
IMAGE_INSTALL:append = " opencv python3-opencv gstreamer1.0-plugins-good v4l-utils"

# 构建最小镜像
bitbake tisdk-base-image

构建产物位于 tmp/deploy/images/<machine>/,包括 .wic 镜像、内核 Image、设备树 .dtb 和根文件系统压缩包。Yocto 的价值在于可复现:把 local.conf、bblayers.conf 和自定义 layer 纳入 Git 管理后,任何一台机器都能构建出相同镜像。但代价是首次构建耗时较长,建议分配至少 8 核 CPU、16 GB 内存和 200 GB 磁盘空间。

宿主机 (x86_64 Ubuntu) Processor SDK 安装 /opt/ti/processor-sdk-linux-am62xx-evm/ source linux-devkit/environment-setup 交叉编译工具链 aarch64-oe-linux-gcc --sysroot=$SDKTARGETSYSROOT 输出: ARM aarch64 可执行文件 Yocto / OpenEmbedded 构建 bitbake tisdk-base-image IMAGE_INSTALL:append = "opencv ..." 产出: .wic / Image / .dtb / rootfs 版本管理 (Git) local.conf / bblayers.conf / meta-custom 应用源码 + 构建配置统一纳管 目标板 (Sitara AM62x) 启动介质 SD 卡 / eMMC / QSPI-NOR U-Boot → Kernel → RootFS 串口调试 USB-UART: /dev/ttyUSB0 115200 8N1 minicom / picocom / screen 网络调试 SSH: ssh root@192.168.1.100 SCP / rsync 文件传输 NFS 挂载根文件系统 远程部署 scp vision_app root@target:/opt/app/ systemd 服务 / 启动脚本 可执行文件 系统镜像 部署脚本 宿主机负责构建与版本控制,目标板负责运行与调试,两者通过串口/网络/存储介质协同

四、串口与网络调试:建立第一条可靠通道

板子第一次上电时,网络尚未配置,串口是唯一的“生命线”。Sitara EVM 通常通过 USB-UART 桥接芯片引出调试串口,宿主机识别为 /dev/ttyUSB0。连接参数固定为 115200-8-N-1,无流控。常用命令:

# 查看串口设备
ls /dev/ttyUSB*

# 使用 picocom 连接
sudo picocom -b 115200 /dev/ttyUSB0

# 或使用 minicom
sudo minicom -D /dev/ttyUSB0 -b 115200

上电后应能看到 U-Boot 倒计时和内核启动日志。如果没有任何输出,先检查串口线是否接对、波特率是否匹配、板子是否真的上电。进入系统后,用 ip addr 查看网口状态。若使用 DHCP,执行 udhcpc -i eth0 获取地址;若使用静态 IP,可临时配置:

ip addr add 192.168.1.100/24 dev eth0
ip link set eth0 up
ip route add default via 192.168.1.1

网络通后,优先验证 SSH:ssh root@192.168.1.100。如果板子没有 SSH 服务,可通过串口执行 opkg install openssh-sshd 或 apt install openssh-server(取决于根文件系统)。SSH 打通后,SCP 和 rsync 就能用于日常文件传输,NFS 则适合在开发阶段直接挂载宿主机目录作为根文件系统,避免反复烧写。

五、远程部署与版本管理:让每次变更可追溯

部署不是简单地把文件拷过去。一个可复现的部署流程应包含:构建产物命名、传输、目标板落位、服务重启、版本记录。例如:

# 宿主机:构建并打包
make clean && make
tar czf vision_app_v1.2.0_$(date +%Y%m%d).tar.gz vision_app config/

# 传输到目标板
scp vision_app_v1.2.0_20250101.tar.gz root@192.168.1.100:/opt/app/

# 目标板:解压并重启服务
cd /opt/app && tar xzf vision_app_v1.2.0_20250101.tar.gz
systemctl restart vision-app.service
systemctl status vision-app.service

版本管理方面,应用源码用 Git 管理是基本要求,但更重要的是把 Yocto 构建配置也纳入版本控制。建议仓库结构如下:

  • app/:视觉应用源码,含 CMakeLists.txt 和交叉编译配置;
  • meta-custom/:Yocto 自定义 layer,含 recipe 和镜像追加配置;
  • deploy/:部署脚本、systemd 服务文件、版本清单;
  • docs/:环境搭建记录、串口/网络参数、已知问题。

每次发布时,在 deploy/versions.md 中记录:应用版本号、对应 Git commit、SDK 版本、内核版本、根文件系统构建时间。这样当现场设备出现异常时,可以快速定位是应用问题还是系统问题。对于多台终端,建议用 Ansible 或简单 Shell 脚本批量推送,避免逐台手工操作。

环境搭建检查清单:
  • SDK 安装路径无空格、无中文,environment-setup 可正常 source;
  • file 命令确认交叉编译产物为 ARM aarch64;
  • 串口 115200-8-N-1 可看到完整启动日志;
  • 目标板可 SSH 登录,SCP 传输正常;
  • Yocto 构建配置已提交 Git,镜像可复现;
  • 部署脚本包含版本号、日期和回滚说明。

环境搭建的终点不是“能跑一个 Hello World”,而是形成一条从代码修改到目标板运行的稳定流水线。当交叉编译、镜像构建、串口调试、网络部署和版本记录都各就各位后,后续的视觉算法开发、GStreamer 管道调试和边缘推理优化才有可靠的工程基础。