移植micropython的最小工程到lpc5500微控制器

本文介绍如何将MicroPython移植到NXP的LPC5500微控制器上,涵盖修改Makefile、调整内存布局、初始化硬件、对接UART串口等关键步骤。

移植micropython的最小工程到lpc5500微控制器

概述

micropython目前主要支持的平台是STM32系列微控制器(STM32F407),但也逐渐补充了别家的芯片,几乎覆盖了市面上常见的微控制器架构。STM32系列微控制器在其中作为ARM Cortex-M内核微控制器的代表,可以作为在其它ARM Cortex-M内核微控制器移植的模板。甚至代码库里提供的“minimal”工程就是以STM32微控制器为平台进行演示的。

我手头有一些NXP的板子,比如最近在社区里比较流行的lpc55s69-evk,我想试着在原生开发环境中将micropython的移植到基于ARM Cortex-M33内核的lpc5500的芯片上。一方面通过移植的过程学习一下micropython代码,另一方面也希望通过micropython实现对微控制器系统硬件操作的封装,便于以后做点有意思的小东西。毕竟我不愿意把大量的时间放在重复阅读寄存器说明书上,一直跟底层的电路较真也是比较烦的,但用python写程序确实很方便。然而,最终的目的还是考虑get到micropython这个在微控制器上运行“编译器”的技术,以后在必要的情况下可以把它用起来。

在这里插入图片描述
本文记录了我在原生开发环境中,从零开始创建一个基于lpc5500微控制器的最小工程的过程,包括调试过程中遇到的一些问题和解决方法,方便自己日后查阅,也与其它开发者共勉。

上文书说到,我已经在Windows系统中搭建起micropython的原生开发环境。https://blog.youkuaiyun.com/suyong_yq/article/details/112797556

创建最小工程的目标,就是要实现可以使用UART串口终端同板子上运行的micropython进行交互。具体来说,就是要基于lpc5500微控制器的链接命令文件、启动代码、驱动程序,替换掉模板工程中关于具体芯片底层的部分,编译通过,能够将log输出到UART串口并收到终端输入,最后通过运行python语句验证micropython已经在板子上正常运行。

我之前在早期版本(v1.9)中,尝试过基于之前做平衡小车的主板(基于NXP KE18F,ARM Cortex-M4内核)进行过移植。当时相关的移植指导文档也很少放出来,我是基于“ports/minimal”和“ports/bare-arm”工程进行替换和改装,很多底层驱动的代码都是自己一边读手册一边码出来的,自己一点一点摸索着完成。由于当时我对micropython代码的理解比较浅,所以至今很多必要的调用流程都没搞明白是干啥的。经过这两年的积累,官方有越来越多的文档发布出来。通过进一步的研究,我也了解到了一些开发micropython的规范。刚好在近期发布的版本(v1.13)中,我看到了micropython的代码库里已经添加了对部分NXP imxrt系列微控制器的支持(Teensy 4.0板子的主控芯片是imxrt1062),其中使用了tinyusb组件实现usb的功能,而tinyusb引用了一个精简版的NXP MCUXpresso SDK的驱动代码仓库,这个代码仓库里不仅有NXP mimxrt的驱动程序,还顺带包含了NXP lpc5500系列和NXP lpc54100系列微控制器的驱动。就这么通过连带关系,micropython代码仓库中实际已经包含了lpc5500系列微控制器的驱动程序,为我在lpcxpress55s69板子上展开移植提供了必要条件,这样我就不需要专门从MCUXpresso SDK中提取驱动代码了。同时,micropython官方对imxrt平台的支持,也为其它同属nxp mcuxporesso sdk支持平台芯片的移植提供了范例。套用参考工程对SDK的文件组织方式,替换文件更有针对性,这样可以少走很多弯路。所以,本次移植到lpc5500平台时,更多还是参考了“ports/mimxrt”下面的组织框架。

修改Makefile,替换芯片相关文件

首先,我还是在“ports”目录下复制了一份“minimal”工程的目录,重命名为“lpc5500”,后面移植代码的具体工作都将在这个目录下完成。

这个时候我还是习惯性地make了新创建的“lpc5500”工程,虽然它目前还是基于stm32f405微控制器的,并且肯定能编过(上文已经介绍了编通的过程)。但这个仪式感是一定要有的,因为后续要有很长一段时间这个目录下的工程是不能再编通的。等到它再次通过编译的时候,就是云开月明山花烂漫之时。

接下来打开“Makefile”,开始替换里面引用的文件路径,将与stm32相关的文件替换成lpc5500的。我之后90%的工作都是在调这个Makefile,个中细节就不详述了,本来以为最多一个小时的事情,我前前后后折腾了3个晚上才调通。在本文中,我把几个重点拉出来单独聊聊,至于整体文件,我会把完整的代码库分享出来,到时候感兴趣的同行可以下载研究,或者直接使用即可。

主要做的几个事情:

  • 替换linker文件。
  • 替换编译选项,从stm32的cortex-m4替换的lpc5500的cortex-m33。
  • 添加必要的驱动文件和启动代码文件的搜索路径
  • 删除不必要的源文件,并添加必要的源文件
  • 调整make规则,删除不必要的操作步骤。

调整linker文件

调整linker文件实际上是确定对芯片存储空间的使用安排,特别是对数据区、堆和栈空间的安排。

linker文件还是使用SDK的原版“LPC55S69_cm33_core0_flash.ld”文件作为模板,但是我考虑要调整其中的内存分块,并且要精简掉不必要的分区,所以单独复制出一份放到“lpc5500”项目的根目录中,便于自己随意改动。

先看一眼lpc55s69芯片的内存资源:
在这里插入图片描述

其中从0x2000_0000开始的常规SRAM就有256KB,16KB的PowerQUAD专有内存就不去碰了,从0x1400_0000开始的32KB内存我一开始没好意思用,后面考虑把data(和bss)部分和工程自带的堆放进去,然后把256KB的常规SRAM空间全部预留给栈空间和给micropython的gc内存管理器使用。

这里有个知识点,关于micropython工程的内存使用情况:

  • micropython管辖的内存主要是整个系统的栈空间(用来动态编译的放字节码)和gc管理的私有堆空间(存放micropython运行过程中创建的对象)。micropython在运行的初始阶段就要通过代码指定其管辖的栈内存区域和私有堆空间。
  • micropython管辖之外的系统层面上使用的数据,例如一些进入micropython之前的硬件初始化函数,系统库函数等使用的数据,一部分放在系统栈空间(micropython会让出这部分栈空间),另一部分放在系统堆空间中(很少)。
  • micropython对接底层驱动时,在编写C代码过程中,例如驱动程序,创建的全局变量将会放在系统的data段(或者bss段)中,局部变量同micropython常规的函数调用一样,存放在系统栈中。

按照这个原则,在linker文件中进行调整,我的改动包括如下:

将常规SRAM分成两块

/* Specify the memory areas */
MEMORY
{
   
   
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000140
  m_text                (RX)  : ORIGIN = 0x00000140, LENGTH = 0x0009D000
  m_data                (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00020000
  m_data2               (RW)  : ORIGIN = 0x20020000, LENGTH = 0x00020000
  m_usb_sram            (RW)  : ORIGIN = 0x40100000, LENGTH = 0x00004000
}

我将常规SRAM分成了m_data和m_data2两块,都是128KB大小。m_data打算用来存放data(bss)和栈,m_data2整块给GC作为micropython的私有堆空间。

原始版本中的用于多核通信的共享内存区域和预留存放双核系统中另一个核的text段被合并到现有区块中,因为micropython中暂时用不到,所以就精简掉了,后面对应区块的定义也可以删掉。至于m_text区域为啥没有填满整个640KB的空间,而是只用了大约630KB的空间,也是参考了手册中关于内存分布情况的说明(见上图),最后这10 KB的空间是预留的,这个可能存放了一些同芯片硬件配置相关的一些数据,总之不要碰它就好。

增大栈的大小

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值