C语言开发MicroPython模块(添加module)

C语言开发MicroPython模块(添加module)MicroPython 添加模块框架模式相对简单 只需要按照定义好的固定框架就可以添加模块 module 一 向固件里面添加 module1 1 编写 mymodule c 文件 在 ports esp32 文件夹下新建一个文件 mymodule c 文件内输入如下内容 include stdint h include stdio h include py obj h include py runtime h STATICmp obj tmp my test functio

  MicroPython添加模块框架模式相对简单,只需要按照定义好的固定框架就可以添加模块(module)。

一、向固件里面添加module

1.1、编写mymodule.c文件

  在ports/esp32文件夹下新建一个文件mymodule.c ,文件内输入如下内容:

#include "stdint.h" #include "stdio.h" #include "py/obj.h" #include "py/runtime.h" STATIC mp_obj_t mp_my_test_function(mp_obj_t myms) { 
    uint32_t Myms = mp_obj_get_int(myms); vTaskDelay(Myms / portTICK_PERIOD_MS); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(My_mp_my_test_function, mp_my_test_function); STATIC const mp_rom_map_elem_t modnormal_globals_table[] = { 
    { 
   MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_my_test_module)}, { 
   MP_OBJ_NEW_QSTR(MP_QSTR_mytestfunction), MP_ROM_PTR(&My_mp_my_test_function)}, { 
   MP_OBJ_NEW_QSTR(MP_QSTR_test), MP_ROM_PTR(&modnormal_test_type)}, }; STATIC MP_DEFINE_CONST_DICT(mp_module_modnormal_globals, modnormal_globals_table); const mp_obj_module_t mp_module_my_test_mod = { 
    .base = { 
   &mp_type_module}, .globals = (mp_obj_dict_t *)&mp_module_modnormal_globals, }; 

  文件mymodule.c 内创建了一个mp_module_my_test_mod的模块,它包含了一个funtion和一个type,type定义在其他文件内。

1.2、注册module

  我们要把我们定义的module注册到micropython中去,这个是在mpconfigport.h文件中修改,找到MICROPY_PORT_BUILTIN_MODULES 定义的地方按照格式添加我们定义的module:

// extra built in modules to add to the list of known ones extern const struct _mp_obj_module_t esp_module; extern const struct _mp_obj_module_t esp32_module; extern const struct _mp_obj_module_t utime_module; extern const struct _mp_obj_module_t uos_module; extern const struct _mp_obj_module_t mp_module_usocket; extern const struct _mp_obj_module_t mp_module_machine; extern const struct _mp_obj_module_t mp_module_network; extern const struct _mp_obj_module_t mp_module_onewire; extern const struct _mp_obj_module_t mp_module_my_test_mod;//声明模块 #define MICROPY_PORT_BUILTIN_MODULES \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_esp32), (mp_obj_t)&esp32_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&utime_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&uos_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_my_test_module), (mp_obj_t)&mp_module_my_test_mod }, \ 

二、向固件里面添加module的原理

  在文章C语言开发MicroPython模块(模块框架)里面已经介绍了,编译进内核的模块(module)有四种类型,MicroPython将它们组成四个不同的模块集合,并且定义了不同的名字。

2.1、模块集合

  以我们编写的和硬件平台密切相关的 module集合mp_builtin_module_map为例,在objmodule.c文件内有

MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table); 

  其中mp_builtin_module_map就是这个被编译进内核的模块集合的名字,mp_builtin_module_table是存储模块的结构体数组。  MP_DEFINE_CONST_MAP的定义在obj.h文件内,内容如下:

#define MP_DEFINE_CONST_MAP(map_name, table_name) \ const mp_map_t map_name = { 
      \ .all_keys_are_qstrs = 1, \ .is_fixed = 1, \ .is_ordered = 1, \ .used = MP_ARRAY_SIZE(table_name), \ .alloc = MP_ARRAY_SIZE(table_name), \ .table = (mp_map_elem_t*)(mp_rom_map_elem_t*)table_name, \ } 

  宏定义MP_DEFINE_CONST_MAP就是定义了一个结构体,这个结构体的内容为mp_map_t

// TODO maybe have a truncated mp_map_t for fixed tables, since alloc=used // put alloc last in the structure, so the truncated version does not need it // this would save 1 ROM word for all ROM objects that have a locals_dict // would also need a trucated dict structure typedef struct _mp_map_t { 
    size_t all_keys_are_qstrs : 1; size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered size_t is_ordered : 1; // an ordered array size_t used : (8 * sizeof(size_t) - 3); size_t alloc; mp_map_elem_t *table; } mp_map_t; 

  MP_ARRAY_SIZE的定义为:

// get the number of elements in a fixed-size array #define MP_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 

  说明结构体的alloc是模块集合的指针合所占的长度,table是一个指针,这个指针指向了mp_builtin_module_table这个结构体数组。在.table = (mp_map_elem_t*)(mp_rom_map_elem_t*)table_name, \这行代码里面mp_rom_map_elem_t和mp_map_elem_t的定义为:

// Underlying map/hash table implementation (not dict object or map function) typedef struct _mp_map_elem_t { 
    mp_obj_t key; mp_obj_t value; } mp_map_elem_t; typedef struct _mp_rom_map_elem_t { 
    mp_rom_obj_t key; mp_rom_obj_t value; } mp_rom_map_elem_t; 

  而mp_obj_t和mp_rom_obj_t的定义为:

typedef void *mp_obj_t; typedef const void *mp_const_obj_t; typedef mp_const_obj_t mp_rom_obj_t; 

  所以名字为mp_builtin_module_map的这个模块集合在最终包含了一系列的指针,mp_builtin_module_table这个结构体数组内元素。而mp_builtin_module_table这个结构体数组内的元素则是一个一个的模块。

2.2、模块数组

  mp_builtin_module_table的定义如下:

// // Global module table and related functions STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { 
    { 
    MP_ROM_QSTR(MP_QSTR___main__), MP_ROM_PTR(&mp_module___main__) }, { 
    MP_ROM_QSTR(MP_QSTR_builtins), MP_ROM_PTR(&mp_module_builtins) }, { 
    MP_ROM_QSTR(MP_QSTR_micropython), MP_ROM_PTR(&mp_module_micropython) }, #if MICROPY_PY_ARRAY { 
    MP_ROM_QSTR(MP_QSTR_array), MP_ROM_PTR(&mp_module_array) }, #endif #if MICROPY_PY_IO { 
    MP_ROM_QSTR(MP_QSTR_uio), MP_ROM_PTR(&mp_module_io) }, #endif #if MICROPY_PY_COLLECTIONS { 
    MP_ROM_QSTR(MP_QSTR_ucollections), MP_ROM_PTR(&mp_module_collections) }, #endif #if MICROPY_PY_STRUCT { 
    MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) }, #endif #if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_MATH { 
    MP_ROM_QSTR(MP_QSTR_math), MP_ROM_PTR(&mp_module_math) }, #endif #if MICROPY_PY_BUILTINS_COMPLEX && MICROPY_PY_CMATH { 
    MP_ROM_QSTR(MP_QSTR_cmath), MP_ROM_PTR(&mp_module_cmath) }, #endif #endif #if MICROPY_PY_SYS { 
    MP_ROM_QSTR(MP_QSTR_sys), MP_ROM_PTR(&mp_module_sys) }, #endif #if MICROPY_PY_GC && MICROPY_ENABLE_GC { 
    MP_ROM_QSTR(MP_QSTR_gc), MP_ROM_PTR(&mp_module_gc) }, #endif #if MICROPY_PY_THREAD { 
    MP_ROM_QSTR(MP_QSTR__thread), MP_ROM_PTR(&mp_module_thread) }, #endif // extmod modules #if MICROPY_PY_UERRNO { 
    MP_ROM_QSTR(MP_QSTR_uerrno), MP_ROM_PTR(&mp_module_uerrno) }, #endif #if MICROPY_PY_UCTYPES { 
    MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) }, #endif #if MICROPY_PY_UZLIB { 
    MP_ROM_QSTR(MP_QSTR_uzlib), MP_ROM_PTR(&mp_module_uzlib) }, #endif #if MICROPY_PY_UJSON { 
    MP_ROM_QSTR(MP_QSTR_ujson), MP_ROM_PTR(&mp_module_ujson) }, #endif #if MICROPY_PY_URE { 
    MP_ROM_QSTR(MP_QSTR_ure), MP_ROM_PTR(&mp_module_ure) }, #endif #if MICROPY_PY_UHEAPQ { 
    MP_ROM_QSTR(MP_QSTR_uheapq), MP_ROM_PTR(&mp_module_uheapq) }, #endif #if MICROPY_PY_UTIMEQ { 
    MP_ROM_QSTR(MP_QSTR_utimeq), MP_ROM_PTR(&mp_module_utimeq) }, #endif #if MICROPY_PY_UHASHLIB { 
    MP_ROM_QSTR(MP_QSTR_uhashlib), MP_ROM_PTR(&mp_module_uhashlib) }, #endif #if MICROPY_PY_UCRYPTOLIB { 
    MP_ROM_QSTR(MP_QSTR_ucryptolib), MP_ROM_PTR(&mp_module_ucryptolib) }, #endif #if MICROPY_PY_UBINASCII { 
    MP_ROM_QSTR(MP_QSTR_ubinascii), MP_ROM_PTR(&mp_module_ubinascii) }, #endif #if MICROPY_PY_URANDOM { 
    MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_module_urandom) }, #endif #if MICROPY_PY_USELECT { 
    MP_ROM_QSTR(MP_QSTR_uselect), MP_ROM_PTR(&mp_module_uselect) }, #endif #if MICROPY_PY_USSL { 
    MP_ROM_QSTR(MP_QSTR_ussl), MP_ROM_PTR(&mp_module_ussl) }, #endif #if MICROPY_PY_LWIP { 
    MP_ROM_QSTR(MP_QSTR_lwip), MP_ROM_PTR(&mp_module_lwip) }, #endif #if MICROPY_PY_WEBSOCKET { 
    MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&mp_module_websocket) }, #endif #if MICROPY_PY_WEBREPL { 
    MP_ROM_QSTR(MP_QSTR__webrepl), MP_ROM_PTR(&mp_module_webrepl) }, #endif #if MICROPY_PY_FRAMEBUF { 
    MP_ROM_QSTR(MP_QSTR_framebuf), MP_ROM_PTR(&mp_module_framebuf) }, #endif #if MICROPY_PY_BTREE { 
    MP_ROM_QSTR(MP_QSTR_btree), MP_ROM_PTR(&mp_module_btree) }, #endif // extra builtin modules as defined by a port MICROPY_PORT_BUILTIN_MODULES }; 

  结构体mp_rom_map_elem_t的定义如下:

typedef struct _mp_rom_map_elem_t { 
    mp_rom_obj_t key; mp_rom_obj_t value; } mp_rom_map_elem_t; 

  说明mp_builtin_module_table这个数组里面每个元素都必须是mp_rom_map_elem_t类型。当增加一个模块时,就往这个数组里面添加一个元素。下面以第一个数组元素进行分析:

2.2.1、MP_ROM_QSTR

{ 
    MP_ROM_QSTR(MP_QSTR___main__), MP_ROM_PTR(&mp_module___main__) }, 

  MP_ROM_QSTR的定义为:

#define MP_ROM_QSTR(q) MP_OBJ_NEW_QSTR(q) 

  而MP_OBJ_NEW_QSTR的定义为:

#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2)) 

  其中mp_uint_t的定义为

typedef unsigned int mp_uint_t; // must be pointer size 

  mp_obj_t的定义为

typedef void *mp_obj_t; 

  所以MP_ROM_QSTR(MP_QSTR___main__)的作用是将将MP_QSTR___main__强制转换为类型int,然后将结果值左移两位,在将二进制结果的值与2进行或操作,再将结果转换为无符号的指针类型。最终就变成了一个为_main__的无符号指针。

2.2.2、MP_ROM_PTR

  MP_ROM_PTR的 定义为:

#define MP_ROM_PTR(p) (p) 

2.3、MICROPY_PORT_BUILTIN_MODULES

  MICROPY_PORT_BUILTIN_MODULES的定义在mpconfigport.h文件内为

#define MICROPY_PORT_BUILTIN_MODULES \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_esp32), (mp_obj_t)&esp32_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&utime_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&uos_module }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \ { 
      MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib }, \ 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234010.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • QtCharts :QStringList插入值[通俗易懂]

    QtCharts :QStringList插入值[通俗易懂]QStringList初始化QStringListqstrList;1.增加字符串append()QStringList可以通过append(),或使用<<来添加List元素,如qstrList.append(“python”);qstrList<<“PHP”;2.插入字符串insert()插入字符串insert方法可以将字符串插入到我们…

    2022年6月11日
    66
  • 远程连接工具SecureCRTPortable连接不上linux的解决方法[通俗易懂]

    远程连接工具SecureCRTPortable连接不上linux的解决方法[通俗易懂]今天学习linux用远程工具连接时,连接不上,出现了一个类似函数的东西,运用了排除法,1.先检查了虚拟机服务是否开启2.然后ping网关看能通吗3.然后pingDNS域名,再pingwww.baidu.com都能ping通,百思不得其解然后通过查资料,输入route发现default后面并没有分配默认网关于是输入routeadddefaultgw192.168…

    2022年5月8日
    333
  • SQL SERVER 中的smalldatetime和datetime区别[通俗易懂]

    SQL SERVER 中的smalldatetime和datetime区别[通俗易懂]smalldatetime不能到秒.不過它占的空間小.(4位)datetime(8位)而且兩者的時間範圍不一樣.datetime占8字节,精度3.33毫秒,时间从1753.1.1到9999.12.31

    2022年7月2日
    33
  • pycharm设置背景颜色_idea自定义背景颜色

    pycharm设置背景颜色_idea自定义背景颜色pycharm原始的背景是白底黑字或者黑底白字,我都不是很喜欢。我配置的是豆沙绿背景,字还是黑字,效果还不错,这种是比较护眼的。如图:  具体操作如下:File->Settings->Editor->Colors&Fonts->General->Text->Defaulttext然后修改background的颜色,配置如下图:

    2022年8月27日
    4
  • 从伯努利分布到多项式分布的条件_伯努利分布的期望

    从伯努利分布到多项式分布的条件_伯努利分布的期望1.伯努利分布(bernoulidistribution)又称0-1分布,指一次随机试验,结果只有两种。也就是一个随机变量的取值只有0和1。其中p表示一次伯努利实验中结果为正或为1的概率。概率计算:

    2022年10月12日
    2
  • 三本毕业北京打工考研北大计算机,知乎刘洋:三本到北大软微到牛津博士,最后在哈工深当老师。…

    三本毕业北京打工考研北大计算机,知乎刘洋:三本到北大软微到牛津博士,最后在哈工深当老师。…(转发侵删)背景:当年在某三本独立学院,考研一志愿报了北大信科,没过复试线,校内调剂至北大软件工程参加复试复试时第一个问题是让简单介绍一下自己和本科学校,我刚说到学校名字就被考官打断了:“你的本科学校叫AA大学BB学院,那它到底是AA大学的一个下属学院呢,还是个跟AA大学没啥关系的独立学院呢?”我回答说:“是个独立学院,三本。”于是全场寂静,空气凝结。当时的直觉就是,这伙哥们儿肯定在想:“你一个…

    2022年9月21日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号