4.5 KiB
4.5 KiB
#领域/未知
#复盘/0 #临时/备忘 #状态/待处理
20260528-备忘-主题名-文件内容
一句话描述
[________]
🔥 MicroPython ESP32 自定义内置 C 模块 完整标准流程
(适配你的 ESP32-S3,零报错、可直接复用,总结所有实操步骤)
一、核心前提
我们做的是 编译进固件的 C 语言内置模块(性能高、可直接 import)
开发目录固定:
plaintext
micropython/ports/esp32/
二、标准 5 步流程(必看)
步骤 1:创建模块文件
在 ports/esp32/ 下新建 C 文件,命名规则:
mod+模块名.c
例:modsayhello.c
步骤 2:编写模块代码(固定万能模板)
直接复制,修改函数即可,无报错、适配所有 ESP32
#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:烧录 + 测试
- 烧录固件
bash
运行
esptool.py --chip esp32s3 --port /dev/ttyUSB0 write_flash -z 0x1000 firmware.bin
- 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) |
四、添加多个函数(极简流程)
- 写函数 → 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) },
五、实战避坑(你踩过的所有坑)
STATIC报错:用 C 原生static替代- 编译失败:必须执行
make clean清理缓存 - 函数重复定义:一个函数只能写一个注册宏
- 文件不生效:确认
esp32_common.cmake文件名拼写正确 - 模块找不到:确认
MP_REGISTER_MODULE模块名一致
六、一句话总结
创建 modxxx.c → 写函数 → 注册到 CMake → 清理编译 → 烧录测试
这就是 MicroPython ESP32 自定义 C 模块的完整标准流程!