非常簡(jiǎn)單的一個(gè)工程,沒(méi)有用到任何IO操作,與STM32有關(guān)的僅僅只有芯片的選擇,即其SRAM大小有區(qū)別。圖1是工程示意圖,從圖中可以看出,除了自己編寫的代碼外,僅僅增加了2個(gè)文件,即system_stm32f10x.c和startup_stm32f10x_hd.s,其中為了對(duì)startup_stm32f10x_hd.s進(jìn)行修改,將其從庫(kù)文件夾復(fù)制到了項(xiàng)目文件夾中。

圖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).
說(shuō)明:
(1)Code增加了4字節(jié)
(2)其余沒(méi)有任何變化
代碼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).
分析:程序中增加了數(shù)組myArry,Code增加為816字節(jié),但是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字節(jié)。原因是32位機(jī)中int型變量是32位的,占4字節(jié),所以初始6個(gè)值后,增加了24字節(jié)。
(2)再增加初始化變量的數(shù)量,則RO-data隨之增加,而Code不再變化,也就是Code由代碼3的816字節(jié)增加到1024字節(jié),是增加了初始化處理的代碼量。
根據(jù)以上分析,似乎與已知資料有沖突。
***************************************************
RO是程序中的指令和常量RW是程序中的已初始化變量ZI是程序中的未初始化的變量由以上3點(diǎn)說(shuō)明可以理解為:RO就是readonly,RW就是read/write,ZI就是zero
****************************************************
如果按此說(shuō)明,增加變量應(yīng)該增加RO,但從代碼1到代碼2的變化來(lái)看,僅是增加了Code,卻沒(méi)有增加RO。
初始化變量時(shí),應(yīng)該增加RW,但是從代碼2~代碼4,RW卻沒(méi)有任何變化。
看來(lái)這個(gè)說(shuō)法只能適用于ARM芯片,即運(yùn)行時(shí)需要將代碼調(diào)入RAM運(yùn)行的芯片,對(duì)于STM32這類芯片并不完全適用。
以下再作研究:
當(dāng)使用 int myArray[300]時(shí):
圖2
當(dāng)使得int myArray[100]時(shí):
圖3
應(yīng)該是向下生成的??
而且與芯片無(wú)關(guān),無(wú)論選擇6K RAM還是48K RAM都是如此,且當(dāng)數(shù)組再大時(shí),就會(huì)將地址置于小于0x2000000的地址,但編譯并不報(bào)錯(cuò)。
當(dāng)使得int myArray[450]時(shí):
圖4
當(dāng)然,執(zhí)行是錯(cuò)誤的。
當(dāng)int myArray[409]時(shí):正指向0x2000000
去掉其他變量,對(duì)于這個(gè)地址沒(méi)有影響!
代碼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(;;);
}
編譯結(jié)果:
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).
分析:
本段程序?qū)?shù)組作為全局變量來(lái)定義,情況立即發(fā)生了變化。RW-data變成了1620。其中的1600應(yīng)該是這個(gè)數(shù)組增加的4*400=1600,而20則是代碼1~代碼4中一直都有的。
經(jīng)查驗(yàn)資料,局部變量是放在棧中的,如果棧定義得較小,那么變量數(shù)就很少。因此當(dāng)數(shù)組在main內(nèi)部定義時(shí),是作為局部變量從棧中分配內(nèi)存給它。所以在代碼1~代碼4的實(shí)驗(yàn)中還發(fā)現(xiàn),即便更改芯片,從6KB RAM的C4到48KB RAM的VC,編譯的結(jié)果不發(fā)生變化,其原因就在于不論哪種芯片,給它分配的棧是固定的。棧的大小應(yīng)該在啟動(dòng)代碼中修改。

圖5
更改這個(gè):startup_stm32f10x_hd.s可以更改棧的大小。
改成500后的編譯結(jié)果如下:
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).
說(shuō)明:注意到ZI-ddata已發(fā)生了變化。
至此可以明白R(shí)O-data ZI-data應(yīng)該是針對(duì)棧來(lái)說(shuō)的。即棧中的只讀數(shù)據(jù)和零數(shù)據(jù)??但是RW-data似乎又有所不同,這里還應(yīng)該再次探究。
-
內(nèi)存
+關(guān)注
關(guān)注
9文章
3210瀏覽量
76369 -
STM32
+關(guān)注
關(guān)注
2309文章
11162瀏覽量
373448
原文標(biāo)題:用Keil環(huán)境編程 發(fā)現(xiàn)STM32內(nèi)存管理的一個(gè)問(wèn)題
文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
管理STM32 MCU中的內(nèi)存保護(hù)單元
在Keil中使用STM32CubeProgrammer
內(nèi)存管理簡(jiǎn)介
請(qǐng)問(wèn)STM32工程在keil下怎么移植到IAR環(huán)境?
STM32內(nèi)存管理的相關(guān)資料推薦
Keil環(huán)境中建立帶FreeRTOS的STM32L項(xiàng)目教程詳細(xì)說(shuō)明
STM32學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之keil5編程與GPIO開(kāi)發(fā)
stm32在keil和IAR中的匯編啟動(dòng)代碼不相同
STM32的內(nèi)存管理相關(guān)(內(nèi)存架構(gòu),內(nèi)存管理,map文件分析)
STM32內(nèi)存結(jié)構(gòu)介紹,F(xiàn)reeRTOS內(nèi)存分配技巧,Stack_Size和Heap_Size大小設(shè)置
STM32+Keil 5+proteus 8 編程、仿真方法匯總
STM32內(nèi)存管理
在Keil環(huán)境編程中發(fā)現(xiàn)STM32內(nèi)存管理存在的問(wèn)題
評(píng)論