STM32 boot和app之间的数据传递
总之,在stm32中有通过备份SRAM(备份寄存器)的方式来进行存储数据,也可以在编译链接过程中划分出一块不会占用的空间来进行存储数据,这和备份SRAM是效果一样,只要板子不掉电,ram中的数据就不会丢失,当然备份SRAM可以由VBAT进行供电,哪怕板子掉电,备份域中的数据也不会丢失,这是SRAM比不了了,当然也由于这个性质,备份SRAM的较为珍贵,如果备份SRAM不够使用,F1系列的备份寄存器只
STM32 boot和app之间的数据传递
-
背景
在一个项目中,我们需要获取stm32单板的复位原因,复位原因通过查询寄存器的方式就可以实现,但是这里出现了个问题,在boot阶段会重置一下这个寄存器,重置的操作是位于一个HAL库函数中实现的,本来我是打算在重置之前,把寄存器值读出来,重置后再写回寄存器。这在F1和F4中是可以实现的,这个寄存器是可读可写,但是我们使用的平台是F7系列,这个寄存器只是可读,不能被更改,所以要么修改HAL函数,要么有其他方式讲结果从boot传递到app。修改HAL库函数属实属于下策,不利于移植和兼容性。
1. boot和app之间的数据传递方式
-
外部存储
通过外部存储,比如e2prom和外部flash方式实现,这种方式没啥好说的,boot和app都要实现相应的驱动,商定读写位置即可。
-
内部flash
这里和外部flash类似,但是并不建议使用内部flash进行传递数据,内部flash擦写次数有限,而这里每次启动都需要传递一次数据,也就要擦写一次,并不建议这样做
-
备份sram和备份寄存器
在F4和F7系列中,有4K的备份SRAM,在F1系列中有84字节的备份寄存器,备份SRAM的访问需要一些步骤来使能。
- F4/F7 BKPSRAM
-
F1 备份数据寄存器
-
编译链接过程中划分出一块不会占用的SRAM空间来进行存储数据,本文将重点讲解这一块内容。
2. 通过SRAM方式来传递
如果在SRAM中留出一块空间给boot和app之间进行数据传递,也是一个不错的方式。
SRAM中开头部分是各种数据段,想.bss段和.data段就在SRAM的开头部分,在SRAM的结尾部分是堆栈位置,栈顶指针指向了SRAM的结尾。
所以这里有两种方式来实现预留空间,一个是开头部分,一个是结尾部分。开头部分需要定义一个数据段占用SRAM开头也就是0x20000000,结尾部分则需要修改栈顶指针
-
预留SRAM头部空间
预留头部空间需要在SRAM头部定义一个数据段出来,(其实不定义也可,直接指针偏移,也能达到同样效果)
- 在链接脚本(.ld文件).data之前添加一个数据段,这个长度是0x100的数据段
- 从map文件中看到这个数据段,长度为0x100,地址是0x20000000,也就是SRAM开头部分
-
预留SRAM尾部空间
预留尾部空间则需要修改栈顶指针,在STM32链接脚本和启动文件中,栈顶指针是有RAM起始地址+RAM长度计算得来的,所以我们只需要将RAM长度修改,自然可以将栈顶指针位置做出修改。
- 原map文件的堆栈指针指向sram尾部0x20005000
-
在链接脚本中,将20K修改为18K,使得预留出2K的空间出来
-
在map文件中可以看到栈顶指针已被修改
-
其实预留头部空间时,也可以修改堆栈起始地址和堆栈长度来实现,.data段的起始地址也发生了偏移,Sram的头部空间的2K就被保留了下来
3. 总结
总之,在stm32中有通过备份SRAM(备份寄存器)的方式来进行存储数据,也可以在编译链接过程中划分出一块不会占用的空间来进行存储数据,这和备份SRAM是效果一样,只要板子不掉电,ram中的数据就不会丢失,当然备份SRAM可以由VBAT进行供电,哪怕板子掉电,备份域中的数据也不会丢失,这是SRAM比不了了,当然也由于这个性质,备份SRAM的较为珍贵(F1系列的备份寄存器只有84Byte),如果备份SRAM不够使用,可以在SRAM中划分空间存储,不过从移植的角度来看,还是使用备份SRAM更为便捷。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)