MicroPython VM

# MicroPython VM

        MicroPython VM (Virtual Machine) 是一个运行 MicroPython 代码的虚拟机,可以将 Python 代码编译成字节码并在 MicroPython VM 的内部环境中运行。MicroPython VM 通常用于在嵌入式系统中运行 Python 代码,因为它可以在较小的存储空间和处理器速度下运行。

        使用 MicroPython VM,可以在 C 语言程序中运行 Python 代码。以下是一个简单的示例,展示了如何使用 MicroPython VM 执行 Python 程序:

#include <stdio.h>
#include "py/mphal.h"
#include "py/mpstate.h"
#include "py/gc.h"
#include "py/mppy.h"
#include "py/stackctrl.h"

// 将 Python 代码编译成字节码并返回字节码对象
mp_obj_t compile_code(const char *source_code) {
    // 将代码字符串转换为字节码对象
    mp_lexer_t *lex = mp_lexer_new_from_str_len("", strlen(source_code), false);
    mp_parse_tree_t pt = mp_parse_compile(lex, MP_PARSE_FILE_INPUT);

    // 编译字节码
    mp_obj_t module_fun = mp_compile(&pt, "", MP_EMIT_OPT_NONE, false);

    // 返回字节码对象
    return module_fun;
}

int main(void) {
    // 初始化 MicroPython VM
    mp_init();
    mp_obj_t module_fun;
    char source_code[] = "print('Hello World')";  // Python 代码

    // 编译 Python 代码
    module_fun = compile_code(source_code);

    // 在 VM 中执行函数
    mp_call_function_0(module_fun);
    return 0;
}

        上述代码中,`mp_init()`函数用于初始化 MicroPython VM,并创建一些必要的对象,例如全局对象和垃圾回收堆栈。

        `compile_code()`函数将 Python 代码字符串编译为字节码对象。在这个函数中,我们使用 `mp_lexer_new_from_str_len()` 函数将字符串转换为 lexer 对象并通过 `mp_parse_compile()` 函数将其编译为字节码。然后我们调用 `mp_compile()` 函数创建字节码对象,该对象便可以被 MicroPython VM 运行。

        最后,我们使用 `mp_call_function_0()` 函数在 VM 中执行 `module_fun` 函数。在此示例中,Python 函数输出一个"Hello World"消息。

# compile_code和mp_call_function_0函数

# compile_code源码

py/compile.h 中 compile_code() 的函数签名和注释:

mp_obj_t compile_code(const char *data, mp_uint_t len, bool is_repl, bool is_repl_cont, mp_parse_input_kind_t input_kind);

编译一段 Python 代码并返回一个函数对象。

参数:

  • data - 包含 Python 代码的字符串。

  • len - 字符串 data 的长度。

  • is_repl - 表示这个代码是不是在 REPL 中输入的。

  • is_repl_cont - 如果是 REPL 中输入且需要续行,为 true

  • input_kind - 输入的类型,可以是 MP_PARSE_SINGLE_INPUTMP_PARSE_FILE_INPUT 或 MP_PARSE_EVAL_INPUT

返回值:

  • 如果编译成功,则返回一个函数对象,否则返回 MP_OBJ_NULL 并且输出错误信息到标准错误输出。

compile_code() 函数的实现在文件 py/compile.c 中,具体实现细节如下:

   1,首先构建编译器环境。

mp_parse_tree_t parse_tree = {0};
emit_glue_t emit_glue = {0};
mp_lexer_t *lex = NULL;
mp_parse_node_t pn;

   2,然后,根据给定的输入类型,调用不同的输入函数,返回一个解析器。

if (input_kind == MP_PARSE_SINGLE_INPUT) {
    lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, data, len, 0);
    pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT);
} else if (input_kind == MP_PARSE_FILE_INPUT) {
    ...
} else { // input_kind == MP_PARSE_EVAL_INPUT
    ...
}

        这里我们只展开 MP_PARSE_SINGLE_INPUT 的情况。

       3,对解析得到的语法树进行语法分析和代码生成,把生成的字节码放到一个新的字节码对象中。

if (pn != MP_PARSE_NODE_NULL) {
    // make sure last expression statement is a result
    PN_set_flag(pn, PN_CAN_BE_NONE);

    // compile it
    qstr source_name = lex ? lex->source_name : MP_QSTR_eval;
    if (is_repl) {
        if (is_repl_cont) {
            source_name = MP_QSTR__lt_stdin_gt_;
        } else {
            // add prefix "  "
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Micropython原理图是一个用来解释Micropython系统架构和工作原理的图示。它展示了Micropython虚拟机VM)的基本组成部分和它们之间的关系。 Micropython原理图通常包括以下几个关键组件: 1. 解释器(Interpreter): 这是Micropython的核心组件,负责解释和执行Micropython的源代码。它接收用户编写的Python代码并将其转换为底层机器码进行执行。 2. 编译器(Compiler): 编译器负责将Python源代码转化为字节码,以便解释器可以执行它们。字节码是一种中间代码,它将Python代码转换为一系列指令,可以被虚拟机理解和执行。 3. 垃圾收集器(Garbage Collector): 垃圾收集器负责管理动态分配的内存,并在不再使用时进行自动回收。这样可以防止内存泄漏和资源浪费。 4. 原生模块(Native Modules): 原生模块是一些底层的功能模块,它们是使用C语言编写的,提供了一些底层硬件和操作系统的接口。通过原生模块,Micropython可以访问和控制外部设备,如传感器、执行器等。 5. 硬件抽象层(Hardware Abstraction Layer): 硬件抽象层是Micropython与底层硬件之间的接口层。它提供了一组统一的函数和接口,使得用户可以在不同硬件平台上开发和运行Micropython代码。 Micropython原理图的作用是帮助开发者理解Micropython的内部结构和工作原理。通过了解原理图,开发者可以更好地利用Micropython平台进行嵌入式开发,编写高效、可靠的代码。同时,原理图也可以作为教学工具,帮助初学者快速入门Micropython编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值