1. 课程导学与开发环境准备:TDD与Renode概述、课程目标、安装Python3、Git、Renode与依赖工具链
1.1 这门课到底讲什么?
先说说我为什么想做这门课。
做了十几年嵌入式开发,我见过太多「写完代码再调试」的惨案。项目 deadline 前一周,bug 像韭菜一样割不完。你改一个变量,崩三个模块。这种体验,我相信你不陌生。
TDD(测试驱动开发)在互联网后端已经普及了,但在嵌入式领域,很多人觉得「硬件没法测」、「仿真太慢」、「写测试比写代码还费时间」。说实话,我以前也这么想。
直到有一次,我在一个 STM32 的电机控制项目里,硬着头皮用了 TDD。结果呢?原来需要两周的联调,五天就搞定了。从那以后,我就成了 TDD 的布道者。
这门课的核心就三件事:
- 学会 TDD 的思维——先写测试,再写代码,让测试驱动你的设计
- 玩转 Renode 仿真——在电脑上跑嵌入式程序,不用反复烧录硬件
- 把两者结合起来——用 TDD 的方式开发嵌入式软件,用 Renode 做自动化验证
课程目标速览
- 掌握 TDD 红-绿-重构循环,能独立编写嵌入式单元测试
- 熟练使用 Renode 进行外设仿真、脚本化测试和回归验证
- 搭建一套完整的 CI 流水线,让每次提交都自动跑测试
- 最终能独立开发一个带外设驱动的嵌入式项目,测试覆盖率达到 80% 以上
1.2 TDD 到底是什么?
说白了,TDD 就是「先写测试,再写代码」。流程很简单:
- 红——写一个会失败的测试
- 绿——写刚好能让测试通过的代码
- 重构——优化代码,保持测试通过
你想想看,这跟传统开发方式完全反过来了。传统方式是先写代码,再补测试(甚至不补)。TDD 是先想清楚「我要什么结果」,再动手实现。
我刚开始练 TDD 的时候,总觉得别扭。明明能直接写功能代码,为什么要先写测试?后来我发现,TDD 最大的好处不是「测 bug」,而是倒逼你把代码设计得更好。因为测试先写,你的代码必须可测试——这就意味着低耦合、高内聚。
我的经验:TDD 最难的不是技术,是习惯。前两周你会觉得效率变慢了,但坚持一个月后,你会发现 debug 时间减少了 70%。
1.3 Renode 能干什么?
Renode 是一个开源的嵌入式仿真平台。它不是模拟器,而是仿真器——可以模拟完整的硬件平台,包括 CPU、内存、外设、甚至多个设备互联。
为什么选 Renode 而不是 QEMU 或其他?
| 特性 | Renode | QEMU | 硬件开发板 |
|---|---|---|---|
| 外设仿真 | 丰富(GPIO/UART/SPI/I2C等) | 有限 | 真实但昂贵 |
| 多节点仿真 | 支持(多个MCU互联) | 有限 | 需要额外硬件 |
| 脚本化控制 | 原生支持(Robot Framework) | 需要额外工具 | 需要外接设备 |
| 调试能力 | GDB + 日志 + 波形 | GDB | JTAG/SWD |
| CI 集成 | 开箱即用 | 可以 | 困难 |
我个人最看重的是 Renode 的可脚本化能力。你可以用 Python 或 Robot Framework 写测试脚本,自动控制仿真、检查输出、生成报告。这意味着什么?意味着你的测试可以无人值守地跑,每次代码提交都自动验证。
注意:Renode 不是万能的。它不能仿真模拟电路、射频、高精度时序。如果你的项目依赖这些,还是需要真实硬件。但 80% 的嵌入式软件逻辑,Renode 都能搞定。
1.4 知识体系总览
下面这张图,是我对整门课知识结构的梳理。你可以把它当作地图,随时回来看看自己走到哪了。
1.5 开发环境准备
好,理论说完了,咱们动手。先把环境搭起来。
1.5.1 Python 3
Renode 的脚本接口依赖 Python 3。我建议你装 3.8 以上版本。
# 检查是否已安装
python3 --version
# Ubuntu/Debian
sudo apt update
sudo apt install python3 python3-pip
# macOS (Homebrew)
brew install python3
# Windows
# 从 https://www.python.org/downloads/ 下载安装包
# 安装时勾选 "Add Python to PATH"
避坑指南:我曾经在 Windows 上忘记勾选「Add Python to PATH」,结果 Renode 死活找不到 Python。折腾了半小时才发现。嗯,这种低级错误犯一次就够了。
1.5.2 Git
版本控制是 TDD 的基础。每次测试通过后,你都应该提交一次。
# 检查版本
git --version
# Ubuntu/Debian
sudo apt install git
# macOS
brew install git
# Windows
# 从 https://git-scm.com/download/win 下载安装
1.5.3 Renode
这是重头戏。安装方式取决于你的操作系统。
# Linux (推荐使用官方脚本)
wget https://github.com/renode/renode/releases/latest/download/renode_latest_linux_portable.tar.gz
tar -xzf renode_latest_linux_portable.tar.gz
sudo ./renode_*/install.sh
# macOS
brew install renode
# Windows
# 下载 .msi 安装包,双击安装
# 或使用 Chocolatey: choco install renode
安装完成后,验证一下:
renode --version
如果看到版本号,恭喜你,环境搭好了。
1.5.4 依赖工具链
我们还需要一些编译工具链,用来把 C 代码编译成能在 Renode 上运行的二进制文件。
| 工具 | 用途 | 安装命令 (Ubuntu) |
|---|---|---|
| gcc-arm-none-eabi | ARM 交叉编译器 | sudo apt install gcc-arm-none-eabi |
| make | 构建工具 | sudo apt install make |
| cmake | 跨平台构建系统 | sudo apt install cmake |
| gdb-multiarch | 多架构调试器 | sudo apt install gdb-multiarch |
重要提醒:如果你用的是 macOS 或 Windows,ARM 工具链的安装方式略有不同。macOS 可以用 brew install arm-gcc-binutils,Windows 需要从 ARM 官网下载安装包。我会在课程配套的文档里给出详细步骤。
1.6 第一个测试:验证环境
环境搭好了,咱们跑个简单的测试,验证一切正常。
# 创建一个测试目录
mkdir tdd-renode-demo
cd tdd-renode-demo
# 创建一个简单的 C 文件
cat > hello.c << 'EOF'
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(2, 3);
printf("2 + 3 = %d\n", result);
return 0;
}
EOF
# 编译
gcc hello.c -o hello
# 运行
./hello
如果输出 2 + 3 = 5,说明你的本地编译环境没问题。
接下来,试试用 Renode 仿真运行:
# 用 ARM 交叉编译器编译
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -nostartfiles -Ttext=0x0 hello.c -o hello.elf
# 启动 Renode
renode
# 在 Renode 控制台中输入:
# (monitor) mach create
# (monitor) machine LoadPlatformDescription @platforms/cpus/cortex-m3.repl
# (monitor) sysbus LoadELF @hello.elf
# (monitor) showAnalyzer sysbus.uart0
# (monitor) start
嗯,这一步可能有点复杂。别担心,后面几章我会手把手带你熟悉 Renode 的操作。现在你只需要确认工具能跑起来就行。
本章小结
- TDD 的核心是「红-绿-重构」循环,先写测试再写代码
- Renode 能仿真嵌入式硬件,支持脚本化自动化测试
- 环境准备需要 Python 3、Git、Renode 和 ARM 工具链
- 验证环境是否正常:编译一个简单的 C 程序,在本地和 Renode 上分别运行