Files
sweekar-esp32-gyroscope/main/MODULE_DEVELOPMENT_GUIDE.md
T

5.9 KiB
Raw Blame History

Sweekar-ESP32 模块化开发与构建系统指南

为了支持多人无冲突协作,并保持系统代码的高内聚、低耦合,Sweekar-ESP32 的 CMake 构建系统采用 “透明化脚手架 (Transparent Scaffolding) + Kconfig 自动组装” 架构。

在这套架构下,开发者在添加新的底层硬件驱动、业务服务或测试代码时,完全不需要修改任何顶层文件(包括 main/CMakeLists.txt 和 main/Kconfig.projbuild),构建系统会自动帮你生成必要的模板文件,而后续的修改则完全交由你掌控,没有任何“黑魔法”。

以下是添加新模块的标准流程和机制说明。


1. 确定模块归属的目录分类

系统顶层会自动扫描以下目录下的子文件夹:

  • 04_hal/ : 硬件抽象层代码(如 Codec 驱动、马达驱动等)
  • 05_executors/ : 执行器组件(如 AudioPlayer, Display, 传感器读取等)
  • 05_service/ : 后台服务组件(如 AI RTC、QCloud、WiFi 连接等)
  • 06_behaviors/ : 行为逻辑组件
  • tests/ : 各种测试模块(如麦克风测试、扬声器测试等)
  • sweekar_demos/ : 各种组装好的 Demo 入口

假设我们要添加一个专门测试麦克风的模块,名为 test_mic,它显然应该归属于 tests/ 目录。

2. 新建模块与文件 (自动化部分)

在对应的分类下新建文件夹,并将你的源码和头文件放进去:

mkdir -p main/tests/test_mic
touch main/tests/test_mic/test_mic.cc
touch main/tests/test_mic/test_mic.h

【核心自动化机制】 此时,你不需要手动去写 CMake 文件。你只需要在终端执行一次:

idf.py reconfigure

(或者 idf.py build 如果这是你第一次编译该工程)。

构建系统中的 Python 脚本 (generate_kconfig_modules.py) 会在配置阶段自动扫描目录。当它发现 tests/test_mic 目录下有源码但没有 module.cmake 时,它会自动为你生成一个 module.cmake 脚手架文件。

自动生成的文件内容类似于:

# main/tests/test_mic/module.cmake
# 自动生成的模块脚手架,可直接手工修改。
# 如果后续添加了新文件,可以手工在此处添加,或者删除本文件让脚本重新生成。

if(NOT CONFIG_ENABLE_TEST_TEST_MIC AND NOT EARLY_EXPANSION)
    message(STATUS "  [Skip] test_mic module disabled by menuconfig.")
    return()
endif()

list(APPEND MODULE_SRCS
    "tests/test_mic/test_mic.cc"
)

list(APPEND MODULE_INCLUDE_DIRS
    "tests/test_mic"
)

# 需要公开依赖时,在这里手工补充。例如:
# list(APPEND MODULE_REQUIRES
#     esp_timer
#     driver
# )

3. 后续维护与修改 (手工部分)

“透明化”原则:一旦 module.cmake 被生成,Python 脚本就再也不会覆盖或修改它。它现在完全属于你。

3.1 当你新增/删除源文件时

你有两种选择:

  1. 手动修改(推荐):直接打开 module.cmake,在 list(APPEND MODULE_SRCS ...) 中手动添加或删除文件路径。所见即所得,非常直观。
  2. 重新生成(偷懒大法):如果你一口气加了十几个文件,不想手写路径,你可以直接删除这个 module.cmake 文件,然后运行 idf.py reconfigure,脚本会重新帮你扫描并生成一份包含所有最新文件的脚手架。

3.2 当你需要依赖其他库时

直接在 module.cmake 底部,取消注释并填入你需要的 ESP-IDF 组件名(如 esp_adc, audio_pipeline 等):

list(APPEND MODULE_REQUIRES
    audio_pipeline
    driver
)

4. 编写模块内部的 Kconfig (可选)

系统会自动为你的模块生成一个默认的配置开关(例如 CONFIG_ENABLE_TEST_TEST_MIC)。

  • tests/ 目录下的默认开关为关闭(default n)。
  • 其他目录默认开启(default y)。

如果你需要为你的模块定义更复杂的配置选项(比如定义默认开启、依赖其他模块、或者包含子菜单),你可以在模块目录(main/tests/test_mic/)下建立一个名为 Kconfig 的文件:

# main/tests/test_mic/Kconfig
config ENABLE_TEST_MIC
    bool "Enable Microphone Test Module"
    default n
    help
        Enable this to compile the microphone testing routines.

系统如果扫描到模块自带 Kconfig,就会使用你写的,而不再自动生成默认开关。

5. 编译与配置

  1. 运行 idf.py menuconfig。
  2. 导航到 Sweekar Subsystems Configuration -> 对应的目录(如 Tests Modules)。
  3. 找到你刚刚添加的 Enable test_mic(或你自己定义的开关名字),按空格键勾选 [*]。
  4. 保存退出后,运行 idf.py build 即可!

⚠️ 常见问题与注意事项

Q: 为什么我新建了一个文件夹或者删除了 module.cmake,运行 idf.py build 没有反应?

这是 CMake 的缓存机制导致的。如果你只是增删了目录或文件,但没有修改任何现有的 CMakeLists.txt 内容,CMake 会跳过配置阶段直接去编译,导致 Python 扫描脚本没有运行。 解决办法:遇到这种情况,请明确告诉 IDF 重新配置:

idf.py reconfigure

然后再运行 idf.py build。

Q: 为什么要加 NOT EARLY_EXPANSION?

ESP-IDF 的构建系统分为两步:

  1. 依赖解析阶段 (Early Expansion):此时 CMake 快速扫描所有组件收集 REQUIRES,但此时 menuconfig 的配置尚未加载,所有的 CONFIG_xxx 都是空值!
  2. 实际构建阶段 (Build Pass):此时配置加载完毕,开始真实编译。

如果在 module.cmake 顶部仅仅写 if(NOT CONFIG_ENABLE_XXX) return(),会导致在依赖解析阶段该模块就被错误地跳过了,从而丢失其依赖声明,引发“找不到头文件”的编译灾难。 加入 AND NOT EARLY_EXPANSION 后,能保证所有启用的组件依赖都被正确收集到构建树中,实现完美解耦。