2. 嵌入式系统基础
做嵌入式测试,第一关不是写代码,而是把环境搭起来。我见过太多人卡在这一步,工具链装到一半就放弃了。其实没那么复杂,咱们一步步来。
本章核心目标:让你的电脑能跟目标板“说话”,能编译代码,能单步调试。说白了,就是打通从开发机到嵌入式设备的整条路。
2.1 硬件调试器:J-Link 与 ST-Link 配置
调试器是连接电脑和嵌入式设备的桥梁。我个人习惯用 J-Link,兼容性好,速度快。ST-Link 也不错,便宜,跟 STM32 是绝配。
2.1.1 J-Link 驱动安装与验证
- 下载驱动:去 SEGGER 官网下载 J-Link Software and Documentation Pack。别下错了版本,Windows 就选 Windows 版,Linux 选 Linux 版。
- 安装:Windows 下双击安装,一路 Next。Linux 下解压后运行
install.sh。 - 验证:插上 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 到目标板,数据是怎么流动的?
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。按这个顺序来,问题会少很多。遇到问题别慌,对照上面的排查表一步步来,基本都能解决。