开发规范
大约 6 分钟
代码修改规范
本文面向 FastBee-Arduino 固件、Web 控制台和测试脚本的维护者。目标是减少“修好一处又破坏另一处”的回归,保证 Lite、Standard、Full 三个档位在不同芯片上的长期稳定运行。
修改前影响分析
调用链检查
修改任何函数、配置结构或 API 前,先搜索所有调用点:
1. 搜索函数名、配置字段、API 路径或宏名。
2. 检查调用方是否依赖返回值、副作用、状态变化或错误码。
3. 判断是否需要同步修改测试、默认配置、Web UI、文档和版本能力接口。例如修改 NetworkManager::startAPMode() 时,要同时看 initialize()、attemptReconnect()、handle()、ProtocolManager、WiFiManager 和 Web 网络状态页,避免 WiFi 模式切换影响 MQTT 状态机或配网页面。
状态机评估
涉及网络、MQTT、OTA、外设执行、认证或配置保存时,必须列出修改前后的关键状态流。状态机改动不要只看“成功路径”,还要覆盖连接中、失败、超时、恢复、低内存和重启后的状态。
修改前:STA -> AP+STA -> STA -> AP+STA(可能震荡)
修改后:STA -> AP(终止重试并保留配网入口)
同步影响:自动重连、MQTT 断开、仪表盘状态、日志告警跨模块依赖
| 模块关系 | 关注点 |
|---|---|
NetworkManager ↔ WiFiManager | WiFi 模式、STA/AP 状态、重连策略 |
NetworkManager → ProtocolManager | 网络就绪后 MQTT/Modbus 初始化和恢复 |
ProtocolManager → Web/API | MQTT/Modbus 状态、配置保存、错误码 |
HealthMonitor → 网络/Web/SSE | 低内存降级、连接清理、日志节流 |
WebConfigManager → 所有模块 | REST API 路由、认证、配置读写 |
多芯片兼容
| 芯片 | 约束 |
|---|---|
| ESP32 | 4MB 环境空间紧张,串口默认 UART0 |
| ESP32-S3 | PSRAM 可缓解大对象分配,但 RMT/红外等驱动需单独验证 |
| ESP32-C3 | RAM 最紧张,Lite 预设优先 |
| ESP32-C6 | 依赖库支持不同,OneWire/DallasTemperature 等需检查 |
凡是涉及内存分配、任务栈、库依赖、串口、RMT、USB-CDC、PSRAM 或 lib_ignore 的修改,都必须跑对应芯片环境编译。
修改中编码约束
防御性编码
- 状态判断要覆盖中间态,例如 connecting、disconnecting、failed、low-memory。
- 外部输入、JSON 字段、配置数组和引脚列表都要做边界校验。
- 高频路径避免临时
String拼接、大对象 JSON 和频繁new/delete。
if (currentStatus != WL_DISCONNECTED) {
WiFi.disconnect(false);
delay(100);
}资源清理
- WiFi 模式切换前后确认是否需要
WiFi.disconnect()和重连任务停止。 new、malloc、文件句柄、任务、定时器和回调注册必须有释放或注销路径。- 优先使用 RAII、静态池、预分配缓存和明确的失败返回。
日志分级
static unsigned long lastLog = 0;
if (millis() - lastLog > 30000) {
lastLog = millis();
Serial.printf("[MODULE] Status info\n");
}
LOG_ERROR("NetworkManager: Failed to start AP mode");- 高频路径使用节流日志。
- 一次性事件用 INFO。
- 错误和异常用 ERROR/WARN,并保留足够上下文。
- 生产构建默认保持
FASTBEE_STRIP_INFO_LOGS=1、FASTBEE_DEBUG_LOG=0。
类型与接口安全
- 跨抽象层调用时确认接口是否属于基类,必要时使用显式转换并检查空指针。
- API 响应字段新增、删除或语义变化时,同步 Web UI、测试矩阵和文档。
- 配置结构新增字段时,同步默认配置、迁移逻辑、导入导出和恢复出厂设置。
前端样式
- 优先复用
web-src/css/main.css中的.fb-*组件类和设计令牌。 - 页面内样式只用于当前页面确实需要的局部覆盖。
- 修改前端后必须验证 gzip 产物体积和静态资源完整性。
修改后验证矩阵
统一入口是 scripts/test-all.ps1。按改动风险选择检查项,影响共享模块、配置、网络、协议或 Web/API 时不要只跑单环境。
| 检查 | 命令 | 覆盖内容 |
|---|---|---|
| 静态检查 | scripts/test-all.ps1 -Checks static | UTF-8、测试注册、API 矩阵、默认配置、Web 静态资源等 |
| native 单元测试 | scripts/test-all.ps1 -Checks native | host 侧 C++ 单元测试 |
| 多芯片编译 | scripts/test-all.ps1 -Checks build | ESP32、C3、C6、S3 的发布环境 |
| 发布产物 | scripts/test-all.ps1 -Checks artifacts | 合并固件、LittleFS、manifest |
| 设备冒烟 | `scripts/test-all.ps1 -Checks device-smoke -BaseUrl http://<设备IP> -DeviceProfile <lite | standard |
| 设备浸泡 | scripts/test-all.ps1 -Checks device-soak -BaseUrl http://<设备IP> -DeviceProfile full -SoakRounds 100 | API 循环、内存趋势、认证稳定性和响应耗时 |
常用本地命令:
# 快速提交前检查
powershell -ExecutionPolicy Bypass -Command ".\scripts\test-all.ps1 -Checks static,build"
# 完整本地矩阵,不访问真实设备
powershell -ExecutionPolicy Bypass -Command ".\scripts\test-all.ps1 -Checks static,native,build,artifacts"
# 单个 native 测试
pio test -e native -f test_web_api高风险修改清单
| 类型 | 风险 | 必查项 |
|---|---|---|
| WiFi 模式切换 | 栈溢出、状态震荡、配网入口丢失 | 禁止无约束 AP+STA 震荡;模式切换前清理状态 |
| MQTT 连接管理 | 断网时无意义重试、内存消耗、阻塞主循环 | isNetworkConnected() 门控、退避重连、低内存暂停 |
| 内存分配 | 堆碎片、最大连续块不足、任务栈溢出 | 大对象优先 PSRAM、低内存降级、避免高频分配 |
platformio.ini 依赖 | 未用库被编译、Flash 膨胀、芯片不兼容 | 检查 lib_deps、lib_ignore、宏和多芯片编译 |
| Web/API 字段 | 前端显示异常、测试矩阵失配、旧配置不兼容 | 同步 UI、默认配置、导入导出、API 测试 |
| OTA/文件系统 | 断电损坏、分区不匹配、恢复失败 | 断电恢复、校验失败、旧固件回退路径 |
回归测试规范
每次修复 Bug 都应补对应测试。测试文件按模块组织,并在 test/run_tests.cpp 或当前测试入口注册。
| Bug 类型 | 测试建议 |
|---|---|
| 逻辑错误 | 行为单元测试或源码回归测试 |
| 状态机错误 | 状态转换模拟测试 |
| 内存问题 | 堆阈值、低内存保护或长稳测试 |
| 配置错误 | 默认配置、导入导出、非法字段测试 |
| 多模块协作 | E2E 场景测试 |
| 性能退化 | 性能基准或 soak 指标 |
新增设备 API 时,必须同步 scripts/device-api-test-matrix.json,并至少跑一次对应档位的 smoke。
Git 提交要求
- 一个提交解决一个问题,修复和对应测试放在同一个提交中。
- 提交信息使用 Conventional Commits,例如
fix(network): STA 失败后回退纯 AP 模式。 - 提交正文写清楚根因、改动点、验证命令和影响范围。
- 不把无关格式化、文档同步和功能修复混在一个提交里。
AI 辅助开发注意事项
- 提需求时优先给出现象、日志、期望行为和复现步骤。
- 审核修改时检查调用点、状态机、日志格式、测试和文档是否同步。
- AI 不能替代硬件验证;WiFi、MQTT、内存趋势、多设备并发和具体传感器兼容性仍需真机确认。
