MCU启动方式
MCU代码启动
为了便于更新代码。MCU开发一种固件升级方式,通过串口来升级固件。通过配置Boot0,Boot1管脚。将Boot0管脚拉高,重新给芯片上电,执行固化在存储介质的代码(bootloader),通过串口下载固件(下载到flash中)。通过Boot0拉低,启动由flash启动,执行新更新的固件。
MCU固件最开始是以.s后缀的文件。是MCU上电之后,最先执行一段的代码。其主要功能是完成堆栈指针的设置,复位向量的获取,重定位,变量初始化。最后跳转到用户代码。
内存映射
不同的内核,会有差异。以32位举例子。
图 1 内存映射图
一共是4G空间:0x0000 0000 ~0xffff ffff
0x0000 0000 最初始的地址。根据BOOT模式,映射到不同的物理内存。
映射到物理内存,取决于boot的配置。
芯片复位,或由待机唤醒之后,根据配置boot,执行不同物理内存的代码:
Boot0为低电平,被映射到Flash Memory,这种模式最常用。Flash Memory区域起始地址0x800 0000
Boot0为高电平,BOOT1为高电平,映射到System memory区域,进入bootloader模式。System memory区域起始地址0x1fff ec00。这部分区域存放bootloader代码,代码与数据是在工厂就固化完成的。
BOOT0为高电平,BOOT1为低电平,映射到SRAM。SRAM区域起始地址0x2000 0000。该区域存放用户变量,堆和栈,代码也可以加载到该区域。
0x4000 0000 Pheriperals芯片集成的外设,USART, SPI, GPIO,IIC ,ADC等的寄存器地址在这一区域。
0xE000 0000 Cortex-M0 internal pheriperals M0内核映射区域,systick,NVIC,Debug都在该区域。
启动代码位置定位:
通过观察内存0x0000 0000 与内存0x800 0000 处的内容:如下图所示
图 2 不同地址内存查看
在地址0x0000 0000 与地址0x800 0000 处的代码内容是一致的。说明被映射到0x800 0000处。
0x0000 0000:初始堆栈指针
0x0000 0004: 复位向量,上电或复位后最先加载入PC
在用户模式下,对应falsh区域中的0x0800_0000,0x0800_0004。
程序在.s文件中,初始化堆栈指针,PC值,初始化SystemInit()函数,获取__main()函数的首地址,跳转执行__main()函数。之后,跳转到用户main()函数。