Python变得越来越流行,现在实时嵌入式软件开发人员可以通过Micro Python在微控制器上访问Python,开发人员了解Micro Python堆比以往任何时候都更重要。嵌入式开发人员需要了解几个与堆相关的库和内核选项。
首先,并非所有的Micro Python端口都充分利用了微控制器中可用的RAM空间。Micro Python最初是为具有128 KB RAM的STM32F405开发的。大多数端口以STM32F405作为默认模板,这意味着堆仍然只能分配到0x1C000字节。这看起来似乎有很多堆空间,但是Python解释器在运行时使用堆来分配对象和处理脚本,所以可用的堆空间越多越好!
开发人员可以在他们的内核链接器文件中查找变量_heap_end。该变量的大小应与微控制器的RAM大小相匹配。例如,STM32F405的RAM为128 kB,has _heap_end = 0x2001C000。使用STM32F429等具有192 kB RAM的器件的开发人员会希望确保_heap_end = 0x2002C000。为堆分配额外的0x10000 64 kB内存。进行这种调整可以防止脚本中出现内存不足的错误。
即使嵌入式开发人员有很多堆空间,他们也会希望定期监控他们的堆空间使用情况,以确保堆得到有效使用。当Python解释器执行它的脚本时,对象将被创建和销毁。有一个垃圾收集器可以回收被丢弃的对象,但有时它运行得不够快。随着时间的推移,堆会变得非常零碎,几乎无法使用。开发人员可以通过导入gc库并调用collect方法来强制垃圾回收。
Import gc
gc.collect()
在执行期间,可以使用mem_info方法密切监视Micro Python的内存使用情况。调用mem_info()将打印出基本信息,如堆栈使用情况、总堆空间、已用堆空间,甚至可用块数。当开发人员使用详细模式(传入1)调用mem_info时,事情变得非常有趣。当这种情况发生时,仍然提供基本信息,但是也打印出堆如何被使用的完整输出。
嵌入式开发人员不能忘记,即使Python运行在微控制器上,他们编写代码的方式也可能会产生实时和内存后果。从内存的角度来看,在开发过程中使用mem_info是一种很好的方式,可以监控堆的使用情况,以及堆是否会分裂到试图分配另一个对象最终会失败的程度。