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文件。
Hi3861下移植micropython无法引入freeze程序的解决方法-开源基础软件社区
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
收藏
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐