在阅读国民技术A455系列的用户手册时发现该系列有一块大小为16KB的R-sram(Retention SRAM)有点特殊,除去常规SRAM存放程序执行过程中的变量和数据、堆栈的功能外,还可以在STOP2模式下保存数据。
本文旨在验证Rsram在STOP模式保持数据的特性。本文使用的开发板为N32A455REL7 EVB001 V1.1。
使用的SDK版本为1.1.0,主要使用的为PWR中的STOP2例程。
根据手册N32A455REL7的Rsram地址范围为0x2002 0000~0x2002 3FFF。
keil前期准备
验证的大概思路是在Rsram的固定地址写入一个数据,使用MCU进入stop2模式,MCU从STOP2模式下唤醒后,使用keil查看之前的地址的写入的数值是否还保留。由于MCU在进入STOP2模式后,Jlink与MCU的连接会丢失。且jlink连接上芯片后芯片后进行复位,之前的状态会丢失。
所以首先需要将keil设置成连接芯片后不会进行复位,能够直接进行调试。
1.在编辑器中填入以下内容LOAD %L INCREMENTAL,重命名为debug _itm.ini。
2.去掉Load Application at Startup勾选
3.选择刚刚编辑的调试文件
4.在debug页面去掉Reset after Connect的勾选,使jlink在连接后不对MCU进行复位。
5.去掉update Tamget before Debugging勾选
指定栈范围
如果在默认不修改栈范围和地址的情况下,打开startup_n32a455.s,其中:
栈的大小是0x00001500,即5376 字节。双击工程名可以打开Map文件,可以看到:
__initial_sp指向的地址是0x20001508(至于为什么不是0x20001500,而是0x20001508,可能是栈的操作是8字节对齐?),结合我们之前得到Stack_Size为0x00001500。这个可以我们知道栈的空间为0x20000008~0x20001508.根据手册这段地址在SRAM上。
接下来需要将栈的空间指定到0x20022000~0x20023000 ,也就是R-SRAM的地址范围内,大小为0x1000。
打开startup_n32a455.s,修改Stack_Size、ADDR_STACK_END、ADDR_STACK_START如下所示:
打开Linker页,去掉Use Memory Layout from Target Dialog的勾选,重新编译文件,会生成一个后缀后.sct的散列文件。
未修改的文件应该是这样,只有一个RW_IRAM1
需要增加一个RW_IRAM2,将其改为:
重新编译工程,打开Map文件,查看__initial_sp指向的初始地址。因为栈是向下生长,即从大地址到小地址,所有0x20023000为最大的地址,
将数据存入R-SRAM
PWR中的STOP2例程流程是,MCU上电后,在一小段的延时后就会进入到STOP2模式,此时可以通道PA0的按键中断唤醒。
在常规的SRAM的0x20010000写入0xA5A5A5A5:
通过调试可以看到数据已经被正确放入预设的地址
运行到PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI);时,MCU进入STOP模式,此时会丢失与jlink的连接。
触发PA0的按键中断,重新点击仿真,由于之前的设置,此时jlink不会让MCU restart。而是直接从程序运行位置开始调试。
可以看到之前存在SRAM的0x20010000的0xA5A5A5A5数据已经丢失!这符合预期。SRAM 在 Stop2 模式下数据不能保持。
在R-SRAM的0x20023000写入0xA5A5A5A5
通过仿真可以看到该地址已经被正确写入预设值
与之前的操作一样,运行到PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI);时,MCU进入STOP模式,此时会丢失与jlink的连接。触发PA0的按键中断,重新点击仿真,由于之前的设置,此时jlink不会让MCU restart。而是直接从程序运行位置开始调试。
仿真查看0x20023000地址,发现0xA5A5A5A5仍然保持!
将全局变量存放入R-SRAM的操作也类似。将0x123456存入0x20022F00。
在Map文件中可以得到确认,globalVariable即0x123456存入0x20022F00。
在STOP2中唤醒后该地址的数据同样得到了保持.
这样就验证了R-SRAM 中的数据在STOP2模式下也能正常保持。