STMCU小助手
发布时间:2022-8-2 19:45
|
对于 STM32 用户,经常会涉及到通过用户启动程序实现对用户应用程序的更新升级。一般来讲,用户启动程序主要用来跟外界通信,获取新的用户程序代码并实现对用户代码区的应用程序升级。用户应用程序是指实现各种用户功能的代码。% S6 j9 r5 j, b9 x* v) Z 在这个过程中,往往需要做从用户引导程序区(以下简称【BOOT 区】)到用户应用程序区(以下简称【APP 区】)的跳转,有时可能还需实现从用户应用程序区跳回到用户启动程序区,甚至不同用户程序区的互相跳转等操作。在这些跳转过程中,常常有人的开发工作在此遇到阻碍,甚至破费周折。, [3 r5 l3 {! {6 _ 8 C+ @" D5 W8 j1 X% M : t: ]4 p7 [5 \; E* g& l2 n9 l5 u& V+ ] STM32F0 代码区跳转; k$ A, X! j0 k7 c1 d$ y 在此我们以 STM32F0 为例,就芯片内不同程序区的跳转问题做些交流与介绍,限于篇幅,这里仅直接介绍具体操作和注意事项,不做过多拓展介绍。相关知识点可阅读 STM32 芯片参考手册、STM32 相关内核编程手册。 下面介绍中提及的集成编译环境是指 ARM MDK,硬件基于 STM32F072RB Nucleo 开发板。 后面我将逐一介绍不同跳转操作的基本流程和注意事项,涉及以下三种情况:/ n' }6 Y5 f, `0 J9 T 从【BOOT 区】跳转到【APP 区】 从【APP 区】跳转到另外新【APP 区】 从【APP 区】跳回【BOOT 区】 一般来讲,不同区段的执行代码我们通过建立不同的工程项目来实现,最终将不同区段执行代码写入芯片。这里假定 BOOT 区对应的内部 FLASH 地址段为 0x8000000—0x8004000,APP1 区对应的内部 FLASH 地址段为 0x8004000—0x8008000, APP2 区对应的内部 FLASH 地址段为 0x8008000—0x800C000.
1 [- r( d( ^/ O! }0 n) k 从【BOOT 区】跳转到【APP 区】 先说从 BOOT 区跳转到 APP 区。这个跳转代码比较简洁、简单,注意跳转前要关闭刚才程序区开启过的所有中断使能,保证所有中断请求位都被清除,不是简单的关闭总中断,否则往往隐患多多。BOOT 区相关跳转代码如下: If ( Jump_Condition Satisfied ) { if(((*(__IO uint32_t*)APPLICATION_ADDRESS_APP) & 0x2FFE0000) == 0x20000000)4 {) H' E* T+ a' s { /* Jump to user app */ JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS_APP + 4& A6 O# T+ \( T% n; Y' }; } JumpToApplication = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS_APP); JumpToApplication();1 K. c% C/ N5 D# H1 F$ x } 这个从 BOOT 区到 APP 区的跳转最终能否成功,关键还是取决于 APP 区代码相关配置及准备工作。假设这里的 APP 区是上面提到的 APP1 区,内部 FLASH 地址段为 0x8004000—0x8008000,那么在 MDK 的 option 项里的 memory 配置板块要做正确配置,即 flash 空间与 ram 空间的配置,如下图所示:2 h! Y" e# M: Z # t. V3 n3 p9 x$ J% q$ ]$ L
IROM1 的配置就是 APP1 代码摆放的起始空间地址及长度。IRAM 的配置要注意先保留 48个字的空间用来存放中断矢量表的内容。因为 stm32F0 芯片的中断矢量表的大小就是 48个字(即 0xc0 字节)。至于剩下的内部 RAM 空间大小由芯片本身的 RAM 容量决定(这里是基于 STM32F072RB 芯片,其内部 RAM 总容量为 0x40000)。. t0 t) p2 m* T% Q0 I' h. R 另外一件很重要的事情就是做中断矢量表的拷贝。在 APP1 区的 main()程序开头部分,将放在 flash 程序空间起始部分的连续 48 个中断矢量地址表拷贝到内部 RAM 的起始地址段。 即将矢量表从 0x8004000 地址开始拷到 0x20000000 开始的连续 48 个字空间(前面提到的存储配置正是为了配合这个拷贝操作)。基于 MDK 环境的参考代码如下:6 Z8 ^3 L- I1 P$ L" s #define APPLICATION_ADDRESS4 (uint32_t)0x08004000% i1 m- }" y; {9 n __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));+ u9 Y& v$ f( w8 a# R3 g int main(void)$ s7 b: r6 J: t# T8 M2 H/ N { HAL_Init(); SystemClock_Config();$ x4 @. y# z% B for(i = 0; i < 48; i++)7 G2 Y- I% P; k! ] { VectorTable= *(__IO uint32_t*)(APPLICATION_ADDRESS4 + (i<<2)); } /* Enable the SYSCFG peripheral clock*/ __HAL_RCC_SYSCFG_CLK_ENABLE(); //使能 SYSCFG 外设* x; k4 n7 W5 u9 ?, P' p __HAL_SYSCFG_REMAPMEMORY_SRAM();//将内部 SRAM 映射到 0x00000000 地址 。。。。。。 后面为用户功能代码。。。。。。 3 t2 F, Y. O2 m Z" i, N# K 上面代码中绿色语句就是实现中断矢量表从内部 flash 到内部 RAM 的拷贝,而红色语句则是为了实现将程序执行的 0 地址域的重映射,即将程序运行的 0 地址从内部 flash 的 0x8000000 通过重映射机制切换到 0x20000000,为的是在 APP1 区发生中断时 CPU 能从正确的地方准确获取相应中断矢量地址去执行中断服务程序。 到此,从 BOOT 区跳转到 APP1 区就算完成了。 8 v+ C: a% H% l: j3 W9 | 完整版请查看:附件 : {- A+ r1 N4 A , q& U; f! c3 j& f$ p3 O 1 h& `' u4 M4 U4 T& \# i |
Jumping topic about different procedure code zone based on STM32F0.pdf
下载565.26 KB, 下载次数: 1
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
小白也能明白的STM32的低功耗与唤醒机制
STM32系统中2种数据掉电保护的方法
分享STM32F051中文参考手册(重制书签版)
AI工具训练营-用ChatGPT解决HID Keyboard实现的问题
STM32固件库分享,超全系列整理
STM32小白入门指南:从基础到OTA实现方案
STM32超详细学习笔记
新手必看!STM32单片机应该怎么学?
如果你解决了这些问题,就可以直接学STM32
微信公众号
手机版