Code/ RO-data/ RW-data /ZI-data
在Keil中编译工程成功后,在下面的Bulid Ouput窗口中会输出下面这样一段信息:
Program Size: Code=6320 RO-data=4864 RW-data=44 ZI-data=1636
代表的意思:
Code :是程序中代码所占字节大小
RO-data :程序中所定义的指令和常量大小 (个人理解 :Read Only)
RW-data :程序中已初始化的变量大小 (个人理解”:Read/Write)
ZI-Data :程序中未初始化的变量大小 (个人理解 :Zero Initialize)
ROM(Flash) size = Code+RO-data+RW-data;
RAM size = RW-data+ZI-data
可以通过.map查看占用的flash和ram大小
相关代码实例:
int a=0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[]="abc"; //栈
char *p3= "1234567"; //在文字常量区
static int c =0 ; //静态初始化区
p1= (char *)malloc(10); //堆区
strcpy(p1,"123456"); //"123456"放在常量区
}
STM32内部映射
ROM(Flash) size :stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同。
RAM size :RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。
Flash中的内容一般用来存储代码和一些定义为const的数据,断电不丢失,
RAM可以理解为内存,用来存储代码运行时的数据,变量等等。掉电数据丢失。
STM32将外设等都映射为地址的形式,对地址的操作就是对外设的操作。
stm32的外设地址从0x4000 0000开始,可以看到在库文件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。
一般情况下,程序文件是从 0x0800 0000 地址写入,这个是STM32开始执行的地方,0x0800 0004是STM32的中断向量表的起始地址。
keil 中的设置
程序的写入地址从0x08000000(数好零的个数)开始的,其大小为0x80000也就是128K的空间,换句话说就是告诉编译器flash的空间是从0x08000000-0x08020000,RAM的地址从0x20000000开始,大小为0x5000也就是20K的RAM。这与STM32的内存地址映射关系是对应的。
M3复位后,从0x08000004取出复位中断的地址,并且跳转到复位中断程序,中断执行完之后会跳到我们的main函数,main函数里边一般是一个死循环,进去后就不会再退出,当有中断发生的时候,M3将PC指针强制跳转回中断向量表,然后根据中断源进入对应的中断函数,执行完中断函数之后,再次返回main函数中。大致的流程就是这样。
STM32内部flash构成
- 主存储器:一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域它是存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个区域的大小。与其它 FLASH 一样,在写入数据前,要先按扇区擦除,
- 系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、 USB 以及 CAN 等 ISP烧录功能。
- OTP 区域:OTP(One Time Program),指的是只能写入一次的存储区域,容量为 512字节,写入后数据就无法再更改, OTP 常用于存储应用程序的加密密钥。
- 选项字节:选项字节用于配置 FLASH 的读写保护、电源管理中的BOR 级别、软件/硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器修改。
查看工程内存分布
由于内部 FLASH 本身存储有程序数据,若不是有意删除某段程序代码,一般不应修改程序空间的内容,所以在使用内部 FLASH 存储其它数据前需要了解哪一些空间已经写入了程序代码,存储了程序代码的扇区都不应作任何修改。通过查询应用程序编译时产生的“ *.map”后缀文件, 打开 map 文件后,查看文件最后部分的区域,可以看到一段以“ Memory Map of the image”开头的记录(若找不到可用查找功能定位)
这一段是某工程的 ROM 存储器分布映像,在 STM32 芯片中, ROM 区域的内容就是 指存储到内部 FLASH 的代码。
在上面 map 文件的描述中,我们了解到加载及执行空间的基地址(Base)都是0x08000000,它正好是 STM32 内部 FLASH 的首地址,即 STM32 的程序存储空间就直接是执行空间;它们的大小(Size)分别为 0x00000b50 及 0x00000b3c,执行空间的 ROM 比较小的原因就是因为部分 RW-data 类型的变量被拷贝到 RAM 空间了;它们的最大空间(Max)均为 0x00100000,即 1M 字节,它指的是内部 FLASH 的最大空间。
计算程序占用的空间时,需要使用加载区域的大小进行计算,本例子中应用程序使用 的内部 FLASH 是从 0x08000000 至(0x08000000+0x00000b50)地址的空间区域。 所以从扇区 1(地址 0x08004000)后的存储空间都可以作其它用途,使用这些存储空间时不会篡改应用程序空间的数据。