STM32F0代码区跳转
在此我们以STM32F0为例,就芯片内不同程序区的跳转问题做些互换与先容,限于篇幅,这里仅直接先容详细操作和把稳事变,不做过多拓展先容。干系知识点可阅读STM32芯片参考手册、STM32干系内核编程手册。 下面先容中提及的集成编译环境是指ARM MDK,硬件基于STM32F072RB Nucleo开拓板。后面我将逐一先容不同跳转操作的基本流程和把稳事变,涉及以下三种情形:
从【BOOT区】跳转到【APP区】
从【APP区】跳转到其余新【APP区】
从【APP区】跳回【BOOT区】
一样平常来讲,不同区段的实行代码我们通过建立不同的工程项目来实现,终极将不同区段实行代码写入芯片。这里假定BOOT区对应的内部FLASH地址段为0x8000000—0x8004000, APP1区对应的内部FLASH地址段为0x8004000—0x8008000, APP2区对应的内部FLASH地址段为0x8008000—0x800C000。
从【BOOT区】跳转到【APP区】
先说从BOOT区跳转到APP区。这个跳转代码比较简洁、大略,把稳跳转前要关闭刚才程序区开启过的所有中断使能,担保所有中断要求位都被打消,不是大略的关闭总中断,否则每每隐患多多。BOOT区干系跳转代码如下:
If ( Jump_Condition Satisfied )
{
if((((__IO uint32_t)APPLICATION_ADDRESS_APP) & 0x2FFE0000) == 0x20000000)
{ / Jump to user app /
JumpAddress = (__IO uint32_t) (APPLICATION_ADDRESS_APP + 4 ;
JumpToApplication = (pFunction) JumpAddress;
__set_MSP((__IO uint32_t) APPLICATION_ADDRESS_APP); JumpToApplication();
}
}
这个从BOOT区到APP区的跳转终极能否成功,关键还是取决于APP区代码干系配置及准备事情。假设这里的APP区是上面提到的APP1区,内部FLASH地址段为0x8004000—0x8008000,那么在MDK的option项里的memory配置板块要做精确配置,即flash空间与ram空间的配置,如下图所示: IROM1的配置便是APP1代码摆放的起始空间地址及长度。IRAM的配置要把稳先保留48个字的空间用来存放中断矢量表的内容。由于stm32F0芯片的中断矢量表的大小便是48个字(即0xc0字节)。至于剩下的内部RAM空间大小由芯片本身的RAM容量决定(这里是基于STM32F072RB芯片,其内部RAM总容量为0x40000)。 其余一件很主要的事情便是做中断矢量表的拷贝。在APP1区的main()程序开头部分,将放在flash程序空间起始部分的连续48个中断矢量地址表拷贝到内部RAM的起始地址段。即将矢量表从0x8004000地址开始拷到0x20000000开始的连续48个字空间(前面提到的存储配置正是为了合营这个拷贝操作)。
基于MDK环境的参考代码如下:
#define APPLICATION_ADDRESS4 (uint32_t)0x08004000
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
int main(void)
{
HAL_Init();
SystemClock_Config();
for(i = 0; i < 48; i++) {
VectorTable[i] = (__IO uint32_t)(APPLICATION_ADDRESS4 + (i<<2));
}
/ Enable the SYSCFG peripheral clock/
__HAL_RCC_SYSCFG_CLK_ENABLE(); //使能SYSCFG外设
__HAL_SYSCFG_REMAPMEMORY_SRAM();//将内部SRAM 映射到 0x00000000地址 。 ..............后面为用户功能代码。
}
上面代码中绿色语句便是实现中断矢量表从内部flash到内部RAM的拷贝,而赤色语句则是为了实现将程序实行的0地址域的重映射,即将程序运行的0地址从内部flash的0x8000000通过重映射机制切换到0x20000000,为的是在APP1区发生中断时CPU能从精确的地方准确获取相应中断矢量地址去实行中断做事程序。 到此,从BOOT区跳转到APP1区就算完成了。
从【APP区】调转到新【APP区】
那么,如果想从APP1区跳转到其余APP2代码区呢?这个跟从BOOT区跳转到APP1区类似。在APP1区的跳转代码这里就不说了,地址给对、代码写对就好。APP2区的代码也同样必须做中断矢量表的拷贝和0地址域的重映射。但由于在APP1代码里已经做过了0地址的重映射,以是就不必重复做了。 假定APP2代码区的内部flash空间安排在为0x8008000—0x800C000。
则MDK里memory布局配置如下:
从【APP区】跳转到【BOOT区】
有时我们还希望或须要程序能从APP区跳回用户BOOT区,那如何操作呢?对付STM32F0芯片而言,程序实行区从APP区跳回BOOT区跟从BOOT区跳到APP区还不太一样,常常有人在这个跳转过程中卡壳,对付跳得出而跳不回感到难以理解。 假设从APP2区跳回BOOT区,在APP2区做跳转准备时除了给定精确的跳转地址外,另一个要做的便是将之前通过重映射将0地址程序空间从内部SRAM切换回内部flash区。实际运用中,我们每每由于忽略了这点,跳回去后一碰到中断就问题来了。其余,从APP区跳回BOOT区无须矢量表的拷贝操作。以是在APP2区实行跳转前需将0地址重映射回内部flash空间,通过运行如下库代码完成:
__HAL_SYSCFG_REMAPMEMORY_FLASH();
几点主要履历总结:
通过以上几种不同情形下操作过程的描述,我们可以知道,想要避免STM32F0在代码调转中出错,该当遵照以下几条关键的履历:
从【BOOT区】跳转到【APP区】,在【APP区】要做中断矢量表的拷贝和将0地址从内部flash切换到内部SRAM起始地址。
从【APP区】跳转到其它新的【APP区】,只需在新的【APP区】的代码里再做中断矢量表的拷贝,并担保干系存储配置的精确。
从【APP区】跳回【BOOT区】,该过程无矢量表的拷贝,只需将0地址实行域重新映射回内部flash区。
不论从什么区跳往什么区,跳转前禁用当前用户打开过的所有中断使能、确保无未处理的中断要求存在或在跳转过程中发生中断。
以上操作流程紧张针对基于 COMTEX M0 内核的 STM32F0 系列芯片。
以上文档信息来自ST官方文档。