8.2. 直接运行字节码
PikaScript 的运行时架构如下图所示,在默认情况下,Python 脚本解析成 Pika 字节码的过程是放在 MCU 执行的,这使得 MCU 可以直接运行 Python 脚本,包括支持交互式运行。
而在资源受限的情况下,可以将 Python 脚本解析为字节码的过程在 PC 提前完成,在 MCU 中直接执行 Pika 字节码,这样一来 解析 Python 脚本的代码就可以被裁剪掉了。
在代码中避免使用 obj_run()
执行 python 脚本,编译器就会自动优化掉 Python 解析的代码,降低代码体积占用。
8.2.1. 在 PC 上将 Python 转为字节码:
预编译器 rust-msc-latest-win10.exe
集成了字节码生成器,在预编译时会将 main.py 和被 main.py import
(包括间接 import
) 的 .py
文件编译为字节码,生成的字节码文件在 pikascript-api 文件夹下。
.py
文件会被生成为 .py.o
字节码文件,例如 main.py
会生成 pikascript-api/main.py.o
。
同时,所有的 .py.o
文件会被自动打包成一个库文件 pikascript-api/pikaModules.py.a
,库文件中包含了所有的字节码文件。
为了方便编译固件时在 mcu 中载入库文件,预编译器还会把库文件自动转换为 C 的字节数组文件 pikascript-api/__asset_pikaModules_py_a.c
。
/* __asset_pikaModules_py_a.c */
#include "PikaPlatform.h"
/* warning: auto generated file, please do not modify */
PIKA_BYTECODE_ALIGN const unsigned char pikaModules_py_a[] = {
0x7f, 0x70, 0x79, 0x61, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e,
...
8.2.2. 使用库文件
使用 obj_linkLibrary()
API 可以导入库文件,参考自动生成的 pikaScriptInit()
PikaObj *pikaScriptInit(void){
...
__pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(__pikaMain, pikaModules_py_a);
...
}
导入库文件后,即可直接在 python 脚本里面 import
库文件中包含的模块。
也可以直接将一个模块作为脚本运行,如:
obj_runModule(__pikaMain, "main");
8.2.3. 运行单个字节码
从单个字节码文件 .py.o
中读取数据,然后使用 pikaVM_runByteCode()
API可以就直接运行单个字节码,可以参考g030中从字节码启动的用法。
https://gitee.com/Lyon1998/pikascript/blob/master/bsp/stm32g030c8/Booter/main.c