文章目录[隐藏]
在bootloader时,通常需要单独开辟一块区域用来存放一些变量,并且希望这些变量在发生软件复位(boot和app互相跳转)时不被初始化,这些变量一般用来存放跳转boot的原因(正常上电启动或者从app跳转boot)等信息。对于这种变量的存放方式有两种,一种是使用MCU自带的(模拟/真实)EEPROM,一种是针对变量所在的区域做一些修改,使得这些RAM区域在软件复位时不进行初始化,S32K1中这种功能称为RAM retention。前一种方式之前介绍过,如下链接:
《巧用S32K的模拟EEPROM功能标定参数》 ,本文以S32K144为例,介绍第二种方式。
配置介绍
下面从启动文件,链接文件以及主程序中的设置三方面介绍实现RAM retention的方法。
启动文件
如果对S32K144的启动过程不是很清楚,建议看一下胡工的这篇文章:
首先,需要关闭SRAM的ECC初始化操作,因为该操作会修改SRAM数据。同时,关闭SRAM的ECC初始化的操作需要在软件复位后执行,如下红框是修改部分:
0x40048004是寄存器CHIPCTL的地址,在进入软件复位之前会操作该寄存器,后面主程序部分会有描述,和此处对该寄存器的值进行判断能够对应上。
链接文件
如果对S32K144的链接文件不是很清楚,可以看一下如下这篇文章:
接着在链接文件中设置两个自定义的地址,用来保存需要实现RAM Retention的变量。
主程序
接着在主程序中使用关键字attribute
修饰需要实现RAM retention功能的变量,如下所示:
__attribute__((section (".myRAML"))) uint8_t Led_Color_Flag = 0x00;
__attribute__((section (".myRAMU"))) uint8_t Buffer[10] = {0};
最后在调用软件复位函数之前将CHIPCTL的SRAML_RETEN和SRAML_RETEN两位置0,如下所示:
/*
* This logic ensures that any attempted access to SRAM is blocked
* after these bits are written,
* thereby preventing memory corruption during reset assertion.
* */
SIM->CHIPCTL &= ~SIM_CHIPCTL_SRAMU_RETEN_MASK;
SIM->CHIPCTL &= ~SIM_CHIPCTL_SRAML_RETEN_MASK;
/*SW software*/
SystemSoftwareReset();
结合参考手册CHIPCTL寄存器和SRAM retention章节的描述,将这两位置为0后,可以让RAM的数据在复位过程中不在篡改,同时在复位之后需要改写为1。
至此,主要的修改注意点已经描述完毕。
例程测试
环境搭建
- 开发板:S32K144EVB-Q100
- 开发环境:S32DS for ARM 2.2
功能描述
为了测试RAM retention功能,我定义了两组变量,一组变量使用attribute
修饰,使之固定到自定义的区域,一组变量不做修饰,会被放到.bss段(查看map文件可知)。如下图所示:
然后在主函数中判断一下变量的值是否为期望值,如果不是,就亮一段时间的红灯,同时对变量赋值,然后进行软件复位,然后再次判断变量的值是否为期望值,如果是,就一直亮绿灯。主要代码如下:
测试现象
在下图红框处打上断点,当完成软件复位之后再次执行到该语句时,查看变量,发现处于自定义RAM区域的变量保留了之前的值,而处于bss段的变量被初始化为0了。
退出调试模式,重新上电,LED先亮几秒红灯,然后亮绿灯,且一直保持。重复几次,现象一样,符合预期。
注意事项
笔者在调试RAM retention功能时,总结了一些注意事项,分享给大家。
1. 另一种实现RAM retention功能的方式
想要使用RAM retention功能,不一定需要修改ld文件,也可以按如下方式进行:
- 定义变量如下:
#define SRAMU 0x20006000u
#define SRAML 0x1FFF8600u
uint32_t Temp[2] = {0};
- 主函数的实现方式如下:
2. 自定义RAM区域的地址问题
在ld文件设置自定义地址时,增加了NOLOAD
关键字,主要是为了生成的烧录文件(S19/HEX/BIN)不包含自定义RAM区域的地址,否则无法使用量产工具下载程序。
3. bool类型变量使用RAM retention功能
如果将需要使用RAM retention功能的变量定义为bool类型,在掉电之前该值为true,会发现重新上电之后,该变量的值仍为true。但是,如果掉电之前该值为false,重新上单之后,该值为true。发生该现象的原因笔者并未找到,建议尽量不使用bool类型变量实现该功能。
如果非要使用bool类型,初始化值使用true,主程序中赋值为false,具体如下面两张图,测试结果是OK的。
4. 不使用调试模式进行测试
在测试该例程时,发现重新上电进入debug模式时,自定义区域的变量已经变成了期望值(上电之后并未进行软件复位),和预期结果不符合。但是脱离调试模式,进行的测试结果又是符合预期的。建议读者测试RAM retention功能时离线测试,debug模式下会出现意料之外的情况。
参考资料
- Example S32K144 RAM Retention S32DS.R1 - NXP Community
- S32K1xxRM Rev12.1, 02/2020,官网已是最新的Rev14
- 老王的朋友圈截图
例程分享
本文所使用的例程分享如下:
链接:https://pan.baidu.com/s/155Ok2mU51AMBsaQ9n-XFGg
提取码:89vy
版权声明:本文为CSDN博主「北极熊的脖子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bjxdbz/article/details/122799397
暂无评论