科普:
先请问大家一个问题:keil5编译后生成 Program Size: Code RO-data RW-data ZI-data是什么?
Program Size: Code=x RO-data=x RW-data=x ZI-data=x 的含义
Code(代码): 程序所占用的FLASH大小,存储在FLASH.
RO-data(只读的数据): Read-only-data,程序定义的常量,如const型,存储在FLASH中。
RW-data(有初始值要求的、可读可写的数据):
Read-write-data,已经被初始化的变量,存储在FLASH中。初始化时RW-data从flash拷贝到SRAM。
ZI-data:Zero-Init-data,未被初始化的可读写变量,存储在SRAM中。ZI-data不会被算做代码里因为不会被初始化。
ROM(Flash) size = Code + RO-data + RW-data;
RAM size = RW-data + ZI-data
简单的说就是在烧写的时候是FLASH中的被占用的空间为:Code+RO Data+RW Data
程序运行的时候,芯片内部RAM使用的空间为: RW Data + ZI Data
==================================================
要想知道RAM溢出分析,对内存需要比较了解。实际上:
====================================================
**Total RO Size (Code + RO Data)
Total RW Size (RW Data + ZI Data)
Total ROM Size (Code + RO Data + RW Data)**
====================================================
ZI-data: 已定义未初始化或者初始化为0的变量大小
RW-data:已经初始化的变量大小
Total RW Size 就是STM32中的RAM内存空间。
个人做了一个实验论证了一下:
参考代码,使用全局变量来占用RAM
#define KB_BYTE 1
uint8_t fft1_output[1024*KB_BYTE];
void StartTask06(void const * argument)
{
BaseType_t xReturn = pdPASS;
int AI_Result[3]={0};
for(;;)
{
xReturn=xSemaphoreTake(xBSem_AI_Start_Flag,portMAX_DELAY); //
if(xReturn==pdTRUE){
for(uint32_t i;i<1024*KB_BYTE;i++){
fft1_output[i]=fft1_output[i]+fft1_output[i];
}
}
}
}
测试条件:STM32F4,RAM为128K。编译器为level 0,数组定义为全局变量,代码路上。Program Size如下
从上面可以看出,当数组为56K(56*1024)大小时,RAM为128.5K溢出。报错
Error: L6406E: No space in execution regions with .ANY selector matching xxx.o(.data).
为了更为精确的测试,我们利用数组,凑齐128K,代码同上
图一:
图二:
另外测试过程中发现,定义的全局变量数组必须在函数中使用到。不然会被keil编译优化掉。使得数据一直不会变。