--- #领域/未知 #复盘/0 #临时/备忘 #状态/待处理 20260528-备忘-主题名-文件内容 ## 一句话描述 [________] --- # 🔥 MicroPython ESP32 自定义**内置 C 模块** 完整标准流程 (适配你的 ESP32-S3,零报错、可直接复用,总结所有实操步骤) ## 一、核心前提 我们做的是 **编译进固件的 C 语言内置模块**(性能高、可直接 import) 开发目录固定: plaintext ``` micropython/ports/esp32/ ``` --- ## 二、标准 5 步流程(必看) ### 步骤 1:创建模块文件 在 `ports/esp32/` 下新建 C 文件,命名规则: `mod+模块名.c` 例:`modsayhello.c` --- ### 步骤 2:编写模块代码(固定万能模板) 直接复制,修改函数即可,**无报错、适配所有 ESP32** ```c #include "py/obj.h" #include "py/runtime.h" // ====================== 函数1:无参数 hello() ====================== static mp_obj_t sayhello_hello(void) { mp_printf(&mp_plat_print, "Hello from ESP32-S3!\n"); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_0(sayhello_hello_obj, sayhello_hello); // ====================== 函数2:带1个参数 hello(name) ====================== static mp_obj_t sayhello_hello_name(mp_obj_t name) { const char *str = mp_obj_str_get_str(name); mp_printf(&mp_plat_print, "Hello %s!\n", str); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(sayhello_hello_name_obj, sayhello_hello_name); // ====================== 函数3:带2个参数 add(a,b) ====================== static mp_obj_t sayhello_add(mp_obj_t a_obj, mp_obj_t b_obj) { int a = mp_obj_get_int(a_obj); int b = mp_obj_get_int(b_obj); return mp_obj_new_int(a + b); // 返回计算结果 } static MP_DEFINE_CONST_FUN_OBJ_2(sayhello_add_obj, sayhello_add); // ====================== 把所有函数注册到模块 ====================== static const mp_rom_map_elem_t sayhello_module_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sayhello) }, // 在这里添加函数! { MP_ROM_QSTR(MP_QSTR_hello), MP_ROM_PTR(&sayhello_hello_obj) }, { MP_ROM_QSTR(MP_QSTR_hello_to), MP_ROM_PTR(&sayhello_hello_name_obj) }, { MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&sayhello_add_obj) }, }; static MP_DEFINE_CONST_DICT(sayhello_module_dict, sayhello_module_table); const mp_obj_module_t sayhello_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&sayhello_module_dict, }; MP_REGISTER_MODULE(MP_QSTR_sayhello, sayhello_module); ``` --- ### 步骤 3:添加到编译列表(关键) 打开文件:`ports/esp32/esp32_common.cmake` 找到 `MICROPY_SOURCE_PORT` 列表,**添加你的 C 文件**: cmake ``` list(APPEND MICROPY_SOURCE_PORT # ... 其他文件不变 modsayhello.c # 新增这一行 ) ``` --- ### 步骤 4:编译固件(必须清理缓存) bash 运行 ``` # 进入目录 cd micropython/ports/esp32 # 清理旧缓存(必做!) make BOARD=ESP32_GENERIC_S3 clean # 编译固件 make BOARD=ESP32_GENERIC_S3 ``` 编译成功后,固件位置: plaintext ``` build-ESP32_GENERIC_S3/firmware.bin ``` --- ### 步骤 5:烧录 + 测试 1. 烧录固件 bash 运行 ``` esptool.py --chip esp32s3 --port /dev/ttyUSB0 write_flash -z 0x1000 firmware.bin ``` 1. REPL 测试 python 运行 ``` import 模块名 模块名.函数() ``` --- ## 三、函数参数规则(万能记忆) 表格 |参数个数|注册宏|示例| |---|---|---| |0 个参数|MP_DEFINE_CONST_FUN_OBJ_0|无参数 hello ()| |1 个参数|MP_DEFINE_CONST_FUN_OBJ_1|带名字 hello (name)| |2 个参数|MP_DEFINE_CONST_FUN_OBJ_2|加法 add (a,b)| --- ## 四、添加多个函数(极简流程) 1. 写函数 → 2. 注册宏 → 3. 加入模块表 c 运行 ``` // 新增函数 static mp_obj_t test_add(mp_obj_t a, mp_obj_t b) { return mp_obj_new_int(mp_obj_get_int(a)+mp_obj_get_int(b)); } static MP_DEFINE_CONST_FUN_OBJ_2(test_add_obj, test_add); // 加入模块表 { MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&test_add_obj) }, ``` --- ## 五、实战避坑(你踩过的所有坑) 1. **`STATIC` 报错**:用 C 原生 `static` 替代 2. **编译失败**:必须执行 `make clean` 清理缓存 3. **函数重复定义**:一个函数只能写一个注册宏 4. **文件不生效**:确认 `esp32_common.cmake` 文件名拼写正确 5. **模块找不到**:确认 `MP_REGISTER_MODULE` 模块名一致 --- ## 六、一句话总结 创建 `modxxx.c` → 写函数 → 注册到 CMake → 清理编译 → 烧录测试 **这就是 MicroPython ESP32 自定义 C 模块的完整标准流程!**