今天来说说 MicroPython 的架构情况,如果有必要我会做一些源码分析的文章供大家参考。
先来认识一下 MicroPython 整体情况,可以从软件的角度上去看待,首先我们拿到 MicroPython 的主仓库。
直接 git clone https://github.com/micropython/micropython
,在 Windows 下进行操作了解一下。
之后需要交叉编译代码的时候,必然会回到 Linux ,Windows 10 的发展 Linux 内核还需要一些时间,但应该也快了,届时巨硬霸主将会携带跨平台系统和云端开发服务重新降临到开发者阵营中,拭目以待。
目录情况
一般来说,我们先看一下 readme.md 这里大多时候都会存放这个项目的整体情况或 build 情况。
This is the MicroPython project, which aims to put an implementation
of Python 3.x on microcontrollers and small embedded systems.
You can find the official website at micropython.org.
可知 micropython 是实现了 Python3.x 以上的 Python 语法解释器,接着看到。
MicroPython implements the entire Python 3.4 syntax (including exceptions,with
, yield from
, etc., and additionally async
/await
keywords from
Python 3.5). The following core datatypes are provided: str
(including
basic Unicode support), bytes
, bytearray
, tuple
, list
, dict
, set
,frozenset
, array.array
, collections.namedtuple
, classes and instances.
Builtin modules include sys
, time
, and struct
, etc. Select ports have
support for _thread
module (multithreading). Note that only a subset of
Python 3 functionality is implemented for the data types and modules.
可以看到实现了不少关键词(keywords ),注意 Python3 最大的变化在于 str 和 byte 彻底分离,而 MicroPython 也为此做了很多修改,符合预期。
然后协程相关的语法糖(yield、async、await)都支持了,with 和 in 也有,再来基本的标准库 sys 与 time、struct 、math 等。
最最重要的是,大量现成的基础容器(str、bytes、bytearray、tuple、list、dict、set、btree),编写软件的福利鸭!
最后就是根据芯片的 RTOS 情况提供的 _thread 多线程库,功能上略有缺失,因为多线程的设计和 X86 的有些区别。
but,这些特性并非所有芯片都支持,有时候,要依据不同的芯片情况,对此做裁剪处理,类似制作 linux kernel 一样,选择性的放入一些硬件相关的关键 C 驱动代码。
现在我们接着看很关键的仓库目录说明,可能有些过时,但这并不影响我们对它的认识。
Major components in this repository:
- py/ -- the core Python implementation, including compiler, runtime, and core library.
- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts into precompiled bytecode.
- ports/unix/ -- a version of MicroPython that runs on Unix.
- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar STM32 boards (using ST's Cube HAL drivers).
- ports/minimal/ -- a minimal MicroPython port. Start with this if you want to port MicroPython to another microcontroller.
- tests/ -- test framework and test scripts.
- docs/ -- user documentation in Sphinx reStructuredText format. Rendered HTML documentation is available at http://docs.micropython.org.
Additional components:
- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used mostly to control code size.
- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1 (preliminary but functional).
- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC.
- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC.
- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs.
- extmod/ -- additional (non-core) modules implemented in C.
- tools/ -- various tools, including the pyboard.py module.
- examples/ -- a few example Python scripts.
可以看到这些是官方做了一些架构上的说明,虽然有点乱,但也是可以窥探一二的。
只是为了编译使用 MicroPython 的同学,可以直接看到 ports 文件夹,这里存放着官方移植的一些对应硬件的编译固件配置,进入到其中选择你想要编译的平台,即可得到一个 MicroPython 解释器,开始你的 Python 编程。
如果想知道更多,我继续往下讲。
想知道更多?
文件夹列表大致内容如下
- py Python 解释器相关的抽象实现的代码,包含运行时等等。
- mpy-cross MicroPython 编译器,处理 Python 代码回 ByteCode 机器码。
- ports 对应平台移植配置文件
- tests 框架测试脚本
- docs 配置到 Sphinx 的文档网站
- extmod 一些不需要在 Core 中的抽象 C 接口代码。
- tools 各类脚本辅助工具,例如 Pyboard.py 可以通信控制 MicroPython 。
- examples Python 示例代码。
- lib 给 port 用的各自平台的 SDK 依赖库,可能在里面,也可能在外面,并不重要。
- drivers 通过软实现的硬件驱动,基于 py 的架构使用标准 C 实现的 Python 模块(C + Python),和芯片自己提供的 SDK 略微不同,有较大的兼容性。
对于我们做移植或做深层次的开发有两个方向,假设不破坏官方的架构的基础上,如何结合到现在自己手头的硬件或者软件。
MicroPython 解释器核心的基本认识
我们需要对 MicroPython 的解释器有一个大概的认识,这就需要初略阅读一下 py 的结构了,关键的文件在 compile(python) 、 obj(alloc) 、 nlr (non-local return) 、vm(execute) 等地,总之全都很重要吧。
因此一个解释器的构成情况常有有代码执行环境(堆栈)、代码交互接口(REPL)、变量存取接口(allocator)、代码编译接口(compile)等。
就我们通常的使用方法来讲解吧。
一段 Python 代码,通过 REPL 进入解释器的缓存中,解释器程序将会对这段代码进行解释(编译成 ByteCode),接着通过解释后的 code 进行执行,执行时送到解释器的函数栈上,该执行的就执行,该报异常的报异常。
要做到这样的效果,我们必须深入往下看才能得知具体的细节,关于 py 的部分我就暂且讲到这里,之后也会单独解释一些 py 的源码解释,专门讲解它的构成和 debug 或是修改源码(bug)。
MicroPython 的测试 & 示例
如果我们没有能力去修改 MicroPython ,那就要了解它的外围代码和测试,分别在 example 和 tests,这里有许多测试示例代码供你应用和查阅。
如看 run-tests-exp.sh 和 run-tests-exp.py 文件,又或是 run-tests ,这些都是自动化的测试接口脚本,通过这样的方式可以让 micropython 解释器进行接口覆盖性测试。
自动化生成的示例如下:(均可在 Windows 或 Unix 下运行喔)
如图所见,将在 repl 执行的 Python code 结果返回存到 .exp (example)下进行测试核对。
了解到它的测试框架后,现在是不是对 MicroPython 稍微有了一些信心呢?接着我们还要看到真正开始使用的部分了。
MicroPython 中各芯片标准移植接口
这里就存放着 MicroPython 应用领域中最有价值的代码,也就是官方提出的专用的移植接口示范,对于一般的开发者来说,足够使用了,但对于专业的来说,不仅是使用它,包括如何移植它,改造它,修复它等等都是要了解的。
先看一点简单的移植示例吧 windows 、unix 、还有 minimal 文件夹。
比如我现在在 Windows 上,使用 VS2019 直接打开 windows 的 micropython.vcxproj 文件即可编译生成一个 micropython.exe 解释器了,如下图。
而 unix 则对应着 linux 或 macOS 环境下直接运行即可,我这里不想多示范了,没有什么区别。
但 minimal 很重要,这个是以 STM32F405 的芯片启动流程做了一个硬件移植示范,关于如何从 main 函数初始化 py 相关资源然后链接 nlr 函数等等示例,这将指导你如进行 MicroPython 的移植。
事实上,无论是 STM 还是 TI 又或是 nRF 家的芯片,都可以依次为依据进行主体的移植,然后根据周边情况提供标准库函数的接口,就可以完成 MicroPython 的移植,如果是嵌入式 C 类型的芯片,注意一下替代函数的对接就好了,因为 MicroPython 设计之初就足够的抽象了,不信看看 bare-arm 的三个关键文件 mpconfigport.h 、 mphalport.h 、 qstrdefsport.h ,接着再看看 JavaScript 的接口,就知道我在说什么了,你完全可以把 MicroPython 当作一个解释器接口模块导入你的环境,其他动态语言也是如此,例如 lua 和 JerryScript 也是如此,只是 micropython 提供了太多稳定可用的模块代码,让我没得选择了(真香。
结语
之后我将会以我在做的乐鑫 ESP 系列的芯片 esp8266 和 esp32 来做移植和修改的源码解析说明,毕竟官方已经移植完了大多数主流的芯片配置项目,所以我只能做一些源码升级和修改的说明了,那些移植直接抄过来都不是太大的问题。
写到这里,仔细一看 micropython 和我当年做的 ZwLib 是同样的架构鸭,可惜我的太菜了就放弃继续维护了,大佬不仅强,写代码的速度也很快,真令人头大。
- 撰写时间:2019年9月2日
- 作者名称:junhuanchen
- 联系方式:
- WeChat & Github: 作者名称
- QQ & E-mail: 作者名称@qq.com