编写micropython原生模块 (1) - 准备工作
前言
在经历了自己设计字库格式、编写字库生成工具、编写纯py版本的字库查询函数库之后,发现几经优化的查询函数库依然没办法满足速度需求。没办法,只好试试原生mpy模块能否提高运行效率。
比较坑的是官方文档对于编写原生模块的介绍只有一篇文档,然后丢了几个example就完事,只能靠自己摸索。这里记录下来方便以后查阅。
原生模块的特点和限制
原生模块的特点:
- 原生模块可以像正常mpy模块一样被import,只需要将编译出来的.mpy文件放到对应的路径即可。只要CPU架构相同,原生模块可以通用,无需编译整个micropython的固件
- 使用原生模块能够让你更好地控制内存使用,提高速度和内存利用率。
- 使用原生模块可以控制mpy中几乎所有的对象。
但是原生模块也有不少限制:
- 原生模块不能访问系统API,只能使用mpy的动态运行时的API,这也是原生模块能在相同架构CPU的机器下通用的原因。
- 需要手动管理内存,在动态申请内存之后,要记得尽早释放。(除非是将申请的内存转换成mpy对象并交给mpy管理,比如通过byte数组创建的bytearray作为返回值返回,此时不需要释放byte数组的内存)。
- 不支持Data Section和静态BSS变量,这个我也没看懂,总之所有的静态对象都要在全局定义,影响不大。
准备工作
首先需要获取一份MicroPython的源码。
git clone --recursive https://github.com/micropython/micropython.git
这里没必要使用国内镜像加速,因为micropython项目有不少git子模块,都是从github获取的,配置一个好一点儿的代理更靠谱。
然后要准备对应平台的编译工具,比如我用的ESP32开发版,就下载官方的ESP-IDF工具(ESP23-PORT配置工具链指南)。确保编译工具链在PATH当中,全局可用。
编译第一个mpy原生模块
复制一份 /micropython/examples/natmod/features0 目录,这是最简单的原生模块的例子。可以看到例子很短,特别是Makefile十分简单。
修改Makefile中MPY_DIR和ARCH部分,改成自己的micropython源码目录,和单片机的架构,在交叉编译工具链全局可用的情况下,直接执行make就可以编译。不出意外的话,会在目录下生成features0.mpy文件。
测试编译出来的原生模块
将原生模块复制到单片机目录下(可以用ampy或者mpfshell工具上传文件),然后执行下面的代码:
import features0
sum = features0.factorial(3) # some int
print(sum)
输出的数字就是斐波那契数列计算的结果,可以查看源代码获取具体的算法。
小结
千里之行,始于足下。到这里,已经成功编译了一个原生mpy模块,并且实现了int型参数的传递与返回。
此时,数据已经可以在mpy运行时和原生运行时之间传递了。接下来所有的工作就是围绕如何丰富这个简单的模块而展开的。
评论已关闭