前言
开始记录工作和学习中遇到的问题了
工作一两年,用的最多且一直在用的也就是C了,以后会定期更新一些博客,一是记录一下遇到的问题,再一个就是记录一下当时解决问题的思路和过程,也给自己以后想不起来的时候提供一下思路👌!本篇就记录一下在新项目使用stm32时遇到的一个问题,以及后续的解决方法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、RAM内存检测
项目中对RAM的安全性能有需求,所以在MCU上电时候需要对RAM进行上电自检,程序运行过程中也需要周期自检,这也是本篇博客的由来。
二、自检算法
(其实就是一个简单的读写测试,只不过步骤较多罢了)
三.问题描述和分析
1、问题描述
在main函数一进来,就开始调用RAM的上电自检函数,自检的大概逻辑是先将除过堆栈外的RAM清空,然后写入1,再读取上来判断,正确的话再清零。
目前遇到的问题是:一上电后,0x24000000(RAM的起始地址,附件1)后面的bss或者data段会有些许的值,待到RAM自检函数执行完毕,后续的函数调用就会跑飞,单步调试后以后发现是某些值被清空,导致进入了死循环。
使用MDK5作为开发环境,编译后生成的.map文件中对于RAM中的区域划分如下图所示:
对源码进行在线调试,上电后的RAM内存区域:
2、问题分析
这块存在一个比较肉疼的问题:上电自检不备份RAM中原始数据的话,自检完成以后内存区域中的值都会被清空,待上电自检函数执行完毕后,后续的函数中定义的全局量或者一些编译生成的text段的内容就会丢失,从而导致了后续的程序跑飞,接下来就是对RAM中原始内容的保存到局部变量(栈区),自检,然后恢复RAM内容就可以解决了。
//备份即将自检的内存区域
for (i = 0; i < 32; i++)
......
if (0 != RamSelfTestByWord((u8 *)startAddr))
return ......;
//恢复自检完成的内存区域
for (i = 0; i < 32; i++)
......
后来头铁的执行了一下这样操作,上电自检确实没毛病,但是周期自检的时候又暴雷了,由于周期自检时,需要对当前的自检地址和剩余自检区域的大小进行保存,所以对这两个量加了static关键字,没成想直接保存到了堆栈之前的data段中,周期检完一圈后直接清空了地址,恢复备份到这个地址的时候直接HardFault死循环了。后续就是查资料,固定一块地址,专门放这些不能随意变动的全局或者静态量。
3、解决步骤
MDK5中点击魔术棒,然后根据下图所示进行操作:
点开sct文件后,在里面指定一块确定没有使用到的区域,并重命名为sdram_area
在程序中,需要用到这块区域的全局或者静态量,变量后方加入该关键字,系统就可以自动分配到该地址中,不用手动进行管理,示例如下所示:
#define SDRAM_AREA_ATTRIBUTES __attribute__ ((section("sdram_area")))
static u32 g_lastCheckAddr SDRAM_AREA_ATTRIBUTES = 0x24000000 ;//固定的内存地址,用来存放不能被改变的全局变量
总结
以上就是对RAM自检时遇到的一个小问题的分析和解决步骤,肯定也不可能是比较好的一种解决方案,有合适的方法,项目代码后续也会进行优化和更新的,仅供参考。