0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在Keil環(huán)境編程中發(fā)現(xiàn)STM32內(nèi)存管理存在的問題

GReq_mcu168 ? 來源:未知 ? 作者:胡薇 ? 2018-09-12 16:15 ? 次閱讀

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

圖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字節(jié)

(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).

分析:程序中增加了數(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位機中int型變量是32位的,占4字節(jié),所以初始6個值后,增加了24字節(jié)。

(2)再增加初始化變量的數(shù)量,則RO-data隨之增加,而Code不再變化,也就是Code由代碼3的816字節(jié)增加到1024字節(jié),是增加了初始化處理的代碼量。

根據(jù)以上分析,似乎與已知資料有沖突。

***************************************************

RO是程序中的指令和常量RW是程序中的已初始化變量ZI是程序中的未初始化的變量由以上3點說明可以理解為:RO就是readonly,RW就是read/write,ZI就是zero

****************************************************

如果按此說明,增加變量應(yīng)該增加RO,但從代碼1到代碼2的變化來看,僅是增加了Code,卻沒有增加RO。

初始化變量時,應(yīng)該增加RW,但是從代碼2~代碼4,RW卻沒有任何變化。

看來這個說法只能適用于ARM芯片,即運行時需要將代碼調(diào)入RAM運行的芯片,對于STM32這類芯片并不完全適用。

以下再作研究:

當使用 int myArray[300]時:

圖2

當使得int myArray[100]時:

圖3

應(yīng)該是向下生成的??

而且與芯片無關(guān),無論選擇6K RAM還是48K RAM都是如此,且當數(shù)組再大時,就會將地址置于小于0x2000000的地址,但編譯并不報錯。

當使得int myArray[450]時:

圖4

當然,執(zhí)行是錯誤的。

當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(;;);

}

編譯結(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ù)組作為全局變量來定義,情況立即發(fā)生了變化。RW-data變成了1620。其中的1600應(yīng)該是這個數(shù)組增加的4*400=1600,而20則是代碼1~代碼4中一直都有的。

經(jīng)查驗資料,局部變量是放在棧中的,如果棧定義得較小,那么變量數(shù)就很少。因此當數(shù)組在main內(nèi)部定義時,是作為局部變量從棧中分配內(nèi)存給它。所以在代碼1~代碼4的實驗中還發(fā)現(xiàn),即便更改芯片,從6KB RAM的C4到48KB RAM的VC,編譯的結(jié)果不發(fā)生變化,其原因就在于不論哪種芯片,給它分配的棧是固定的。棧的大小應(yīng)該在啟動代碼中修改。

圖5

更改這個: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).

說明:注意到ZI-ddata已發(fā)生了變化。

至此可以明白RO-data ZI-data應(yīng)該是針對棧來說的。即棧中的只讀數(shù)據(jù)和零數(shù)據(jù)??但是RW-data似乎又有所不同,這里還應(yīng)該再次探究。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2902

    瀏覽量

    73536
  • STM32
    +關(guān)注

    關(guān)注

    2257

    文章

    10828

    瀏覽量

    352454

原文標題:用Keil環(huán)境編程 發(fā)現(xiàn)STM32內(nèi)存管理的一個問題

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    管理STM32 MCU中的內(nèi)存保護單元

    本應(yīng)用筆記介紹如何管理 STM32 產(chǎn)品中的內(nèi)存保護單元(MPU)。MPU 是用于存儲器保護的可選組件。STM32 微控制器(MCU)中嵌入 MPU 之后變得更穩(wěn)健可靠。
    發(fā)表于 12-23 11:04 ?946次閱讀

    Keil中使用STM32CubeProgrammer

    Keil 環(huán)境中對新產(chǎn)品進行下載。對此,用戶可以選擇等待,也可以自行擴展 Keil 的 FLM 來支持該產(chǎn)品。但考慮到用戶產(chǎn)品開發(fā)的時間限制以及新的STM32 正式 Pack 很快
    的頭像 發(fā)表于 11-03 16:50 ?1974次閱讀
    <b class='flag-5'>在</b><b class='flag-5'>Keil</b>中使用<b class='flag-5'>STM32</b>CubeProgrammer

    stm32keil編譯環(huán)境下如何使用printf函數(shù)?

    stm32keil編譯環(huán)境下如何使用printf函數(shù)?
    發(fā)表于 12-01 07:34

    內(nèi)存管理簡介

    內(nèi)存管理1.內(nèi)存管理簡介2. 硬件設(shè)計3. 軟件設(shè)計3.1 STM32CubeMX設(shè)置3.2 MDK-ARM
    發(fā)表于 12-13 06:17

    請問STM32工程keil下怎么移植到IAR環(huán)境?

    請問STM32工程keil下怎么移植到IAR環(huán)境?
    發(fā)表于 12-17 07:12

    STM32內(nèi)存管理的相關(guān)資料推薦

    STM32內(nèi)存管理總結(jié)使用一個STM32芯片,對于內(nèi)存而言有兩個直觀的指標就是 RAM 大小,F(xiàn)LASH大小,比如
    發(fā)表于 02-09 06:22

    Keil環(huán)境中建立帶FreeRTOS的STM32L項目教程詳細說明

    Keil 環(huán)境中建立帶FreeRTOS的STM32L項目   1、先把source 文件夾復(fù)制至project 目錄,然后keil
    發(fā)表于 11-07 14:35 ?13次下載
    <b class='flag-5'>Keil</b><b class='flag-5'>環(huán)境</b>中建立帶FreeRTOS的<b class='flag-5'>STM32</b>L項目教程詳細說明

    STM32學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之keil5編程與GPIO開發(fā)

    STM32學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之keil5編程與GPIO開發(fā)
    發(fā)表于 11-30 12:36 ?4次下載
    <b class='flag-5'>STM32</b>學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之<b class='flag-5'>keil</b>5<b class='flag-5'>編程</b>與GPIO開發(fā)

    stm32keil和IAR中的匯編啟動代碼不相同

    最近學(xué)習(xí)cortex-A8內(nèi)核的soc,Linux環(huán)境下開發(fā),從匯編到C、uboot分析移植。過程中發(fā)現(xiàn),使用的匯編和keil中同是arm內(nèi)核的s
    發(fā)表于 12-03 12:51 ?2次下載
    <b class='flag-5'>stm32</b><b class='flag-5'>在</b><b class='flag-5'>keil</b>和IAR中的匯編啟動代碼不相同

    STM32內(nèi)存管理相關(guān)(內(nèi)存架構(gòu),內(nèi)存管理,map文件分析)

    STM32內(nèi)存管理總結(jié)使用一個STM32芯片,對于內(nèi)存而言有兩個直觀的指標就是 RAM 大小,F(xiàn)LASH大小,比如
    發(fā)表于 12-05 20:21 ?14次下載
    <b class='flag-5'>STM32</b>的<b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>相關(guān)(<b class='flag-5'>內(nèi)存</b>架構(gòu),<b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>,map文件分析)

    STM32+Keil 5+proteus 8 編程、仿真方法匯總

    介紹Keil 5 是我們真正編程開發(fā)的IDE環(huán)境。用C語言寫程序?qū)崿F(xiàn)某些功能STM32CubeMX是為stm32特別服務(wù)的“代碼自動生成”軟
    發(fā)表于 12-16 16:59 ?22次下載
    <b class='flag-5'>STM32+Keil</b> 5+proteus 8 <b class='flag-5'>編程</b>、仿真方法匯總

    STM32內(nèi)存管理

    內(nèi)存管理詳解1、介紹內(nèi)存管理,是指軟件運行時對計算機內(nèi)存資源的分配和使用的技術(shù)。其最主要的目的是如何高效,快速的分配,并且
    發(fā)表于 12-24 19:37 ?13次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>

    淺談嵌入式系統(tǒng)裸機編程內(nèi)存管理

     malloc和freePC編程中是很好用的一種內(nèi)存分配手段。但是,其嵌入式中,就未必好用了。由于嵌入式裸機編程中,無MMU,即
    發(fā)表于 09-15 10:38 ?1404次閱讀

    管理 STM32 MCU 中的內(nèi)存保護單元

    管理 STM32 MCU 中的內(nèi)存保護單元
    發(fā)表于 11-21 08:11 ?4次下載
    <b class='flag-5'>管理</b> <b class='flag-5'>STM32</b> MCU 中的<b class='flag-5'>內(nèi)存</b>保護單元

    AN4838 管理STM32 MCU中的內(nèi)存保護單元

    AN4838 管理STM32 MCU中的內(nèi)存保護單元
    發(fā)表于 11-21 17:07 ?0次下載
    AN4838 <b class='flag-5'>管理</b><b class='flag-5'>STM32</b> MCU中的<b class='flag-5'>內(nèi)存</b>保護單元