微软|嵌入式开发:在MicroPython中优化堆的5个技巧

微软|嵌入式开发:在MicroPython中优化堆的5个技巧

文章图片

微软|嵌入式开发:在MicroPython中优化堆的5个技巧

多年来 , 嵌入式软件开发人员一直在PC端使用Python与嵌入式系统进行交互 。 在过去的几年里 , Micro Python , 一种可以在微控制器上运行的Python端口 , 越来越受欢迎 。 Python开发人员可能很想构建和编写他们的Micro Python代码 , 类似于他们在PC上编写Python的方式 。

Micro Python虽然非常强大 , 但仍然可以在资源受限的设备上运行 , 这意味着开发人员需要小心他们如何编写Python代码 。 最大的潜在问题与堆、内存碎片和内存不足有关 。 以下是开发人员可以遵循的几个技巧 , 以优化他们的堆使用并从他们的Micro Python应用程序中获得最大收益 。
技巧1 – 使用mem_info监控堆
Micro Python在micropython库中包含一个名为mem_info的内存监视器 。 调用 mem_info将为开发人员提供堆状态 , 以便他们可以确定有多少可用空间以及可以提示堆碎片程度的基本诊断 。 开发人员从一开始就可以做的最好的事情是使用 mem_info监视堆 , 以了解他们的软件如何影响堆 。 基本的mem_info输出如下所示:

当基本信息不够时 , 开发人员可以请求详细列表 , 其中提供了堆使用方式的详细地图 。 一个例子可以在下面看到:
【微软|嵌入式开发:在MicroPython中优化堆的5个技巧】
技巧2 – 将模块编译成冻结字节码
当开发人员创建Micro Python应用程序时 , 他们正在创建由Python解释器在运行时执行的脚本 。 在运行时处理脚本不仅会占用堆空间 , 还会导致堆碎片化 。 开发人员可以在他们的应用程序代码中获取模块并将其交叉编译成字节码 , 该字节码与内核代码一起存储在闪存中 。 创建字节码将导致模块代码从闪存执行 , 而不是从堆中执行 。 结果是使用的堆空间更少 , 并且堆碎片减少 。 常量值和字符串也可以预编译成冻结字节码 , 以防止它们占用不必要的RAM 。
技巧3 – 使用const()
与生成可能由其他模块导入的变量的查找相关的RAM可以通过几种方式保存 。 首先 , 开发人员可以使用位于micropython库中的const() 。 开发人员可以通过以下方式使用const():
A = const(0x100)
其次 , 在变量名_A前添加下划线作为前缀 , 可以防止将变量添加到字典中 , 并节省一些RAM字节 。 虽然一开始节省的费用似乎很少 , 但在可能有数百个变量的大型应用程序中 , 节省的费用很快就会增加 。
技巧4 – 预先分配通信缓冲区
使用Python的好处是可以根据需要在代码中动态创建缓冲区 。 例如 , 从USB设备读取数据时 , 开发人员可能会编写类似于以下内容的代码:
while True:
data = https://mparticle.uc.cn/api/usb.read(64)这个应用程序的问题是 , 每次读取数据时 , 都会在堆上创建一个新的64字节缓冲区 , 这为堆提供了碎片化的可能性 。 相反 , 开发人员可以通过执行以下操作预先分配缓冲区:
buffer = bytearray(64)
while True:
usb.readinto(buffer)
此应用程序代码将一遍又一遍地使用相同的缓冲区 , 而不是不断地创建和销毁堆上的缓冲区空间 。

技巧5 – 定期调用gc.collect
Micro Python有一个垃圾收集器 , 它会定期运行以将超出范围的对象返回到堆中 。 虽然垃圾收集是自动的 , 但有时开发人员定期手动调用gc.collect或在初始化应用程序代码后调用它会很有用 。 在gc.collect调用之前调用mem_info总是很有用的 , 然后立即查看有多少内存返回到堆中 。