一. keil 软件编译环境
Program Size: Code=65228 RO-data=5302 RW-data=48 ZI-data=1681
keil软件编译后会出现上面的提示,其意义如下:
Code:指程序中代码的字节数
RO-data:指程序中定义的常量字节数
RW-data :程序中已初始化的变量字节数
ZI-Data :程序中未初始化的变量字节数
可计算出flash和RAM的占用情况:
flash = Code + RO-data + RW-data = 65228 Byte + 5302 Byte + 48 Byte = 70578 Byte
ram = RW-data + ZI-data = 48 Byte + 1681 Byte = 1729 Byte
二. Eclipse 软件编译环境
text data bss dec hex filename
128288 684 17160 146132 23ad4 TLSR8258_Mesh_Dimmer_Light_20240430.elf
128288 684 17160 146132 23ad4 (TOTALS)
数据说明:
.text: 128288 Byte
.data: 684 Byte
.bss: 17160 Byte
dec: text+data+bss=146132 Byte (十进制)
hex: text+data+bss=0x23ad4 Byte (十六进制)
RAM的计算 = data + bss = RW Data + ZI Data
RAM中的大小 = data + bss = 684 Byte + 17160
Byte
= 17844 Byte
bin = text + data = Code + RO Data + RW Data
Code :代表执行的代码,程序中所有的函数都位于此处。
RO data:代表只读数据,程序中所定义的全局常量数据和字符串都位于此处。
RW data:代表已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。
ZI data:代表未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处。
text代码段:
(.text)= (Code + RO data)
,存放代码、常量及向量表,只读。 最终存放在FLASH。
例如函数、const int table[]
、中断向量表。
data数据段:
(.data) = (RW data)
,存放已初始化的全局/静态变量,可读可写。 最终存放在FLASH。
data放的是初始化的变量,且同时计入RAM和FLASH。链接器把数据分配在FLASH中然后在启动代码中从ROM拷贝到RAM。
例如int32_t myVar = 0x12345678;
,data段仅包含初始化所用的数据(本例中的0x12345678
),不含变量(myVar
)。变量myVar不是常量,所以最终会存放于RAM内。但是初始值(0x12345678)是一个常量,因此可以放在FLASH里。
bss:
(.bss) = (ZI data)
,存放所有未初始化的全局/静态变量,可读可写。 最终存放在RAM。
例如int32_t myGlobal;
,函数初始化bss段就是把未初始化的变量置0。
bin文件
binary文件,即二进制文件。
执行raw binary很简单,只需要将程序加载到其起始地址,就可以执行;
从可执行程序的角度来说,如果一个数据未被初始化,就不需要为其分配空间,所以.bss 并不占用可执行文件的大小,仅仅记录需要用多少空间来存储这些未初始化的数据,而不分配实际空间。
hex、bin、flash三者的大小关系
在烧录程序时往往将hex文件烧录到flash中,但hex文件的大小和flash的大小没什么必然的关系,hex文件大于单片机flash的大小也能烧录到单片机中。原因在于真正写入flash的不是hex文件,而是hex文件中的bin文件。有些软件直接生成的就是bin文件,而不是hex文件。