序言:为什么我们要"手撕"嵌入式 TDD?
在嵌入式开发的世界里,我们似乎习惯了某种"玄学":代码逻辑对不对?烧录进去跑跑看;死机了?接上仿真器打断点;时序不对?接上示波器抓波形。
这种"硬件依赖型"的开发模式,正在成为软件复杂化的枷锁。随着项目规模扩大,你会发现:
-
反馈周期太长:编译、烧录、复位的循环极大消耗了专注力。
-
测试场景难复现:你怎么在实验室里模拟传感器正好在第 65535 个毫秒溢出的异常?
-
不敢重构:面对前人留下的"屎山"驱动,因为没有测试覆盖,没人敢动。
TDD(Test-Driven Development,测试驱动开发) 不是什么高深莫测的理论,它只是一种节奏 :在写功能代码之前,先写测试用例。而 Unity + CMock + Ceedling 这一套工具,就是为了让这种节奏在 C 语言环境中像呼吸一样自然。
通过这个专栏,我会带你把逻辑从硬件中剥离出来,用"上帝视角"去操控时间、操控 GPIO、操控复杂的协议栈。
要在 PC 上跑 STM32 的测试,我们不需要模拟整颗 MCU,我们只需要一个能运行 C 代码的原生编译器 (如 GCC)和一个高效的构建系统。
1.1 工具链全家桶
-
Unity :一个轻量级的 C 语言单元测试框架(主要负责断言,比如
TEST_ASSERT_EQUAL)。 -
CMock :这个专栏的灵魂。它能根据
.h文件自动生成"假"的函数(Mock),帮我们欺骗逻辑层。 -
Ceedling:这就是我们要用的"大管家",它基于 Ruby,把 Unity 和 CMock 整合在一起,你只需要一个命令就能跑完所有测试。
1.2 环境准备(以 Windows 为例)
你需要安装以下三个基础工具:
-
Ruby:Ceedling 是用 Ruby 写的(推荐 3.x 版本)。
-
GCC (MinGW/MSYS2):用于在 PC 上编译你的 C 代码。
-
Ceedling Gem : 打开终端执行:
gem install ceedling
1.3 创建你的第一个项目
找一个干净的文件夹,输入:
ceedling new MyStm32Project
你会看到生成的目录结构:
-
src/:存放你的 STM32 源代码(.c)。 -
test/:存放测试脚本。 -
project.yml:Ceedling 的配置文件(核心)。
1.4 第一个测试:验证"加法"
为了确保环境跑通,我们先不碰硬件。
步骤 1:在 src/ 创建 calculator.h
int add(int a, int b);
步骤 2:在 test/ 创建 test_calculator.c
#include "unity.h"
#include "calculator.h"
void test_addition_should_work(void) {
TEST_ASSERT_EQUAL(5, add(2, 3));
}
步骤 3:运行测试 在根目录输入:
ceedling test:all
结果: 你会看到一个红色的失败 。因为你还没实现 add 函数。这就是 TDD 的第一步:红(Red)。
步骤 4:实现代码 在 src/ 创建 calculator.c 并实现函数。再次运行命令,你会看到那道令人愉悦的绿色进度条(Green)。
本章小结
我们已经跨过了最难的一步:搭建好了"无硬件开发"的基础设施。从下一章开始,我们要开始对 STM32 的硬件接口下手了。