Files

6.5 KiB
Raw Permalink Blame History

sweekar-esp32-gyroscope

English | 中文

项目简介

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 环境。

正常编译、烧录、查看日志

idf.py build flash monitor

当需要自动生成 module.cmake 时

如果你新增了测试目录,或者希望重新触发模块扫描与生成,使用:

idf.py fullclean build flash monitor

说明:

  • 平时正常开发:idf.py build flash monitor
  • 新增测试目录后想自动生成 module.cmake:idf.py fullclean build flash monitor

运行结果示例

如果测试代码运行正常,可以看到类似输出:

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/ 下新建一个文件夹

一个测试功能对应一个目录。

例如新建:

main/tests/add/

或者:

main/tests/load_gyroscope/

2. 在新建的文件夹里写代码

通常至少写两个文件:

  • xxx.h
  • xxx.cc

例如 add 测试模块:

main/tests/add/add.h

int add(int a, int b);

main/tests/add/add.cc

#include "add.h"

int add(int a, int b) {
    return a + b;
}

再例如 load_gyroscope 测试模块:

main/tests/load_gyroscope/load.h

void load();

main/tests/load_gyroscope/load.cc

#include "load.h"
#include <cstdio>
#include <gyroscope.h>

void load() {
    Gyroscope g;
    printf("load OK\n");
}

这个例子用于验证:

  • gyroscope.h 能否正常包含
  • Gyroscope 类能否正常实例化
  • 测试模块能否正确参与链接和运行

3. 在 main/main.cc 里调用测试用例

测试代码写好后,在 main/main.cc 中包含头文件并调用。

main/main.cc

#include "add.h"
#include "load.h"
#include <cstdio>

extern "C" void app_main() {
    load();
    printf("%d\n", add(5, 4));
}

然后编译运行:

idf.py build flash monitor

如果你是第一次新增测试目录,想让工程自动生成对应的 module.cmake,使用:

idf.py fullclean build flash monitor

测试模块的最小结构

推荐每个测试模块至少包含下面 3 个文件:

xxx/
├── xxx.cc
├── xxx.h
└── module.cmake

含义如下:

  • xxx.h:声明接口
  • xxx.cc:实现测试逻辑
  • module.cmake:把这个模块注册进构建系统

module.cmake 怎么来

当你在 main/tests/ 下新增一个测试目录时,工程可以自动为它生成 module.cmake。

例如你先新建:

main/tests/load_gyroscope/
├── load.cc
└── load.h

执行:

idf.py fullclean build flash monitor

之后目录会变成:

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 中定义:

set(SUBSYSTEM_DIRS 
    "04_hal"
    "05_executors"
    "05_service"
    "06_behaviors"
    "tests"
)

第二步:扫描每个子目录下的 module.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(...)

最后统一注册:

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

这样就可以快速验证模块是否正常编译和运行。