1. 构建系统与工具链
本仓库包含两套并行的固件构建系统,分别对应不同硬件平台:
ESP32 掌控板(
firmware/port/):基于 MicroPython 官方 ESP32 port,使用自维护的Makefile直接调用 ESP-IDF v4.0.1(通过ESPIDF_SUPHASH_V4 = f56e8baef7fd663d590e6d3b04300066580ea7锁定),交叉编译器为xtensa-esp32-elf-*。构建产物经makeimg.py合并 bootloader/partition/application,再经release.py打包含 VFS、字体的完整固件镜像。ESP32-S3 掌控板 3.0(
esp32s3/firmware/):采用现代 ESP-IDF v5.x(默认v5.5.4,见eim_config.toml)+ CMake 构建,顶层CMakeLists.txt通过MICROPY_BOARD选择板型,自动拼接SDKCONFIG_DEFAULTS列表生成sdkconfig.combined,最终由 IDF 的project.cmake驱动编译,并通过makeimg.py解析分区表生成.bin与.uf2。
文档侧使用 Sphinx(docs/docs/conf.py、esp32s3/docs/conf.py),通过 make html / make.bat 生成中文手册,与固件源码分离。
2. 关键文件与包
ESP32 构建入口:
firmware/port/Makefile(主构建脚本)、firmware/port/makeimg.py(bootloader/partition/app 三合一)、firmware/port/release.py(追加 vfs.bin 与字体到 0x200000/0x400000 偏移)、firmware/port/mpconfigport.h、firmware/port/qstrdefsport.h。ESP32 板级配置:
firmware/port/boards/<board>/mpconfigboard.mk(如mpython/mpconfigboard.mk叠加sdkconfig.base、sdkconfig.240mhz、sdkconfig.ble)、各sdkconfig.*片段、manifest.py(冻结 Python 模块到 flash)。ESP32-S3 构建入口:
esp32s3/firmware/CMakeLists.txt、esp32s3/firmware/esp32_common.cmake、esp32s3/firmware/makeimg.py(解析分区表、生成 bin/uf2、注入 voice_data/srmodels)。ESP32-S3 板级配置:
esp32s3/firmware/boards/<board>/mpconfigboard.cmake(声明IDF_TARGET=esp32s3、SDKCONFIG_DEFAULTS、MICROPY_SOURCE_BOARD、MICROPY_FROZEN_MANIFEST)、partitions-16MiB.csv(定义 factory/vfs/voice_data/model/fr/user_nvs 分区)、sdkconfig.board(音频/GMF AI 语音、BLE、SPIRAM 等 Kconfig 选项)。环境配置:
esp32s3/firmware/eim_config.toml(指定 IDF 路径、工具链版本、镜像源)。发布脚本:
firmware/port/release.py固定偏移(bootloader=0x1000, partitions=0x8000, application=0x10000, vfs=0x200000, font=0x400000),esp32s3/firmware/makeimg.py动态从分区表读取偏移并校验溢出。
3. 架构与约定
3.1 多板型抽象
ESP32:通过
BOARD ?= mpython变量切换boards/<board>/mpconfigboard.mk,Makefile 强制要求目录存在否则报错($(error Invalid BOARD specified))。ESP32-S3:通过
MICROPY_BOARD(默认mpython_v3)选择boards/<board>/mpconfigboard.cmake,支持MICROPY_BOARD_VARIANT变体;每个板型独立sdkconfig.board、partitions-*.csv、manifest.py。
3.2 配置分层
基础配置:
sdkconfig.base提供通用 Kconfig 值。能力开关:
sdkconfig.ble、sdkconfig.240mhz、sdkconfig.spiram、sdkconfig.usb等可组合片段。板专属:
sdkconfig.board集中板级外设(如 S3 的 GMF AI Audio、SR_WN_WN9_NIHAOXIAOZHI_TTS)。构建时拼接:ESP32 在 Makefile 中
SDKCONFIG += ...累加;ESP32-S3 在 CMake 中foreach(SDKCONFIG_DEFAULT ${SDKCONFIG_DEFAULTS})写入sdkconfig.combined.in后复制为sdkconfig.combined。
3.3 固件镜像组装
ESP32:
make all→application.bin+bootloader.bin+partitions.bin→makeimg.py合并 →release.py追加 vfs.bin/font.bin →deploy目标用 esptool 烧录。ESP32-S3:CMake 构建出
micropython.bin+ bootloader + partition-table.bin →makeimg.py先调用mklittlefs打包file_system/<board>为littlefs.bin,再按分区表偏移写入 vfs/voice_data/model 分区,最后对 S3/S2 芯片额外生成.uf2。
3.4 Python 模块冻结策略
ESP32:
boards/manifest.py冻结$(PORT_DIR)/modules与$(BOARD_DIR)/modules。ESP32-S3:
boards/manifest.py额外 includeasyncio、requirebundle-networking、aioespnow、dht、ds18x20、onewire、upysh、collections等标准库。
3.5 依赖与工具链管理
ESP32:通过
ESPIDF_SUPHASH_V3/V4精确锁定 ESP-IDF commit,构建前检查 pyparsing==2.3.1 与 xtensa 工具链是否可用。ESP32-S3:通过
eim_config.toml声明idf_versions=["v5.5.4"]及所需工具集(xtensa/riscv/clang/ninja/openocd),并使用lockfiles/dependencies.lock.${IDF_TARGET}约束组件版本,CI 下若 lockfile 变更则失败。
4. 约定与约束
板型命名:ESP32 板型位于
firmware/port/boards/<name>/,ESP32-S3 板型位于esp32s3/firmware/boards/<name>/,两者互不混用;S3 当前支持mpython_v3、labplus_Ledong_v2、labplus_for_xuejing、labplus_xunfei_js_middle、labplus_xunfei_js_primary五种。Kconfig 不可越权:ESP32 Makefile 显式禁止直接使用
SDKCONFIG变量绕过 board 机制(ifneq ($(SDKCONFIG),) $(error Use the BOARD variable instead of SDKCONFIG))。分区表驱动布局:ESP32-S3 所有偏移来自
partitions-*.csv,makeimg.py通过gen_esp32part.PartitionTable.from_binary()解析,任何手动修改必须同步更新 CSV;构建时会断言offset >= cur_offset防止重叠。VFS 文件系统:ESP32 使用 LFS2(
MICROPY_VFS_LFS2 = 1),通过make_lfs.py将file_system/打包为vfs.bin写入 0x200000;ESP32-S3 同样使用 LittleFS,但额外包含file_system/common/*与<board>/*两个子目录内容。字体资源:ESP32 构建要求外部
Noto_Sans_CJK_SC_Light16.bin置于根目录并写入 0x400000;ESP32-S3 的makeimg.py也引用同名字体文件。版本信息:ESP32 固件名取自
git describe --tags(MICROPY_GIT_TAG);ESP32-S3 的makeimg.py同时提取 git tag、short hash 与 build date 拼入文件名。构建产物隔离:ESP32 输出至
build/<BOARD>/,ESP32-S3 输出至 CMakeBUILD目录(默认build/),避免多板并行冲突。文档与固件解耦:
docs/与esp32s3/docs/仅含 Sphinx 源码与示例代码,不参与固件编译;示例代码位于docs/examples/与esp32s3/firmware/examples/,供用户参考而非构建系统的一部分。