在基於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是相對於作業系統而言的,不 同的作業系統...