图片00
IROM1:
0x80000000,flash的起始地址
0x80000000~0x80002000,合计8k的空间,bootloader程序
0x80002000~0x80040000,合计256k的空间,256k的flash
IRAM1:
0x20000000~0x20010000,合计64k的空间,运行内存
ROM主要指:NAND Flash,Nor Flash
RAM主要指:PSRAM,SDRAM,SRAM,DDRAM
Keil/MDK 小知识点,Program size: Code, RO-data , RW-data, ZI-data 解释。
图片01
最近编译STM32时,发现内存空间不够了如下图所示:(这里用的芯片型号是
STM32F107VCT6,Flash是256k,RAM是64k
)
图片02
将源码中的全局变量部分注释掉:
图片03
编译之后:
图片04
此时再次打开一个64字节数组:
图片05
然后重新编译一下:
图片06
图片06和图片04两者比较一下可以看到,①②③中的Code、RO-data、RW-data存储字节没有变化,变化的是④ZI-data(
64608-64544=64
),刚好增加了64个字节的数据。
将该数组改为常量数组
图片07
重新编译得到:
图片08
通过图片08和图片06进行比较,可以看到:
470行的Call_Array14[64] = {0},这个数组的数据原来是保存在ZI-data中,现在是保存在
RO-data:
64608-65444=64
byte
而RO-data:
3814-3750=64
byte,同时增加了64个字节
讲到这里,先要对Code、RO-data、RW-data、ZI-data所表示含义解释一下:
Code
,
是指代码占用的空间、程序代码部分、储到flash[ROM]中的程序代码。(
这里flash只是占用了125k,远远少于256k
)
RO-data
,
Read Only 只读常量的大小,如const temp等、RO是程序的指令和常量,这些值都被保存到ROM中去,也就是flash中。(
这里是3750个字节,3.7k
)
RW-data
,
(Read Write) 初始化了的可读写变量的大小、
表示已初始化的全局变量、已经赋过值的。(
这里RW-data是880个byte
)
ZI-data
,
(Zero Initialize) 没有初始化的可读写变量的大小。就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。
ZI-data不会被算做代码里因为不会被初始化;(
这里
ZI-data是64608个字节
)
而程序在烧写的时候是FLASH中的被占用的空间为:Code + RO-Data + RW-Data
程序运行的时候,芯片内部RAM使用的空间为: RW-Data + ZI-Data
为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
ROM(Flash)中的指令至少应该有这样的功能:
1.将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中(存在RAM中)
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中(存在RAM中)。
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。
由此可以看到RW-data+ZI-data = 64608+880=65448byte,合计是63.91K多,接近64K的RAM空间。
这里原本是希望定义64*24=1536个字节的的全局变量(RW-dada),同时通过程序又可以进行随意的修改,但是RAM空间已经不够(RAM=ZI-data+RW-data)。
根据上面的分析可以知道,RW-data的数据也会存在ROM中的。
所以只能把这1536个Byte字节的数据直接放在ROM中,如:EEPROM,Flash等都可以,同样通过程序可以进行修改。
具体操作另行分析。