MCU SRAM 上电初值:0x00、0xFF 还是随机值?
前几天有工程师问了我一个问题:MCU 的 SRAM 在上电复位后、程序还没开始初始化之前,里面的值是什么?是 0x00、0xFF 还是随机值?
说实话,这个问题以前还真没认真细究过。借着这个疑问,我实际做了一次测试。
一、测试方法及结果
要测出“上电瞬间”SRAM 的原始状态,首先得保证上电后没有用户代码抢先执行。否则启动代码里的 .bss 清零、.data 搬移等操作都会改写 SRAM,读到的就不是上电那一刻的原始数据了。
测试步骤如下:
1)将 MCU 内部 Flash 全部擦除,确保上电后没有用户代码可运行;
2)通过 J-Link Commander 连接 MCU,再读取 SRAM 区域的数据;
3)完全断电后重新上电;
4)再次用同样的方式连接并读取 SRAM 数据。
第一次测试结果如下:
第二次测试结果如下:
两次上电后读到的 SRAM 数据明显不同,不过也有部分内容相同。
这说明 SRAM 在上电时的状态并不是某个固定值:不是全 0x00,也不是全 0xFF,而是一组不确定的随机数据。至于“部分内容相同”也正常。
二、为什么 SRAM 上电后是随机的?
SRAM 是易失性存储器,断电后,供电电压消失,存储节点上的电平失去维持,数据随即丢失。重新上电时,电源电压从 0V 开始爬升,在这个电压建立的过程中,每个存储单元最终倒向“0”还是“1”,会受到晶体管阈值偏差、上电斜率、内部噪声等因素影响。也就是说,每一位的初态在物理上都是随机的,硬件并不能保证它是 0x00 或 0xFF。
这和 Flash “擦除后固定为 0xFF” 不一样——Flash 的 0xFF 来自浮栅被统一置位,而 SRAM 并不存在类似的“擦除态”。
三、那“全局变量默认是 0”怎么理解?
平时调试时确实经常看到 RAM 里一大片 0x00,但这和“上电随机”并不矛盾。
我们常说的“未初始化全局变量默认是 0”,通常是指 .bss 段。这个“默认值 0”并不是 SRAM 在上电那一刻天然就有的,而是 C 运行时启动代码在进入 main() 之前主动做出来的:
另外补充两点:
1)软件复位、看门狗复位这类不掉电的复位,SRAM 内容一般会保留,而不是重新随机;
2)部分带 ECC/Parity 校验或安全启动机制的 MCU,硬件或 Boot ROM 可能在上电后自动将 SRAM 清零,这属于特定芯片特性,并非通用规则。
所以,工程上不要依赖 SRAM 的“默认值”,所有变量显式初始化才是最稳妥的做法。
40