2、开发环境搭建:安装交叉编译工具链、SDK、驱动、依赖库,配置宿主机与目标板通信
算能BM1684/BM1688系列AI加速盒(如SE5、SM5、SC5等型号)本质上是一台运行Linux系统的ARM嵌入式计算机,其算力核心是TPU(张量处理器)。开发者在x86_64架构的PC(宿主机)上编写C/C++或Python代码,通过交叉编译生成ARM架构的可执行文件,再将其部署到目标板上运行。本章将系统讲解从零搭建开发环境的完整链路,包括交叉编译工具链的安装、SDK的获取与配置、驱动与依赖库的安装,以及宿主机与目标板之间的通信配置。整个过程是后续所有算法移植、模型推理和性能调优的基础,任何一步配置不当都会导致后续开发寸步难行。
上图展示了开发环境搭建的整体架构。宿主机负责代码编写、交叉编译和调试,目标板负责实际运行推理任务。两者之间通过以太网(SSH/SCP/NFS)或串口进行通信。下面我们将按照实际操作顺序,逐步讲解每个环节的具体配置方法。
2.1 交叉编译工具链安装
核心原理
交叉编译是指在x86_64架构的宿主机上,编译生成ARM架构(aarch64)可执行文件的过程。BM1684/BM1688目标板采用ARM Cortex-A53/A55架构,无法直接运行x86_64编译的二进制文件。交叉编译工具链提供了一套完整的编译器、汇编器、链接器和库文件,使得开发者可以在性能强大的PC上进行编译,再将产物拷贝到目标板运行。
操作流程
- 安装基础工具:首先更新宿主机软件源并安装基础依赖:
sudo apt update
sudo apt install -y build-essential git cmake python3-dev
- 安装交叉编译工具链:Ubuntu 20.04/22.04 可直接通过apt安装:
sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
安装完成后,验证工具链是否可用:
aarch64-linux-gnu-gcc --version
# 输出示例:aarch64-linux-gnu-gcc (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0
- 验证编译:编写一个简单的Hello World程序测试交叉编译:
#include <stdio.h>
int main() {
printf("Hello BM1684!\n");
return 0;
}
aarch64-linux-gnu-gcc hello.c -o hello_arm
file hello_arm
# 输出:hello_arm: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV)
2.2 BMNNSDK2 SDK安装与配置
核心原理
BMNNSDK2是算能科技提供的完整软件开发套件,包含TPU运行时库(libbmrt)、计算机视觉库(libbmcv)、BMLib底层库、模型转换工具(bmnetc/bmnetp)以及丰富的示例代码。SDK分为宿主机端(用于交叉编译)和目标板端(用于运行时加载)两部分,两者版本必须严格对应。
安装步骤
| SDK组件 | 宿主机端路径 | 目标板端路径 | 说明 |
|---|---|---|---|
| libbmcv | ${SDK}/lib/bmcv/libbmcv.a | /usr/lib/libbmcv.so | 图像预处理/后处理库 |
| libbmlib | ${SDK}/lib/bmlib/libbmlib.a | /usr/lib/libbmlib.so | 底层设备管理库 |
| libbmrt | ${SDK}/lib/bmrt/libbmrt.a | /usr/lib/libbmrt.so | TPU运行时推理库 |
| bmrt_test | ${SDK}/bin/bmrt_test | /usr/bin/bmrt_test | 推理测试工具 |
| bm_modelbin | ${SDK}/bin/bm_modelbin | /usr/bin/bm_modelbin | 模型转换工具 |
- 下载SDK:从算能官网(developer.sophgo.com)下载BMNNSDK2,解压到宿主机:
tar -xzf BMNNSDK2-7.1.0.tar.gz
cd BMNNSDK2-7.1.0
- 配置环境变量:编辑 ~/.bashrc 添加以下内容:
export BMNNSDK2=/path/to/BMNNSDK2-7.1.0
export PATH=$BMNNSDK2/bin:$PATH
export LD_LIBRARY_PATH=$BMNNSDK2/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=$BMNNSDK2/lib:$LIBRARY_PATH
export CPLUS_INCLUDE_PATH=$BMNNSDK2/include:$CPLUS_INCLUDE_PATH
- 验证SDK安装:
source ~/.bashrc
bmrt_test --version
# 输出:BMNNSDK2 version: 7.1.0
bm_version 命令检查目标板固件版本。
2.3 目标板驱动与依赖库安装
核心原理
目标板需要安装TPU设备驱动(bmdev.ko、bmrt.ko)以及运行时依赖库。驱动负责管理TPU硬件资源,提供设备节点(/dev/bmdev);依赖库则提供应用程序运行所需的API接口。安装方式有两种:一是通过官方提供的Debian安装包,二是手动拷贝编译好的库文件。
安装流程
- 连接目标板:通过串口或SSH登录目标板(默认IP:192.168.1.10,用户:root,密码:sophgo)。
- 安装驱动:将SDK中目标板驱动包拷贝到目标板并安装:
# 在宿主机上执行
scp $BMNNSDK2/scripts/install_driver.sh root@192.168.1.10:/root/
scp $BMNNSDK2/lib/bmrt/kernel/bmrt.ko root@192.168.1.10:/root/
scp $BMNNSDK2/lib/bmlib/kernel/bmdev.ko root@192.168.1.10:/root/
# 在目标板上执行
cd /root
chmod +x install_driver.sh
./install_driver.sh
# 验证驱动是否加载成功
ls /dev/bmdev
# 输出:/dev/bmdev
- 安装依赖库:将宿主机SDK中的目标板库文件拷贝到目标板:
# 在宿主机上执行
scp $BMNNSDK2/lib/bmcv/libbmcv.so root@192.168.1.10:/usr/lib/
scp $BMNNSDK2/lib/bmlib/libbmlib.so root@192.168.1.10:/usr/lib/
scp $BMNNSDK2/lib/bmrt/libbmrt.so root@192.168.1.10:/usr/lib/
# 在目标板上执行
ldconfig
- 安装OpenCV等第三方库:目标板通常需要OpenCV进行图像处理,可通过apt安装:
apt install -y libopencv-dev python3-opencv
现象:执行
insmod bmdev.ko 时报错 "Invalid module format"。分析:内核版本与驱动编译时使用的内核头文件不一致。目标板内核版本为5.10,而驱动是用5.4内核头文件编译的。
解决:重新编译驱动模块,使用目标板当前内核的源码树:
cd $BMNNSDK2/scripts && make KERNEL_PATH=/usr/src/linux-headers-$(uname -r)结果:重新编译后insmod成功,/dev/bmdev节点正常创建。
2.4 宿主机与目标板通信配置
核心原理
开发过程中需要频繁在宿主机和目标板之间传输文件、执行远程命令。常用的通信方式包括:SSH(远程登录)、SCP(文件传输)、NFS(网络文件系统挂载)和串口(调试)。其中SSH+SCP是最基础的组合,NFS适合开发阶段频繁修改代码的场景,串口则用于系统无法正常启动时的紧急调试。
通信配置步骤
| 通信方式 | 适用场景 | 配置要点 | 常用命令 |
|---|---|---|---|
| SSH | 远程命令执行 | 确保sshd服务启动,端口22开放 | ssh root@192.168.1.10 |
| SCP | 单次文件传输 | 基于SSH,无需额外配置 | scp file root@IP:/path |
| NFS | 开发阶段代码共享 | 宿主机配置/etc/exports | mount -t nfs host:/dir /mnt |
| 串口 | 系统调试/紧急恢复 | 波特率115200,8N1 | minicom -D /dev/ttyUSB0 |
- SSH配置:目标板默认开启SSH服务,宿主机直接连接即可:
ssh root@192.168.1.10
# 首次连接需要输入密码:sophgo
- 配置静态IP:为避免每次开机IP变化,建议配置静态IP。编辑目标板 /etc/netplan/01-netcfg.yaml:
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.1.10/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 114.114.114.114]
netplan apply
- NFS挂载配置:在宿主机上配置NFS共享目录:
# 宿主机编辑 /etc/exports
/home/user/bm1684_workspace 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
# 目标板挂载
mount -t nfs 192.168.1.100:/home/user/bm1684_workspace /mnt/workspace
2.5 环境验证与常见问题
验证流程
完成上述配置后,通过以下步骤验证整个开发环境是否正常:
- 编译验证:在宿主机交叉编译一个调用BMNNSDK2 API的测试程序:
# test_bm.cpp
#include "bmruntime.h"
int main() {
bm_handle_t handle;
bm_dev_request(&handle, 0);
printf("TPU handle created successfully!\n");
bm_dev_free(handle);
return 0;
}
aarch64-linux-gnu-g++ test_bm.cpp -I$BMNNSDK2/include -L$BMNNSDK2/lib -lbmrt -o test_bm
- 部署运行:将编译产物拷贝到目标板并运行:
scp test_bm root@192.168.1.10:/root/
ssh root@192.168.1.10 "./test_bm"
# 输出:TPU handle created successfully!
- 性能测试:使用bmrt_test工具验证TPU推理性能:
bmrt_test --input test.bin --model yolov5s.bmodel
# 输出推理耗时、吞吐量等指标
常见误区与总结
- 误区一:使用gcc而非aarch64-linux-gnu-gcc。直接使用gcc编译出的x86_64程序无法在目标板运行,会报"Exec format error"。
- 误区二:忽略动态库依赖。交叉编译时使用静态链接(-static)可以避免目标板缺少库的问题,但会导致可执行文件体积增大且无法使用dlopen动态加载。
- 误区三:IP地址冲突。多块目标板同时连接时,需要为每块板设置不同的静态IP,否则会导致网络通信异常。
- 误区四:SDK版本不匹配。宿主机SDK与目标板固件版本必须一致,否则运行时会出现"TPU firmware mismatch"错误。
背景:某AIoT项目需要在BM1684盒子上部署YOLOv5目标检测模型,开发周期2周。
约束:宿主机为Ubuntu 20.04,目标板为SE5系列,SDK版本7.1.0。
操作过程:
① 安装交叉编译工具链(耗时10分钟);
② 下载并配置BMNNSDK2(耗时30分钟);
③ 通过SSH连接目标板,安装驱动和依赖库(耗时20分钟);
④ 配置NFS共享目录,实现代码实时同步(耗时15分钟);
⑤ 交叉编译YOLOv5示例程序,部署到目标板运行(耗时1小时)。
结果:从零搭建到跑通第一个模型推理,总计约2小时。后续开发效率显著提升,代码修改后通过NFS立即生效。
风险与代价:初次搭建时因SDK版本不匹配导致驱动加载失败,排查耗时1小时。建议在项目启动前先确认SDK与固件版本对应关系。