1. 使用的系统与工具

本仓库同时维护两套固件(firmware/port/ 基于 ESP32 MicroPython port;esp32s3/firmware/ 基于 ESP-IDF v5.x + MicroPython v1.24.1)以及 Sphinx 文档,因此存在三套并行的依赖声明机制:

  • ESP-IDF Component Manager(idf_component.yml):用于 esp32s3/firmware 的 C/C++ 组件依赖,通过 espressif/xxx 命名空间从 Espressif 官方组件仓库拉取。

  • MicroPython frozen manifest(manifest.py / mpconfigboard.mk):用于将 Python 模块编译进固件镜像(frozen bytecode),控制运行时可用的标准库与第三方包。

  • Sphinx 文档依赖(docs/requirements.txt):锁定构建文档所需的 Python 包版本。

此外,esp32s3/firmware/eim_config.toml 使用 EIM(Espressif Install Manager)配置 IDF 工具链、Python 环境及 PyPI 镜像源(清华 tuna),实现本地化下载加速。

2. 关键文件与位置

层次

关键文件

作用

S3 固件顶层

esp32s3/firmware/main/idf_component.yml

声明 ESP-IDF 组件依赖(mdns、tinyusb、esp-sr、esp_audio_codec、esp_video_codec、esp32-camera、joltwallet/littlefs、esp_websocket_client 等)

S3 自定义组件

esp32s3/firmware/components/esp_lcd_jd9853/idf_component.yml

屏幕驱动组件,声明对 cmake_utilities 和 idf >= 4.4 的依赖

S3 代码生成组件

esp32s3/firmware/components/gen_bmgr_codes/idf_component.yml

依赖 compents/esp_lcd_jd9853: 2.0.2

S3 板级 manifest

esp32s3/firmware/boards/*/manifest.py

通过 include("$(PORT_DIR)/boards/manifest.py") 复用基础包集合,再 freeze("modules") 引入板载 Python 模块

S3 基础 manifest

esp32s3/firmware/boards/manifest.py

启用 bundle-networking、aioespnow、dht、ds18x20、onewire、upysh、collections 等 MicroPython 包

ESP32 端口 manifest

firmware/port/boards/manifest.py

冻结 $(PORT_DIR)/modules 与 $(BOARD_DIR)/modules 到固件

文档依赖

esp32s3/docs/requirements.txt

锁定 Sphinx、Jupyter、PyQt、NumPy 等 276 个包的精确版本

工具链配置

esp32s3/firmware/eim_config.toml

指定 IDF 路径、工具链目录、PyPI 镜像(https://pypi.tuna.tsinghua.edu.cn/simple)、IDF 镜像(https://jihulab.com/esp-mirror)

构建脚本

firmware/port/Makefile

强制要求 ESPIDF 环境变量指向受支持的 git hash(v3.3.2 或 v4.0.1),并通过 make submodules 初始化子模块

3. 架构与约定

3.1 组件来源分层

  • 官方组件:通过 espressif/xxx 命名空间引用,版本号采用语义化约束(~1.1.0、^2.0、==1.5.4、>=5.2.0 等)。例如 espressif/mdns: ~1.1.0、espressif/esp32-camera: ^2.0。

  • Git 分支覆盖:tinyusb 通过 git: https://github.com/micropython/tinyusb-espressif.git + version: cherrypick/dwc2_zlp_fix 临时绕过 upstream issue #3154,体现“以补丁分支替代上游版本”的策略。

  • 本地 override_path:GMF(Graphics & Multimedia Framework)相关组件(gmf_loader、gmf_app_utils、esp_capture、esp_board_manager、gmf_core、gmf_io、gmf_audio、gmf_ai_audio、gmf_video、gmf_misc、esp_audio_render)全部通过 override_path: ../../esp-gmf/... 指向外部 Git 子模块,不经过组件仓库。

  • 第三方组件:joltwallet/littlefs: ==1.20.4 作为文件系统后端被精确锁定。

3.2 MicroPython 包冻结策略

  • 基础网络栈通过 require("bundle-networking") 批量引入。

  • 传感器/通信协议(dht、ds18x20、onewire、aioespnow)通过 require() 显式声明。

  • 板级 Python 模块通过 freeze("modules") 将 esp32s3/firmware/modules/ 中的 .py 文件编译进固件,形成运行时可用模块(如 ai_cloud.py、ATGM336H_5N.py、neopixel.py、weather.py、xunfei.py 等)。

  • ESP32 端口(firmware/port/)同样通过 manifest.py 冻结 port/modules 与 port/boards/<board>/modules。

3.3 文档依赖锁定

esp32s3/docs/requirements.txt 是典型的 pip freeze 产物,包含 276 行精确版本(如 Sphinx @ file:///...、PyQt==1.9.0、numpy @ file:///...),其中大量条目使用 @ file:/// 形式指向 CI 构建缓存中的 wheel,说明该文件主要用于 CI 复现而非开发者本地安装。实际开发中应配合 python -m venv 与 pip install -r requirements.txt 使用。

3.4 工具链与镜像

eim_config.toml 明确配置了国内镜像:

  • mirror = "https://dl.espressif.cn/github_assets"

  • idf_mirror = "https://jihulab.com/esp-mirror"

  • pypi_mirror = "https://pypi.tuna.tsinghua.edu.cn/simple"

这确保 IDF 工具链、Python 包和 GitHub Assets 均从国内镜像下载,提升构建速度。

4. 约定与约束

  • ESP-IDF 版本锁定:firmware/port/Makefile 通过 ESPIDF_SUPHASH_V3 / ESPIDF_SUPHASH_V4 硬编码受支持的 IDF commit hash,并在构建时校验当前 IDF 的 git hash,不匹配则输出 WARNING 并继续(非致命错误)。

  • Python 版本约束:ESP32 端口要求 pyparsing==2.3.1(<2.4),否则直接报错退出;S3 端口在 eim_config.toml 中指定 python_version_override = "python313"。

  • 子模块管理:README 明确要求 git clone --recursive 与 make submodules,GMF 相关组件通过 override_path 指向外部 esp-gmf 子模块,需独立维护。

  • 私有/本地组件隔离:所有 GMF 组件通过 override_path 指向本地路径,避免混入公共组件仓库,便于内部迭代。

  • upip 未启用:manifest.py 中 upip.py 的 freeze 调用被注释掉,表明固件不包含远程包管理器,依赖需在构建期冻结进镜像。

  • 无 vendored 第三方源码:除 lib/decode_png、lib/utils 等少量自研 lib 外,未发现 vendor/ 目录;第三方 C 组件一律通过 ESP-IDF Component Manager 拉取。

  • 文档与固件解耦:docs/requirements.txt 仅用于 Sphinx 构建,不影响固件编译;固件依赖集中在 idf_component.yml 与 manifest.py 两个文件中。