1、概述
Micropython是对Python3的一种高效实现,包括了部分Python标准库,针对MCU等资源受限的场景进行了优化。
Python语言语法简洁直观,容易上手,是目前最炙手可热的编程语言之一。而Micropython提供了使用Python语言操控硬件设备的接口,在STEAM教育等领域广受欢迎。
1.1 编译还是解释
虽然Python语言编程对用户友好,但是其执行效率问题也经常被部分人诟病,因其是一种“解释型”语言。与“解释型”语言相对的是“编译型”语言,比如C语言。
C语言的程序要经过编译器编译生成可执行的二进制机器码,然后CPU就可以直接读取执行。而“解释型”语言,比如Shell脚本,执行前一般不需要编译过程,而是“边解释边执行”。
不严谨地说,“编译型”语言与“解释型”语言的区别是,它把解释的工作丢给了编译器。
不过,严格来说,Python语言并不是纯粹的“解释型”语言,Python程序的执行过程其实包括了先编译再解释的过程。
只不过这里的编译并没有把Python语句编译成CPU可以直接执行的机器码,而是编译成了一种平台无关的格式,称为bytecode。bytecode再被虚拟机解释为平台相关的操作并执行。
2、Micropython语句:从开始到结束
一条Micropython语句,无论来自REPL(交互式Shell)、文件还是eval函数,要产生预期的结果,都会经过以下生命周期:
解析:从语句到解析树
编译:从解析树到bytecode
执行:虚拟机解释执行bytecode
这个过程由parse_compile_execute函数(lib/utils/pyexec.c)实现:
/* lib/utils/pyexec.c */
STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
...
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t module_fun;
...
{
#if MICROPY_ENABLE_COMPILER
mp_lexer_t *lex;
if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) {
const vstr_t *vstr = source;
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0);
} else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) {
lex = mp_lexer_new_from_file(source);
} else {
lex = (mp_lexer_t *)source;
}
// source is a lexer, parse and compile the script
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL);
#else
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported"));
#endif
}
// execute code
mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us
#if MICROPY_REPL_INFO
start = mp_hal_ticks_ms();
#endif
mp_call_function_0(module_fun);
mp_hal_set_interrupt_char(-1); // disable interrupt
mp_handle_pending(true); // handle any pending exceptions (and any callbacks)
nlr_pop();
ret = 1;
if (exec_flags & EXEC_FLAG_PRINT_EOF) {
mp_hal_stdout_tx_strn("\x04", 1);
}
} else {
...
}
...
return ret;
}
mp_parse为解析过程
mp_compile为编译过程
mp_call_function_0为执行过程
原作者:Remember
|