1. BSP开发环境全景:搭建TI Jacinto平台的交叉编译环境、SDK安装与配置、目标板与主机连接
做嵌入式BSP开发,第一件事就是把环境搭好。这事听起来简单,但我见过太多工程师在这上面栽跟头——SDK版本不对、交叉编译器路径配错、网络连不上,一折腾就是半天。说白了,环境搭建是后面所有工作的地基,地基不稳,后面全是白费。
1.1 开发环境总览
TI Jacinto平台的BSP开发,核心是交叉编译。什么意思?你的代码在x86主机上写、编译,生成的目标文件却要在ARM架构的Jacinto芯片上跑。这中间需要一套完整的工具链和SDK。
我个人习惯把环境分成三层:
- 主机层:Ubuntu 20.04/22.04 LTS,这是TI官方推荐的主机系统。别用Windows,别问我为什么,踩过坑的人都知道。
- 工具链层:交叉编译器、调试器(gdb-multiarch)、烧录工具(uniflash、fastboot)。
- SDK层:TI Processor SDK Linux for Jacinto,包含内核源码、设备树、文件系统、驱动示例。
核心原则:主机、工具链、SDK三者版本必须严格匹配。我曾经因为SDK版本和编译器版本差了两个月,结果某个驱动模块死活编译不过,最后查了三天才发现是ABI不兼容。
1.2 主机环境准备
先说说主机。我建议用Ubuntu 22.04 LTS,干净安装,不要装乱七八糟的软件包。为什么?因为TI的SDK对系统环境很敏感,多一个包可能没事,少一个包就报错。
安装基础依赖:
sudo apt update
sudo apt install -y build-essential git vim curl wget
sudo apt install -y libncurses5-dev libssl-dev flex bison
sudo apt install -y u-boot-tools device-tree-compiler
sudo apt install -y python3 python3-pip python3-venv
sudo apt install -y minicom picocom screen
嗯,这里要注意:不要用apt自动安装的gcc-arm-linux-gnueabihf。那个版本太老,和TI SDK不兼容。交叉编译器必须从SDK里拿,或者从TI官网下载。
1.3 SDK安装与配置
TI Processor SDK Linux for Jacinto,这是整个BSP开发的核心。我以SDK 8.6为例(对应Linux内核5.10)。
1.3.1 下载SDK
从TI官网下载SDK安装包。注意区分平台:
| 芯片型号 | SDK名称 | 内核版本 |
|---|---|---|
| TDA4VM | ti-processor-sdk-linux-j7-evm-08_06_00_11 | 5.10 |
| DRA829 | ti-processor-sdk-linux-j7-evm-08_06_00_11 | 5.10 |
| AM68A | ti-processor-sdk-linux-am68a-evm-08_06_00_11 | 5.10 |
1.3.2 安装SDK
SDK安装脚本是自解压的。我个人习惯放在/opt/ti目录下:
chmod +x ti-processor-sdk-linux-j7-evm-08_06_00_11-Linux-x86-Install.bin
./ti-processor-sdk-linux-j7-evm-08_06_00_11-Linux-x86-Install.bin
# 选择安装路径:/opt/ti/ti-processor-sdk-linux-j7-evm-08_06_00_11
安装完成后,目录结构是这样的:
/opt/ti/ti-processor-sdk-linux-j7-evm-08_06_00_11/
├── bin/ # 工具脚本
├── board-support/ # 板级支持包(U-Boot、内核源码)
├── filesystem/ # 根文件系统(tisdk-rootfs-image)
├── linux-devkit/ # 交叉编译工具链
├── Makefile # 顶层构建脚本
└── Rules.make # 构建规则配置
小技巧:安装完成后,先执行一次make clean和make all,验证SDK完整性。我第一次用SDK 8.0时,有个文件系统包下载不完整,结果编译到一半报错,浪费了整整一个下午。
1.3.3 配置交叉编译环境
SDK自带的交叉编译器在linux-devkit/sysroots/x86_64-arago-linux/usr/bin下。我建议把它加到~/.bashrc里:
export SDK_PATH=/opt/ti/ti-processor-sdk-linux-j7-evm-08_06_00_11
export PATH=$SDK_PATH/linux-devkit/sysroots/x86_64-arago-linux/usr/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
验证一下:
aarch64-linux-gnu-gcc --version
# 输出:aarch64-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 9.2.1) 9.2.1 20191025
这里有个坑:环境变量必须在每次打开终端时都生效。我建议写一个独立的脚本setup_jacinto_env.sh,每次开发前source一下:
#!/bin/bash
export SDK_PATH=/opt/ti/ti-processor-sdk-linux-j7-evm-08_06_00_11
export PATH=$SDK_PATH/linux-devkit/sysroots/x86_64-arago-linux/usr/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export TI_SDK_DEVKIT=$SDK_PATH/linux-devkit
echo "Jacinto BSP development environment is ready."
1.4 目标板与主机连接
环境搭好了,接下来要把目标板和主机连起来。Jacinto平台通常通过USB转串口和以太网两种方式与主机通信。
1.4.1 串口连接
串口用于U-Boot交互和内核启动日志查看。连接方式:
- 目标板上的Debug UART口(通常是J3或J4)
- USB转串口模块(推荐FT232或CP2102)
- 主机端使用minicom或picocom
配置串口参数:
# 查看串口设备
ls /dev/ttyUSB*
# 通常是 /dev/ttyUSB0
# 使用picocom连接
sudo picocom -b 115200 -d 8 -p n -s 1 /dev/ttyUSB0
# 或者使用minicom
sudo minicom -D /dev/ttyUSB0 -b 115200
串口参数必须匹配:115200波特率、8数据位、无校验、1停止位。这个参数在U-Boot和内核里都是默认的,别乱改。
注意:串口线不要超过2米。我曾经用了一根5米的串口线,结果数据丢包严重,U-Boot启动信息全是乱码。换了根1米的线,问题立刻解决。
1.4.2 网络连接
网络用于NFS挂载根文件系统、tftp下载内核镜像、ssh远程调试。我建议用静态IP,避免DHCP带来的不确定性。
主机端配置:
# 设置主机IP(以eth0为例)
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
# 安装NFS服务器
sudo apt install nfs-kernel-server
sudo mkdir -p /srv/nfs/rootfs
sudo cp -r $SDK_PATH/filesystem/tisdk-rootfs-image-j7-evm.tar.xz /srv/nfs/rootfs/
sudo tar -xf /srv/nfs/rootfs/tisdk-rootfs-image-j7-evm.tar.xz -C /srv/nfs/rootfs/
# 配置NFS导出
echo "/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -a
目标板端(U-Boot中设置):
setenv ipaddr 192.168.1.10
setenv serverip 192.168.1.100
setenv netmask 255.255.255.0
setenv gatewayip 192.168.1.1
saveenv
1.4.3 连接验证
连接完成后,做一次完整的启动验证:
- 上电,观察串口输出,确认U-Boot启动正常
- 在U-Boot中执行
ping 192.168.1.100,确认网络连通 - 使用tftp下载内核镜像:
tftp ${loadaddr} Image - 使用NFS挂载根文件系统:
setenv root=/dev/nfs rw nfsroot=192.168.1.100:/srv/nfs/rootfs - 执行
boot,观察内核启动日志
避坑指南:我曾经遇到一个情况——网络ping得通,但tftp下载总是超时。查了半天,发现是主机防火墙没关。执行sudo ufw disable后问题解决。另外,NFS挂载失败时,先检查/etc/exports的权限配置,no_root_squash这个选项不能少。
1.5 环境验证与常见问题
环境搭完,跑一个简单的Hello World验证交叉编译链:
# hello.c
#include <stdio.h>
int main() {
printf("Hello from Jacinto BSP!\n");
return 0;
}
# 交叉编译
aarch64-linux-gnu-gcc -o hello hello.c
# 查看文件类型
file hello
# 输出:hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV)
把这个文件拷贝到目标板根文件系统里,执行一下,看到输出就说明环境没问题。
常见问题汇总:
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 串口输出乱码 | 波特率不匹配或串口线过长 | 检查波特率设置,更换短串口线 |
| tftp下载超时 | 防火墙未关闭或tftp服务未启动 | sudo ufw disable,sudo systemctl start tftpd-hpa |
| NFS挂载失败 | exports配置错误或权限问题 | 检查/etc/exports,添加no_root_squash |
| 交叉编译报错 | 环境变量未设置或编译器版本不匹配 | 重新source环境脚本,检查编译器版本 |
1.6 开发环境全景图
下面这张图展示了整个开发环境的架构和交互流程。我把它放在这里,方便你对照理解。
这张图把整个开发环境分成了三层:主机层、连接层、目标板层。箭头方向是数据流方向,下面的流程展示了从编写驱动到迭代优化的完整闭环。你想想看,每次修改驱动都要走一遍这个流程,所以环境稳定性和连接可靠性至关重要。
个人建议:刚开始做BSP开发时,别急着写复杂驱动。先把环境跑通,用Hello World验证交叉编译链,用NFS挂载根文件系统,用tftp下载内核。这些基础操作熟练了,后面调试驱动时才不会手忙脚乱。