非常簡單的一個工程,沒有用到任何IO操作,與STM32有關的僅僅只有芯片的選擇,即其SRAM大小有區別。圖1是工程示意圖,從圖中可以看出,除了自己編寫的代碼外,僅僅增加了2個文件,即system_stm32f10x.c和startup_stm32f10x_hd.s,其中為了對startup_stm32f10x_hd.s進行修改,將其從庫文件夾復制到了項目文件夾中。
圖1
代碼1
int main()
{
int a,b,c,d;
a=10;b=20;
c=a+b;
for(;;);
}
myex1.c(3): warning: #550-D: variable "c" was set but never used
linking...
Program Size: Code=796 RO-data=336 RW-data=20 ZI-data=1636
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 1 Warning(s).
代碼2
int main()
{ const int x=16;
int a,b,c,d;
a=10;b=20;
c=a+b;
for(;;);
}
myex1.c(2): warning: #177-D: variable "x" was declared but never referenced
myex1.c(3): warning: #550-D: variable "c" was set but never used
linking...
Program Size: Code=800 RO-data=336 RW-data=20 ZI-data=1636
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 2 Warning(s).
說明:
(1)Code增加了4字節
(2)其余沒有任何變化
代碼3
int main()
{ const int x=16;
int myArry[100];
int i;
int a,b,c,d;
a=10;b=20;
c=a+b;
for(i=0;i<100;i++)
myArry[i]=i;
for(;;);
}
myex1.c(2): warning: #177-D: variable "x" was declared but never referenced
myex1.c(3): warning: #550-D: variable "myArry" was set but never used
myex1.c(5): warning: #550-D: variable "c" was set but never used
myex1.c(5): warning: #177-D: variable "d" was declared but never referenced
linking...
Program Size: Code=816 RO-data=336 RW-data=20 ZI-data=1636
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 4 Warning(s).
分析:程序中增加了數組myArry,Code增加為816字節,但是RO-data等仍未變化
代碼4
int main()
{ const int x=16;
int myArry[100]={1,2,3,4,5,6};
int i;
int a,b,c,d;
a=10;b=20;
c=a+b;
for(i=0;i<100;i++)
myArry[i]=i;
for(;;);
}
myex1.c(2): warning: #177-D: variable "x" was declared but never referenced
myex1.c(3): warning: #550-D: variable "myArry" was set but never used
myex1.c(5): warning: #550-D: variable "c" was set but never used
myex1.c(5): warning: #177-D: variable "d" was declared but never referenced
linking...
Program Size: Code=1024 RO-data=360 RW-data=20 ZI-data=1636
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 4 Warning(s).
分析:
(1)由于myArry作了初始化,因此RO-data增加了 360-336=24字節。原因是32位機中int型變量是32位的,占4字節,所以初始6個值后,增加了24字節。
(2)再增加初始化變量的數量,則RO-data隨之增加,而Code不再變化,也就是Code由代碼3的816字節增加到1024字節,是增加了初始化處理的代碼量。
根據以上分析,似乎與已知資料有沖突。
***************************************************
RO是程序中的指令和常量RW是程序中的已初始化變量ZI是程序中的未初始化的變量由以上3點說明可以理解為:RO就是readonly,RW就是read/write,ZI就是zero
****************************************************
如果按此說明,增加變量應該增加RO,但從代碼1到代碼2的變化來看,僅是增加了Code,卻沒有增加RO。
初始化變量時,應該增加RW,但是從代碼2~代碼4,RW卻沒有任何變化。
看來這個說法只能適用于ARM芯片,即運行時需要將代碼調入RAM運行的芯片,對于STM32這類芯片并不完全適用。
以下再作研究:
當使用 int myArray[300]時:
圖2
當使得int myArray[100]時:
圖3
應該是向下生成的??
而且與芯片無關,無論選擇6K RAM還是48K RAM都是如此,且當數組再大時,就會將地址置于小于0x2000000的地址,但編譯并不報錯。
當使得int myArray[450]時:
圖4
當然,執行是錯誤的。
當int myArray[409]時:正指向0x2000000
去掉其他變量,對于這個地址沒有影響!
代碼5
int myArray[400]={1,2,3,4,5,6,7,8,9,10,11,12,13,14};
int main()
{ const int x=16;
int a,b,c,d;
int i;
a=10;b=20;
c=a+b;
for(i=0;i<100;i++)
myArray[i]=i;
for(i=0;i<100;i++)
c+=myArray[i];
d+=x;
for(;;);
}
編譯結果:
compiling myex1.c...
linking...
Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 0 Warning(s).
分析:
本段程序將數組作為全局變量來定義,情況立即發生了變化。RW-data變成了1620。其中的1600應該是這個數組增加的4*400=1600,而20則是代碼1~代碼4中一直都有的。
經查驗資料,局部變量是放在棧中的,如果棧定義得較小,那么變量數就很少。因此當數組在main內部定義時,是作為局部變量從棧中分配內存給它。所以在代碼1~代碼4的實驗中還發現,即便更改芯片,從6KB RAM的C4到48KB RAM的VC,編譯的結果不發生變化,其原因就在于不論哪種芯片,給它分配的棧是固定的。棧的大小應該在啟動代碼中修改。
圖5
更改這個:startup_stm32f10x_hd.s可以更改棧的大小。
改成500后的編譯結果如下:
linking...
Program Size: Code=1048 RO-data=392 RW-data=20 ZI-data=1892
FromELF: creating hex file...
"myex1.axf" - 0 Error(s), 0 Warning(s).
說明:注意到ZI-ddata已發生了變化。
至此可以明白RO-data ZI-data應該是針對棧來說的。即棧中的只讀數據和零數據??但是RW-data似乎又有所不同,這里還應該再次探究。
-
內存
+關注
關注
8文章
3037瀏覽量
74143 -
STM32
+關注
關注
2270文章
10910瀏覽量
356577
原文標題:用Keil環境編程 發現STM32內存管理的一個問題
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論