2. 嵌入式系统基础

做嵌入式测试,第一关不是写代码,而是把环境搭起来。我见过太多人卡在这一步,工具链装到一半就放弃了。其实没那么复杂,咱们一步步来。

本章核心目标:让你的电脑能跟目标板“说话”,能编译代码,能单步调试。说白了,就是打通从开发机到嵌入式设备的整条路。

2.1 硬件调试器:J-Link 与 ST-Link 配置

调试器是连接电脑和嵌入式设备的桥梁。我个人习惯用 J-Link,兼容性好,速度快。ST-Link 也不错,便宜,跟 STM32 是绝配。

2.1.1 J-Link 驱动安装与验证

  1. 下载驱动:去 SEGGER 官网下载 J-Link Software and Documentation Pack。别下错了版本,Windows 就选 Windows 版,Linux 选 Linux 版。
  2. 安装:Windows 下双击安装,一路 Next。Linux 下解压后运行 install.sh。
  3. 验证:插上 J-Link,打开命令行输入 JLinkExe。如果出现 SEGGER J-Link Commander 提示符,说明驱动装好了。

小技巧:我曾经在 Linux 下装完 J-Link 后死活连不上设备,后来发现是 udev 规则没配。执行 sudo cp 99-jlink.rules /etc/udev/rules.d/ 再重启一下 udev 服务就好了。

2.1.2 ST-Link 驱动安装

ST-Link 更简单。Windows 下装 STM32CubeProgrammer 或者 ST-Link Utility 就行。Linux 下通常不需要额外驱动,内核自带。插上后 lsusb 能看到 STMicroelectronics ST-Link 就对了。

注意:ST-Link 有 V2 和 V3 版本,V3 速度更快但驱动不通用。我建议统一用 V2,兼容性最好。

2.2 交叉编译工具链安装

嵌入式设备资源有限,没法直接在板子上编译代码。我们需要在 PC 上编译,生成目标板能运行的机器码。这就是交叉编译。

常用的工具链是 arm-none-eabi-gcc。为什么叫这个名字?arm 是目标架构,none 表示无操作系统,eabi 是嵌入式应用二进制接口。

2.2.1 安装步骤

平台 安装方式 命令/操作
Windows 下载安装包 从 ARM 官网下载 .exe 安装,添加环境变量
Linux (Ubuntu) apt 安装 sudo apt install gcc-arm-none-eabi
macOS brew 安装 brew install arm-none-eabi-gcc

装完后验证一下:

arm-none-eabi-gcc --version

能看到版本号就说明装好了。我建议装 10.3 以上版本,对 C11 和 C++17 支持更好。

避坑指南:我曾经用 apt 装过一个老版本,编译出来的代码在 Cortex-M4 上跑出了奇怪的问题。后来换成 10.3 版本就没事了。所以版本很重要,别用太老的。

2.3 OpenOCD 与 GDB 服务器搭建

OpenOCD(Open On-Chip Debugger)是个开源调试工具,能跟各种调试器通信。GDB 是 GNU 调试器,负责执行调试命令。两者配合,就能实现单步、断点、查看变量等操作。

2.3.1 OpenOCD 安装

# Linux 下安装
sudo apt install openocd

# 验证
openocd --version

Windows 下可以去官网下载预编译包,解压后把路径加到环境变量里。

2.3.2 配置文件编写

OpenOCD 需要配置文件来告诉它用什么调试器、连什么芯片。下面是一个典型的配置:

# stm32f4.cfg
source [find interface/stlink.cfg]
source [find target/stm32f4x.cfg]

# 设置调试速度
adapter speed 1000

这个配置告诉 OpenOCD:用 ST-Link 调试器,目标是 STM32F4 系列芯片,调试速度 1000kHz。

2.3.3 启动 GDB 服务器

写好配置文件后,启动 OpenOCD:

openocd -f stm32f4.cfg

看到 Info : Listening on port 3333 for gdb connections 就说明服务器跑起来了。默认监听 3333 端口。

然后另开一个终端,启动 GDB:

arm-none-eabi-gdb your_program.elf
(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) load
(gdb) continue

这几条命令的意思是:连接远程服务器、复位并暂停目标板、下载程序、运行。

个人经验:我习惯把 GDB 命令写成一个脚本文件,比如 debug.gdb,里面放好 target remote、monitor reset halt、load 这些命令。每次调试时直接 arm-none-eabi-gdb -x debug.gdb,省事多了。

2.4 整体架构图

下面这张图展示了整个调试环境的架构。你想想看,从 PC 到目标板,数据是怎么流动的?

嵌入式调试环境架构图 PC 开发机 GDB + IDE 硬件调试器 J-Link / ST-Link 目标板 STM32 / 其他 MCU OpenOCD GDB 服务器 TCP :3333 USB SWD / JTAG 说明: GDB 通过 TCP 连接 OpenOCD,OpenOCD 通过 USB 控制调试器,调试器通过 SWD/JTAG 协议与目标板通信。

2.5 常见问题与排查

环境搭建总会遇到各种问题。我整理了几个高频问题,你遇到了可以直接对照排查。

问题现象 可能原因 解决办法
OpenOCD 找不到调试器 驱动未安装或 udev 规则缺失 检查驱动,Linux 下配置 udev 规则
GDB 连接超时 OpenOCD 未启动或端口被占用 确认 OpenOCD 已运行,检查 3333 端口
下载程序后不运行 复位向量表错误或启动文件缺失 检查链接脚本和启动文件
单步调试卡死 调试器速度过快或电源不稳定 降低 adapter speed 值

重要提醒:调试器连接目标板时,注意接线顺序。SWD 接口至少需要 SWDIO、SWCLK、GND 三根线。我见过有人忘了接 GND,结果调试器一直报错,折腾了半天才发现。

2.6 本章小结

环境搭建是嵌入式测试的基础。你想想看,如果连调试器都连不上,后面的单元测试、集成测试根本没法做。所以这一步虽然繁琐,但值得花时间搞定。

我个人建议:先把 J-Link 或 ST-Link 驱动装好,再装交叉编译工具链,最后搭 OpenOCD 和 GDB。按这个顺序来,问题会少很多。遇到问题别慌,对照上面的排查表一步步来,基本都能解决。