Hi3861下移植micropython无法引入freeze程序的解决方法 原创
再见南丫岛
发布于 2022-2-27 19:35
浏览
0收藏
最近在移植micropython到海思Hi3861芯片,基本框架已经完成。现在在研究http的访问,需要urequest.py库。直接在文件系统下存储该文件,然后引用该py库是没有问题的,但是不能freeze之后打包进固件中。于是研究了一下源码,现把解决的思路整理一下,仅供参考。
1、需要启用MICROPY_MODULE_FROZEN宏。
#define MICROPY_MODULE_FROZEN (1)
#define MICROPY_MODULE_FROZEN_MPY (1)
#define MICROPY_MODULE_FROZEN_STR (1)
2、添加manifest.py文件,用于freeze哪个py文件。
3、makefile中添加FROZEN的路径,也就是第二部的文件。
freeze(".", "ssd1306.py")
freeze(".", "_boot.py")
freeze(".", "urequests.py")
freeze(".", "logging.py")
freeze(".", "umqtt.py")
freeze(".", "uasyncio.py")
4、在py.mk中会编译该文件,编译成frozen_content.o
# object file for frozen code specified via a manifest
ifneq ($(FROZEN_MANIFEST),)
PY_O += $(BUILD)/$(BUILD)/frozen_content.o
endif
# object file for frozen files
ifneq ($(FROZEN_DIR),)
PY_O += $(BUILD)/$(BUILD)/frozen.o
endif
# object file for frozen bytecode (frozen .mpy files)
ifneq ($(FROZEN_MPY_DIR),)
PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o
endif
5、编译后会生成frozencontent.c文件。问题就从这里出现。此处自动生成的mpy_names中只有文件名,没有路径。
const char mp_frozen_mpy_names[] = {
"ssd1306.py\0"
"_boot.py\0"
"urequests.py\0"
"logging.py\0"
"umqtt.py\0"
"uasyncio.py\0"
"\0"};
const mp_raw_code_t *const mp_frozen_mpy_content[] = {
&raw_code_ssd1306__lt_module_gt_,
&raw_code__boot__lt_module_gt_,
&raw_code_urequests__lt_module_gt_,
&raw_code_logging__lt_module_gt_,
&raw_code_umqtt__lt_module_gt_,
&raw_code_uasyncio__lt_module_gt_,
};
#ifdef MICROPY_FROZEN_LIST_ITEM
MICROPY_FROZEN_LIST_ITEM("ssd1306", "ssd1306.py")
MICROPY_FROZEN_LIST_ITEM("_boot", "_boot.py")
MICROPY_FROZEN_LIST_ITEM("urequests", "urequests.py")
MICROPY_FROZEN_LIST_ITEM("logging", "logging.py")
MICROPY_FROZEN_LIST_ITEM("umqtt", "umqtt.py")
MICROPY_FROZEN_LIST_ITEM("uasyncio", "uasyncio.py")
#endif
6、import的函数实现在py\builtinimport.c中,导入的时候,会查找frozen文件,但是查找的时候,是有“./”的这样,在于mpy文件对比的时候出现了不一致的情况。可能是我在移植代码的时候有地方遗漏,所以使用了一个临时方案解决这个问题。
既修改源码,在文件对比的时候,主动把“./”删除。这样就可以了。
STATIC mp_import_stat_t mp_frozen_stat_helper(const char *name, const char *str)
函数也要做同样的修改。
STATIC mp_import_stat_t mp_frozen_stat_helper(const char *name, const char *str) {
size_t len = strlen(str);
//jhd change './'
const char *temp_str;
if((str[0] == '.')&&(str[1] =='/'))
{
temp_str = str + 2;
len = len - 2;
}
else
{
temp_str = str;
}
for (int i = 0; *name != 0; i++) {
size_t l = strlen(name);
//if (l >= len && !memcmp(str, name, len)) {
if (l >= len && !memcmp(temp_str, name, len)) {
if (name[len] == 0) {
return MP_IMPORT_STAT_FILE;
} else if (name[len] == '/') {
return MP_IMPORT_STAT_DIR;
}
}
name += l + 1;
}
return MP_IMPORT_STAT_NO_EXIST;
}
到此,编译成功,也可以正常import了。因为自己对micropython的理解还不够深入,暂时先这样解决这个问题,后续找到rootcause之后再更新解决方法。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-3-13 20:51:43修改
赞
3
收藏
回复
相关推荐
赞,感谢大佬排坑