MicroPython C 绑定代码自动生成器



添加提示代码


添加一个 C 函数到 MicroPython 中有如下三个步骤,分别对应 Output 中的三个动作:

  1. 将自动生成的 同名 C 语言函数 拷贝到 port/modules/user/moduserfunc.c 文件
  2. 将该函数注册到用户模块列表 (_globals_table[])
  3. 追加关联该函数的 QSTR 到 port/genhdr/qstrdefs.generated.h 文件

C 绑定添加原理介绍

1. 将 C 函数转化为 MicroPython 函数的关键点是什么?

C 语言和 Python 是两种完全不同的语言,如何使用 Python 来调用 C 语言所实现的函数是许多小伙伴非常疑惑的地方。 其实这个问题的关键点就在于如何用 C 语言的形式在 Python 中表述函数的入参和出参,我举一个例子来讲解这个问题, 请观察下列 Python 函数:

 
def add(a, b):
    return a + b
                
这个函数输入两个参数,输出一个参数。此时如果我们能用 C 语言表示该 Python 函数的输入输出参数,我们就可以将一 个实现该功能的 C 语言的函数对接到 MicroPython 中,我们假设这些参数的类型都为整形,通过自动生成器我们可以得到 如下样板函数:
 
STATIC mp_obj_t add(
    mp_obj_t arg_1_obj,
    mp_obj_t arg_2_obj) {
    mp_int_t arg_1 = mp_obj_get_int(arg_1_obj);   /* 通过 Python 获取的第一个整形参数 arg_1 */
    mp_int_t arg_2 = mp_obj_get_int(arg_2_obj);   /* 通过 Python 获取的第二个整形参数 arg_1 */
    mp_int_t ret_val;

    /* Your code start! */

    ret_val = arg_1 + arg_2;  /* 在此处添加处理入参 arg_1 和 arg_2 的实现,并将结果赋给返回值 ret_val */

    /* Your code end! */

    return mp_obj_new_int(ret_val);               /* 向 python 返回整形参数 ret_val */
}
MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add);
                
生成器会帮我们处理好需要导出到 MicroPython 的函数的入参和出参,而我们只需要编写相应的代码来处理这些输入参数,并且把返回值赋给输出参数即可。 你可以通过包含头文件的方式,任意调用你先前编写的任意 C 函数来对输入参数进行处理,或者根据输入参数来执行相应的动作。

编写完功能函数后,还要记得注册你的函数到模块中,其实也就是将你的函数添加到模块列表 _globals_table[] 中。至于为什么要添加 QSTR,不必太在意, 这是一种在 MicroPython 中节省字符串占用空间的机制,根据提示添加相应的代码就可以了。

最终使用 Python 调用 C 函数的效果如下:
 
>>> import userfunc
>>> userfunc.add(666,777)
1443
                

2. 如何添加一个属于自己的模块呢?

很多小伙伴想要添加属于自己的模块到 MicroPython 中,这个过程稍稍复杂,但也不难。我推荐你先将上述添加 C 函数的过程搞明白, 然后参考 PR add module userfunc to MicroPython 来添加属于自己的模块,该 PR 实现了添加 userfunc 模块到 MicroPython 的功能,你可以按照同样的方式将自己编写的模块注册到 MicroPython 中, 要注意仔细查看这个 PR 中修改的 4 个文件,不要漏掉修改的细节。