# sweekar-esp32-gyroscope [English](README.md) | [中文](README_CN.md) ## 项目简介 `sweekar-esp32-gyroscope` 是一个基于 **ESP-IDF** 的模块化嵌入式工程。 这个仓库是从原始 `sweekar-esp32` 工程中精简出来的版本,当前主要保留了 **gyroscope(陀螺仪)相关功能**,用于独立开发、裁剪验证和测试。 工程仍然保留了原项目的模块化结构,方便后续继续扩展板级驱动、HAL 模块、执行器模块和测试代码。 --- ## 目录说明 ### `main/02_physical/boards` 板级相关代码。 这里放和具体板子强相关的内容,例如板卡定义、板级初始化、IO 扩展、板级配置。 ### `main/04_hal` 硬件抽象层(HAL)。 这里放和板子驱动有关的基础模块,例如: - `audio_codec` - `base_board_hal` - `stepper_driver` ### `main/05_executors` 执行器 / 功能模块层。 当前这个精简工程里,主要保留: - `gyroscope`:陀螺仪驱动代码 ### `main/tests` 测试模块目录。 这里用于编写测试用例,验证某个模块能否正常包含、编译、链接和运行。 --- ## 怎么运行 先确保已经正确安装并导出 **ESP-IDF** 环境。 ### 正常编译、烧录、查看日志 ```bash idf.py build flash monitor ``` ### 当需要自动生成 `module.cmake` 时 如果你新增了测试目录,或者希望重新触发模块扫描与生成,使用: ```bash idf.py fullclean build flash monitor ``` 说明: * 平时正常开发:`idf.py build flash monitor` * 新增测试目录后想自动生成 `module.cmake`:`idf.py fullclean build flash monitor` --- ## 运行结果示例 如果测试代码运行正常,可以看到类似输出: ```text I (600) main_task: Calling app_main() load OK 9 I (604) main_task: Returned from app_main() ``` 这说明: * `load_gyroscope` 测试模块运行成功 * `Gyroscope` 可以正常实例化 * `add` 测试模块也正常运行,输出结果为 `9` --- ## 怎么创建测试用例 创建测试用例的流程很简单: ### 1. 先在 `main/tests/` 下新建一个文件夹 一个测试功能对应一个目录。 例如新建: ```text main/tests/add/ ``` 或者: ```text main/tests/load_gyroscope/ ``` --- ### 2. 在新建的文件夹里写代码 通常至少写两个文件: * `xxx.h` * `xxx.cc` 例如 `add` 测试模块: #### `main/tests/add/add.h` ```cpp int add(int a, int b); ``` #### `main/tests/add/add.cc` ```cpp #include "add.h" int add(int a, int b) { return a + b; } ``` 再例如 `load_gyroscope` 测试模块: #### `main/tests/load_gyroscope/load.h` ```cpp void load(); ``` #### `main/tests/load_gyroscope/load.cc` ```cpp #include "load.h" #include #include void load() { Gyroscope g; printf("load OK\n"); } ``` 这个例子用于验证: * `gyroscope.h` 能否正常包含 * `Gyroscope` 类能否正常实例化 * 测试模块能否正确参与链接和运行 --- ### 3. 在 `main/main.cc` 里调用测试用例 测试代码写好后,在 `main/main.cc` 中包含头文件并调用。 #### `main/main.cc` ```cpp #include "add.h" #include "load.h" #include extern "C" void app_main() { load(); printf("%d\n", add(5, 4)); } ``` 然后编译运行: ```bash idf.py build flash monitor ``` 如果你是**第一次新增测试目录**,想让工程自动生成对应的 `module.cmake`,使用: ```bash idf.py fullclean build flash monitor ``` --- ## 测试模块的最小结构 推荐每个测试模块至少包含下面 3 个文件: ```text xxx/ ├── xxx.cc ├── xxx.h └── module.cmake ``` 含义如下: * `xxx.h`:声明接口 * `xxx.cc`:实现测试逻辑 * `module.cmake`:把这个模块注册进构建系统 --- ## `module.cmake` 怎么来 当你在 `main/tests/` 下新增一个测试目录时,工程可以自动为它生成 `module.cmake`。 例如你先新建: ```text main/tests/load_gyroscope/ ├── load.cc └── load.h ``` 执行: ```bash idf.py fullclean build flash monitor ``` 之后目录会变成: ```text main/tests/load_gyroscope/ ├── load.cc ├── load.h └── module.cmake ``` 所以流程就是: 1. 先建测试目录 2. 再写 `.h` 和 `.cc` 3. 执行 `idf.py fullclean build flash monitor` 4. 自动生成 `module.cmake` 5. 在 `main/main.cc` 中调用测试代码 --- ## 自动添加代码文件到 CMake 的原理 这个工程不是手工在 `main/CMakeLists.txt` 里一条条写死所有 `.cc` 文件,而是通过扫描各模块目录下的 `module.cmake` 自动收集源码和头文件目录。 ### 第一步:定义要扫描的目录 在 `main/CMakeLists.txt` 中定义: ```cmake set(SUBSYSTEM_DIRS "04_hal" "05_executors" "05_service" "06_behaviors" "tests" ) ``` --- ### 第二步:扫描每个子目录下的 `module.cmake` ```cmake foreach(dir ${SUBSYSTEM_DIRS}) file(GLOB MODULE_FILES "${CMAKE_CURRENT_LIST_DIR}/${dir}/*/module.cmake") foreach(mod_file ${MODULE_FILES}) include(${mod_file}) endforeach() endforeach() ``` 也就是说,主工程会自动去找各个模块自己的 `module.cmake`。 --- ### 第三步:每个模块把自己的信息追加进去 每个模块自己的 `module.cmake` 会把内容追加到这些全局变量里: * `MODULE_SRCS` * `MODULE_INCLUDE_DIRS` * `MODULE_REQUIRES` * `MODULE_PRIV_REQUIRES` 例如测试模块会把: * `tests/add/add.cc` * `tests/add` 加进去。 --- ### 第四步:统一交给 `idf_component_register(...)` 最后统一注册: ```cmake idf_component_register( SRCS "main.cc" ${MODULE_SRCS} INCLUDE_DIRS "." ${MODULE_INCLUDE_DIRS} REQUIRES ${MODULE_REQUIRES} PRIV_REQUIRES ${MODULE_PRIV_REQUIRES} ) ``` 所以本质上就是: **主工程自动扫描所有模块的 `module.cmake`,每个模块自己声明要参与编译的文件,最后统一汇总到 `idf_component_register(...)`。** --- ## 总结 这个仓库的定位是: * `sweekar-esp32` 的精简版 * 当前主要保留 `gyroscope` 相关代码 * 支持在 `main/tests/` 下快速新增测试模块 新增测试用例时,按下面流程做即可: 1. 在 `main/tests/` 下新建一个文件夹 2. 在新文件夹里写 `.h` 和 `.cc` 3. 首次新增目录时执行 `idf.py fullclean build flash monitor` 自动生成 `module.cmake` 4. 在 `main/main.cc` 中调用测试代码 5. 后续正常开发执行 `idf.py build flash monitor` 这样就可以快速验证模块是否正常编译和运行。