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 连接验证

连接完成后,做一次完整的启动验证:

  1. 上电,观察串口输出,确认U-Boot启动正常
  2. 在U-Boot中执行ping 192.168.1.100,确认网络连通
  3. 使用tftp下载内核镜像:tftp ${loadaddr} Image
  4. 使用NFS挂载根文件系统:setenv root=/dev/nfs rw nfsroot=192.168.1.100:/srv/nfs/rootfs
  5. 执行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 开发环境全景图

下面这张图展示了整个开发环境的架构和交互流程。我把它放在这里,方便你对照理解。

TI Jacinto BSP开发环境全景图 主机层 (Ubuntu 22.04) • 交叉编译器 (aarch64-linux-gnu-gcc) • SDK 8.6 (内核5.10) • NFS服务器 /srv/nfs/rootfs • tftp服务器 /srv/tftp • 串口终端 (picocom/minicom) 连接层 • USB转串口 (115200 8N1) • 以太网 (静态IP) • JTAG调试器 (XDS110) • USB烧录 (fastboot/uniflash) 目标板层 (Jacinto) • TDA4VM / DRA829 / AM68A • U-Boot 2021.01 • Linux内核 5.10 • 根文件系统 (tisdk-rootfs) 典型开发流程 1. 编写/修改驱动 2. 交叉编译 3. 部署到目标板 4. 调试与验证 5. 迭代优化 反馈循环:根据调试结果修改代码,重新编译部署

这张图把整个开发环境分成了三层:主机层、连接层、目标板层。箭头方向是数据流方向,下面的流程展示了从编写驱动到迭代优化的完整闭环。你想想看,每次修改驱动都要走一遍这个流程,所以环境稳定性和连接可靠性至关重要。

个人建议:刚开始做BSP开发时,别急着写复杂驱动。先把环境跑通,用Hello World验证交叉编译链,用NFS挂载根文件系统,用tftp下载内核。这些基础操作熟练了,后面调试驱动时才不会手忙脚乱。