STM32的記憶體管理和堆疊相關的認知

2021-08-19 05:27:15 字數 2704 閱讀 2102

今天仔細讀了一下記憶體管理的**,然後還有看了堆疊的相關知識,把以前不太明白的一些東西想通了,寫下來,方便以後檢視,也想大家看了能指出**不對,然後修改。

首先,先看一下stm32的儲存器結構。

flash

,sram

暫存器和輸入輸出埠被組織在同乙個

4gb的線性位址空間內。可訪問的儲存器空間被分成

8個主要塊,每個塊為

512mb

。flash

sram

是儲存執行程式中的資料。

所以,只要你不外擴儲存器,寫完的程式中的所有東西也就會出現在這兩個儲存器中。

這是乙個前提!

堆疊的認知

1.stm32中的堆疊

。這個我產生過混淆,導致了很多邏輯上的混亂。首先要說明的是微控制器是一種積體電路晶元,整合

cpu、

ram、

rom、多種

i/o口和中斷系統、定時器

/計數器等功能。

cpu中包括了各種匯流排電路,計算電路,邏輯電路,還有各種暫存器。

stm32

有通用暫存器r0‐

r15 

以及一些特殊功能暫存器

,其中包括了堆疊指標暫存器。當

stm32

正常執行程式的時候,來了乙個中斷,

cpu就需要將暫存器中的值壓棧到

ram裡,然後將資料所在的位址存放在堆疊暫存器中。等中斷處理完成退出時,再將資料出棧到之前的暫存器中,這個在

c語言裡是自動完成的。

2.程式設計中的堆疊。

在程式設計中很多時候會提到堆疊這個東西,準確的說這個就是

ram中的乙個區域。我們先來了解幾個說明

:(1)

程式中的所有內容最終只會出現在

flash

,ram

裡(不外擴)。

(2)段的劃分,是將類似資料種類儲存在乙個區域裡,方便管理,但正如上面所說,不管什麼段的資料,都是最終在

flash

和ram

裡面。c

語言上分為棧、堆、

bss、

data

、code

stm32

以及在mdk

裡面段的劃分。

mdk下

code, ro-data,rw-data,zi-data

這幾個段

:code

是儲存程式**的。

​ro-data

是儲存const

常量和指令。

​rw-data

是儲存初始化值不為

0的全域性變數。

​zi-data

是儲存未初始化的全域性變數或初始化值為

0的全域性變數。

flash=code + ro data + rw data;

ram= rw-data+zi-data;

這個是mdk

編譯之後能夠得到的每個段的大小,也就能得到占用相應的

flash

和ram

的大小,但是還有兩個資料段也會占用

ram,但是是在程式執行的時候,才會占用,那就是堆和棧。在

stm32

的啟動檔案

.s檔案裡面,就有堆疊的設定,其實這個堆疊的記憶體占用就是在上面

ram分配給

rw-data+zi-data

之後的位址開始分配的。堆:

是編譯器呼叫動態記憶體分配的記憶體區域。棧:

是程式執行的時候區域性變數的地方,所以區域性變數用陣列太大了都有可能造成棧溢位。

堆疊的大小在編譯器編譯之後是不知道的,只有執行的時候才知道,所以需要注意一點,就是別造成堆疊溢位了。。。不然就等著

hardfault

找你吧。

3.os中的堆疊及其記憶體管理。

嵌入式系統的堆疊,不管是用什麼方法來得到記憶體,感覺他的方式都和程式設計中的堆差不多。目前我知道兩種獲得記憶體情況:

(1)用龐大的全域性變數陣列來圈住一塊記憶體,然後將這個記憶體拿來進行記憶體管理和分配。這種情況下,堆疊占用的記憶體就是上面說的:如果沒有初始化陣列,或者陣列的初始化值為0,堆疊就是占用的ram的

zi-data部分;如果陣列初始化值不為0,堆疊就占用的ram的

rw-data部分。這種方式的好處是容易從邏輯上知道資料的來由和去向。

(2)​

就是把編譯器沒有用掉的

ram部分拿來做記憶體分配,也就是除掉

rw-data+zi-data+

編譯器堆

+編譯器棧後剩下的

ram記憶體中的一部分或者全部進行記憶體管理和分配。這樣的情況下就只需要知道記憶體剩下部分的首位址和記憶體的尾位址,然後要用多少記憶體,就用首位址開始挖,做乙個鍊錶,把記憶體獲取和釋放相關資訊鏈結起來,就能及時的對記憶體進行管理了。記憶體管理的演算法多種多樣,不詳說,這樣的情況下:

os的記憶體分配和自身區域性變數或者全域性變數不衝突,之前我就在這上面糾結了很久,以為函式裡面的變數也是從系統的動態記憶體中得來的。這種方式感覺更加能夠明白自己位址的開始和結束。

這兩種方法我感覺沒有誰更高明,因為只是乙個記憶體的獲取方式,高明的在於記憶體的管理和分配。​

STM32記憶體管理

這是我的第一篇文章,寫的不好請多多見諒 針對stm32f429來進行講解,其他型號的也可以參照學習 相信很多新手在記憶體管理這個程式中比較疑惑,為什麼分配那麼大,可不可以更改大小?但是改大了編譯會錯誤又是為什麼?這裡將對大家心中的疑惑進行講解,並且教大家進行計算。當該項值為 0 的時候,代表對應的記...

stm32記憶體分配

原文 1 棧區 stack 由編譯器自動分配和釋放,存放函式的引數值 區域性變數的值等,其操作方式類似 於資料結構中的棧。2 堆區 heap 一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能由作業系統 分配 方式類似於資料結構中的鍊錶。3 全域性區 靜態區 static 全域性變數和靜...

STM32之記憶體

記憶體的分類 1 動態記憶體 dram。為什麼稱之為動態記憶體呢?是與他的硬體構成有關。動態隨機儲存器dram 的記憶體單元是以電容的電荷來表示資料。有電荷表示1,無電荷表示0,但是隨著時間的推移,代表1的電荷會放電,代表0的電荷會吸收電荷,因此它需要定期重新整理,所以就有了動態記憶體之稱。重新整理...