3. 测试环境搭建:把工具链拧成一股绳
环境搭建这事儿,说简单也简单,说复杂能折腾你三天。我见过不少同事,代码写得漂亮,结果卡在环境上——编译器版本不对、调试器连不上、版本管理冲突。说白了,测试环境就是你的“战场”,战场没铺好,仗没法打。
这一章,咱们把硬件、软件、通信、版本管理这四块挨个捋一遍。我会把我在项目里踩过的坑、养成的习惯,都抖出来。
3.1 硬件环境准备
硬件是基础。板子选不对,后面全是白费。
3.4.1 开发板选型
我个人习惯,选开发板时先看三点:
- MCU 型号:必须和项目目标芯片一致,或者至少是同一系列。别拿 STM32F1 去仿真 F4 的代码,外设寄存器地址都不一样。
- 引出接口:JTAG/SWD、串口、GPIO 都要方便测量。我遇到过一块板子,SWD 接口藏在底板下面,每次调试都得拆螺丝……
- 供电稳定性:有些廉价板子的 LDO 纹波大,会导致调试器偶尔断开。建议用外部稳压电源供电,别只靠 USB。
3.4.2 调试器选择
调试器是连接 PC 和开发板的桥梁。常用的有这几类:
| 调试器 | 接口 | 速度 | 适用场景 |
|---|---|---|---|
| J-Link | SWD / JTAG | 最高 50 MHz | ARM Cortex 全系列,稳定可靠 |
| ST-Link | SWD | 最高 4 MHz | STM32 专用,性价比高 |
| ULINK2 | JTAG / SWD | 最高 10 MHz | Keil 生态,配合 MDK 使用 |
| CMSIS-DAP | SWD | 最高 1 MHz | 开源方案,适合学习 |
我曾经用某款国产调试器,烧录 10 次有 3 次校验失败。后来换了 J-Link,再没出过问题。调试器这东西,别省那几百块钱。
3.2 软件环境准备
软件环境比硬件更“娇气”。版本不对、路径有中文、环境变量没配好,都能让你抓狂。
3.2.1 IDE 选择与配置
我常用的 IDE 就两个:
- Keil MDK:ARM 生态的老牌 IDE,编译快,调试器集成好。缺点是工程文件是 .uvprojx,跨平台不方便。
- VS Code + GCC:开源、灵活、插件丰富。适合做自动化测试,因为可以命令行编译。
嗯,这里要注意:IDE 的安装路径不要有中文和空格。我见过同事把 Keil 装到“D:\程序文件\Keil_v5”,结果编译时头文件路径解析失败,折腾了两小时。
3.2.2 编译器与调试工具
编译器决定了代码怎么变成机器码。调试工具决定了你能不能看到变量值。
| 工具 | 用途 | 版本建议 |
|---|---|---|
| ARMCC (Keil) | ARM 编译器,配合 Keil MDK | v6.16 以上 |
| GCC ARM None EABI | 开源 ARM 编译器 | 10.3-2021.10 以上 |
| OpenOCD | 开源调试与烧录工具 | v0.11.0 以上 |
| J-Link Commander | J-Link 命令行工具 | v7.70 以上 |
3.3 目标板与宿主机通信配置
通信配置是环境搭建里最容易出幺蛾子的环节。你想想看,板子焊好了、代码编译通过了,就是连不上调试器,急不急?
3.3.1 调试接口连接
SWD 接口只需要 4 根线:SWDIO、SWCLK、GND、VCC(可选)。但实际项目中,我建议多接一根 RST:
- SWDIO:数据线
- SWCLK:时钟线
- GND:共地(必须接!)
- VCC:参考电压(可选,但建议接)
- RST:复位线(强烈建议接)
为什么建议接 RST?因为当芯片进入低功耗模式或者死机时,调试器可能无法通过 SWD 唤醒芯片。这时候拉一下 RST,就能重新连接。我遇到过三次这种情况,都是靠 RST 线救回来的。
3.3.2 串口通信配置
串口是嵌入式调试的“眼睛”。配置参数必须和代码里一致:
| 参数 | 常见值 | 说明 |
|---|---|---|
| 波特率 | 115200 / 921600 | 越高越快,但线长时容易丢包 |
| 数据位 | 8 | 几乎都是 8 位 |
| 停止位 | 1 | 1 位停止位最常用 |
| 校验位 | None | 调试场景一般不校验 |
| 流控制 | None | 调试串口不需要 RTS/CTS |
我个人习惯用 921600 波特率。115200 在打印大量日志时太慢,会拖慢系统响应。但要注意,有些 USB 转串口芯片(比如 CH340G)在高速率下不稳定,建议用 FT232 或 CP2102。
3.4 版本管理工具集成
版本管理不是“锦上添花”,而是“保命符”。我见过有人把代码存在 U 盘里,U 盘丢了,三个月白干。
3.4.1 Git 基础配置
嵌入式项目用 Git 管理,有几个特殊点:
- .gitignore 要写好:忽略编译产物(.o、.hex、.bin)、IDE 临时文件(.uvguix、.scvd)、输出文件夹(Build、Output)。
- 不要管理 .uvprojx 的绝对路径:Keil 工程文件里会记录源文件路径,如果团队里有人把工程放在不同目录,一同步就冲突。
- 二进制文件用 LFS:固件镜像、测试数据等大文件,用 Git LFS 管理,否则仓库会膨胀到几百 MB。
# 编译产物
*.o
*.d
*.hex
*.bin
*.elf
*.map
# IDE 文件
*.uvguix.*
*.scvd
*.uvoptx
# 输出目录
Build/
Output/
Debug/
Release/
# 系统文件
*.swp
.DS_Store
Thumbs.db
3.4.2 分支策略
嵌入式项目建议用 Git Flow 的简化版:
| 分支 | 用途 | 谁可以合并 |
|---|---|---|
| main | 发布版本,只接受经过完整测试的代码 | 技术负责人 |
| develop | 日常开发,集成各功能模块 | 所有开发者 |
| feature/* | 新功能开发,从 develop 拉出 | 功能负责人 |
| hotfix/* | 紧急修复,从 main 拉出 | 指定修复人 |
我曾经在一个项目里,团队 6 个人全在 main 上开发。结果有人提交了未完成的代码,导致编译失败,其他人拉下来也跑不了。从那以后,我强制要求用 feature 分支开发,合并前必须经过 Code Review。
3.5 环境搭建整体流程
下面这张图,是我做环境搭建时的标准流程。你可以照着它一步步来,能省掉不少弯路。
3.6 环境验证清单
环境搭完别急着写代码。先跑一遍验证清单,确认每个环节都通:
- 烧录验证:编译一个 LED 闪烁程序,烧录到板子,看灯亮不亮。
- 调试验证:在 main 函数第一行打断点,看能不能停住。
- 串口验证:打印 "Hello World",看 PC 端能不能收到。
- 版本管理验证:修改一个文件,提交、推送、拉取,看有没有冲突。
环境搭建这事儿,说白了就是“磨刀不误砍柴工”。你花半天把环境整利索了,后面写代码、跑测试会顺畅很多。反过来,环境没弄好就急着写代码,后面大概率要返工。