嵌入式記憶體管理 變數定義後到底是如何神之存在?

2021-10-07 13:24:25 字數 3559 閱讀 5651

在基於rtos進行嵌入式軟體程式設計時,如果讓**精簡,記憶體用到恰到好處,那就需要在開發過程中,對**進行深度優化,然而能達到多深,就看你對記憶體知識掌握的多深了。為了能夠知己知彼,我對相關定義都進行了驗證,入木三分才能有的放矢。

根據上一節文章,我們在開發過程中,定義的變數究竟最後是怎麼存放的呢?怎樣在消耗我們的記憶體?我們以前又是如何在「揮霍」這寶貴的資源的呢?先來個預覽吧:

ram區:

flash區:

我進行了如下驗證:

因為全域性變數定義後,都是存放在.data或者.bss區域,或者const data區,比較讓人疑惑的是區域性變數,故主要對區域性變數進行**。

uint8_t test[

1024]=

;void

*p_arg)

}

,在呼叫區域性函式結束後,任務棧空間會被釋放出來。

在任務中定義乙個陣列,在切換任務後,該陣列依然存在任務棧中,任務的暫存器保護資料儲存在該陣列之後。

同樣,如果該陣列定義在乙個區域性函式內,消耗任務棧記憶體空間,在呼叫區域性函式結束後,任務棧空間會被釋放出來。

void

*p_arg)

}定義static有兩種情況,一種是只定義不使用,此時會被編譯器優化removing掉;

另外,進行了使用,此時,區域性的static變數會存放到***非任務堆疊***的區域,會消耗非任務棧區的其他記憶體。map如下:

512 = 0x200,對比第③種情形,區域性的static值,明顯加入到ble的.data區域中去了,同樣,使用的是***非任務棧空間***。

a.全域性const變數:

const uint8_t datacode[16]

=;

定義了如上的全域性變數,編譯之後檢視map如下所示:

該const全域性變數,存放於code的常量區,並且在使用過程中,直接從0x08016ece呼叫,不消耗記憶體空間

b.區域性const變數:

void

testfunc

(void);

int*p =

null

; uint8_t aaa[

1024];

memcpy

(aaa,datacode,16)

;}

在函式中定義乙個const變數,編譯後map如下所示:

在此區域存在該檔案(task_ble.o)檔案,說明該定義變數不存放在code的const區域,那它存放到**去了呢?

與a.全域性const變數對比,此時ro區為0,證實的確不存放在ro區,但是inc.data多了0x10個,及16個位元組資料,inc.data我理解是code include data,即包含在**裡面。我們去task_ble的**段去看看。

0x0801042c

0x00000098 code ro 476

.text task_ble.o

去0x0801042c檢視flash內部資料,確實,發現了我們定義的資料:

區域性變數的const,在使用過程中,會消耗記憶體。會將code區的資料copy到ram中,然後再進行使用,和其他區域性變數類似,但是加了const之後,改變量無法被修改,可以保證變數的唯一性。

c.const static 的組合定義

c.1區域性定義

void

testfunc

(void);

int*p =

null

; uint8_t aaa[

1024];

memcpy

(aaa,datacode,16)

;}

map資訊:

在code的常量區。

存放在ro區,說明確實存放在code的常量區。使用時也是直接用code const常量區直接取用,不消耗記憶體

c.2全域性定義

const

static uint8_t datacode[16]

=;void

testfunc

(void

)

map資訊:

通過觀察,效果和c.1是一樣的。不消耗記憶體

**const總結:**通過對const定義的實驗,除區域性的const定義外,其他的const定義都存放於code的const常量區,並且使用過程不消耗記憶體。但函式內區域性const存放在**內,且使用過程會消耗記憶體空間。所以,如果想通過const來節省記憶體空間,需要注意該特點。

在初始化檔案裡面,彙編檔案.s檔案中會定義堆和棧的大小,此時使用malloc會分配該空間的記憶體出來。

所以,在使用malloc時,需要注意堆空間大小的設定,以免無法分配記憶體空間。

同時,在使用動態記憶體分配malloc/free時要注意到以下幾方面的限制:

①因為系統記憶體分割槽是一種臨界資源,由訊號量保護,使用malloc會導致當前呼叫掛起,因此它不能用於中斷服務程式;

②因為進行記憶體分配需要執行查詢演算法,其執行時間與系統當前的記憶體使用情況相關,執行時間是不確定的,因此對於有規定時限的操作它是不適宜的;

③由於採用簡單的最先匹配演算法,容易導致系統堆中存在大量的記憶體碎片,降低記憶體使用效率和系統效能。

嵌入式系統 記憶體管理

教材 嵌入式系統及應用,羅蕾 李允 陳麗蓉等,電子工業出版社 嵌入式實時作業系統在記憶體管理方面需要考慮如下因素 快速而確定的記憶體管理 通常的作業系統都至少具有基本的記憶體管理方法 提供記憶體分配與釋放的系統呼叫 不使用虛擬儲存技術 在嵌入式實時作業系統中一般不使用虛擬儲存技術,以避免頁面置換所帶...

嵌入式 記憶體分配管理

嵌入式 記憶體分配管理 嵌入式的記憶體一般都非常的小,最進在學習lwip協議棧的移植,在正點原子的學習資料中找到了許多關於怎麼移植協議棧的東西,其中使用到了記憶體的分配管理技術,能夠高效的管理和使用記憶體,學習之後整理了放在這裡。一 記憶體分配管理函式 函式名函式說說明 輸入 輸出 memory i...

嵌入式中的BSP BSP到底是什麼?

嵌入式中的bsp bsp到底是什麼?參考 1 什麼是bsp?bsp是板級支援包,board support package 是介於主機板硬體和作業系統之間的一層,應該說是屬於作業系統 的一部分,主要目的是為了支援作業系統,使之能夠更好的執行於硬體主機板。bsp是相對於作業系統而言的,不 同的作業系統...