MicroPython项目中的.mpy文件格式详解
什么是.mpy文件
MicroPython定义了一种名为.mpy的二进制容器文件格式,这种文件包含了预编译的代码,可以像普通.py模块一样被导入。当执行import foo时,MicroPython会按照以下顺序查找模块:
- 首先查找
foo.py - 如果没有找到,则查找
foo.mpy - 如果都没有找到,继续在下一个目录中查找
这意味着.py文件比.mpy文件具有更高的优先级。
.mpy文件通常通过mpy-cross工具从Python源代码(.py文件)生成,可以包含字节码。对于某些架构,.mpy文件还可以包含本地机器码,这些机器码通常从C源代码生成。
.mpy文件的版本兼容性
.mpy文件的兼容性取决于以下几个关键因素:
- 文件版本:必须与MicroPython系统支持的版本匹配
- 子版本:如果包含本地机器码,子版本必须匹配
- 小整数位数:文件要求的最小整数位数必须被系统支持
- 本地架构:如果包含本地机器码,系统必须支持该架构
当导入.mpy文件失败时,系统会抛出ValueError异常,提示不兼容的.mpy文件或架构。
检查系统支持的.mpy版本
可以通过以下代码检查当前MicroPython系统支持的.mpy版本和特性:
import sys
sys_mpy = sys.implementation._mpy
arch = [None, 'x86', 'x64',
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
'xtensa', 'xtensawin', 'rv32imc'][sys_mpy >> 10]
print('mpy版本:', sys_mpy & 0xff)
print('mpy子版本:', sys_mpy >> 8 & 3)
print('mpy标志:', end='')
if arch:
print(' -march=' + arch, end='')
print()
MicroPython版本与.mpy版本对应关系
| MicroPython版本 | .mpy版本 |
|---|---|
| v1.23.0及以上 | 6.3 |
| v1.22.x | 6.2 |
| v1.20-v1.21.0 | 6.1 |
| v1.19.x | 6 |
| v1.12-v1.18 | 5 |
| v1.11 | 4 |
| v1.9.3-v1.10 | 3 |
| v1.9-v1.9.2 | 2 |
| v1.5.1-v1.8.7 | 0 |
.mpy文件的二进制编码结构
.mpy文件采用二进制容器格式,代码对象(字节码和机器码)以嵌套层次结构存储。整体结构分为三部分:
- 文件头:包含版本和架构信息
- 全局qstr和常量表:存储所有字符串引用和常量
- 模块外层代码:模块导入时执行的代码
文件头结构
| 大小 | 字段描述 |
|---|---|
| 1字节 | 固定值0x4D('M') |
| 1字节 | .mpy主版本号 |
| 1字节 | 架构和子版本号 |
| 1字节 | 小整数位数 |
全局qstr和常量表
这部分包含整个.mpy文件共享的字符串和常量引用:
| 大小 | 字段描述 |
|---|---|
| 变长整数 | qstr数量 |
| 变长整数 | 常量对象数量 |
| ... | qstr数据 |
| ... | 编码后的常量对象 |
原始代码元素
每个代码元素包含字节码或机器码:
| 大小 | 字段描述 |
|---|---|
| 变长整数 | 类型、大小和子元素标志 |
| ... | 代码内容 |
| 变长整数 | 子元素数量(如果有) |
| ... | 子代码元素 |
调试.mpy文件
可以使用mpy-tool.py工具来检查.mpy文件内容:
./tools/mpy-tool.py -xd myfile.mpy
这个工具可以显示.mpy文件的结构和内容,对于调试和验证文件非常有用。
总结
.mpy文件是MicroPython中重要的预编译代码格式,了解其结构和版本兼容性对于开发和部署MicroPython应用至关重要。通过合理使用.mpy文件,可以提高代码执行效率并保护源代码。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



