
对于 STM32 用户,经常会涉及到通过用户启动程序实现对用户应用程序的更新升级。一般来讲,用户启动程序主要用来跟外界通信,获取新的用户程序代码并实现对用户代码区的应用程序升级。用户应用程序是指实现各种用户功能的代码。 在这个过程中,往往需要做从用户引导程序区(以下简称【BOOT 区】)到用户应用程序区(以下简称【APP 区】)的跳转,有时可能还需实现从用户应用程序区跳回到用户启动程序区,甚至不同用户程序区的互相跳转等操作。在这些跳转过程中,常常有人的开发工作在此遇到阻碍,甚至破费周折。 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= *(__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 区就算完成了。 完整版请查看:附件 |
Jumping topic about different procedure code zone based on STM32F0.pdf
下载565.26 KB, 下载次数: 1