美文网首页
MicroPython添加Module(一)

MicroPython添加Module(一)

作者: tianxiaoMCU | 来源:发表于2019-03-26 16:12 被阅读0次

    前面已经将MicroPython移植到了LPC1788,其中的一些功能已经可以使用。但是片上外设、板载外设还不能访问,需要我们去实现,然后才能在MicroPython中访问。官方文档MicroPython external C modules中对这部分有说明,比较简单。下面通过实战来进一步理解这部分文档。

    添加源文件

    第一步肯定是创建源文件了,给它命名为machine.c

    并添加到MakeFile里边,不然是不会被编译的。
    SRC_C = \
        main.c \
        uart_core.c \
        ...
        ./modules/machine.c
        ...
    
    创建一个Module

    源文件已经建好,接下来就是编码了。在MicroPython中,modules是有确定的结构的。可以把这个结构理解为模板,跟着模板走,总没有错的。先来看看这个模板:

    #include "py/obj.h"
    #include "py/runtime.h"
    #include "py/builtin.h"
    
    STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
        {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_machine)},
    };
    
    STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
    
    const mp_obj_module_t machine_module = {
        .base = {&mp_type_module},
        .globals = (mp_obj_dict_t *)&machine_module_globals,
    };
    

    上面这部分代码使用mp_obj_module_t类型定义了一个module,并初始化了相关的部分,如基本类型、模块的字典。在字典中,定义了__name__,为machine,这个就是我们这个module的名字。
    为了让这个模块能在MicroPython中被import,需要将模块添加到mpconfigport.hMICROPY_PORT_BUILTIN_MODULES中。注意:不是MICROPY_PORT_BUILTINS!!!

    // extra built in modules to add to the list of known ones
    extern const struct _mp_obj_module_t machine_module;  // 注意_mp_obj_module_t是带下划线前缀的
    
    #define MICROPY_PORT_BUILTIN_MODULES \
        {MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&machine_module)},
    

    编译并烧录,在MicroPython中使用import machine测试是否成功,不报错就是成功了。

    添加一个Function

    现在,我们可以添加一个函数到这个模块里面。首先定义一个函数,这里以reset函数来具体说明。

    STATIC mp_obj_t machine_reset(void)
    {
        NVIC_SystemReset();
        return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
    

    这段代码创建了一个名为machine_reset_obj的函数对象,该函数没有参数,被调用时会执行C函数machine_reset。此外,所有的Python函数都必须返回一个mp_obj_t结构对象,但是我们这没有什么可返回的,因此返回None。接下来将这个函数添加到前面创建好的module中。

    STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
        {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_machine)},
        {MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj)},
    };
    

    好了,编译看看。报错了,提示下面的信息

    In file included from modules/machine.c:1:0:
    modules/machine.c:17:18: error: 'MP_QSTR_sys_reset' undeclared here (not in a function)
         {MP_ROM_QSTR(MP_QSTR_sys_reset), MP_ROM_PTR(&machine_reset_obj)},
                      ^
    ../../py/obj.h:92:56: note: in definition of macro 'MP_OBJ_NEW_QSTR'
     #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
                                                            ^
    modules/machine.c:17:6: note: in expansion of macro 'MP_ROM_QSTR'
         {MP_ROM_QSTR(MP_QSTR_sys_reset), MP_ROM_PTR(&machine_reset_obj)},
          ^
    make: *** [build/./modules/machine.o] Error 1
    

    其实上面的操作还缺少一个步骤,就是在qstrdefsport.h.中定义一个Q(reset),再编译就OK了。

    Function的参数

    前面添加一个函数时使用了MP_DEFINE_CONST_FUN_OBJ_0宏来定义一个不带参数的函数。同样也可以定义一个或多个参数的函数。下面列举出所有支持的类型,具体的使用方法不细说,可以查看各个移植的例子。

    说明
    MP_DEFINE_CONST_FUN_OBJ_0 不带参数的函数
    MP_DEFINE_CONST_FUN_OBJ_1 只有1个参数的函数
    MP_DEFINE_CONST_FUN_OBJ_2 有2个参数的函数
    MP_DEFINE_CONST_FUN_OBJ_3 有3个参数的函数
    MP_DEFINE_CONST_FUN_OBJ_VAR 带可变参数的函数
    MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN 跟上面类似,但是参数个数有范围
    MP_DEFINE_CONST_FUN_OBJ_KW 带关键字参数的函数
    在MicroPython中使用Module
    import machine  # 添加的module的名字叫‘machine’,要使用这个模块首先得导入它
    
    machine.reset()  # 调用这个模块的函数
    

    相关文章

      网友评论

          本文标题:MicroPython添加Module(一)

          本文链接:https://www.haomeiwen.com/subject/chcpvqtx.html