stm32內存管理

stm32內存管理

再講stm32內存管理之前,我想先向大家介紹幾個概念:

自然對其

對齊跟數據在內存中的位置有關。如果一個變量的內存地址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設一個整型變量的地址爲0x00000004,那它就是自然對齊的。

c語言中__align()關鍵字的作用與內存對齊的原理

在32位CPU中,CPU訪問內存一次訪問32位,4個字節,一個字。哪怕只讀一個char類型的數據,也會讀出這個數據所在的4個字節的地址來。所以編譯器爲了讓程序以最少的次數就可以讀取到完整的數據,會自動給變量分配的地址可以被4字節整除,比如我們命令CPU讀取一個float類型的數據,如果這個float類型的數據的地址爲0x0000 0004 ,那麼CPU只需要從這個地址開始讀取4個字節,一條指令就可以把float類型的數據讀取出來,但若它的地址爲0x0000 0003,那麼就需要先從0x0000 0000讀最後一個字節,再從0x0000 0004 讀前3個字節,在組合成一個完整的float類型的數據才行,原來一條指令的時間,現在需要3條指令。這就是我們爲什麼要保證內存是對齊的。
關於對齊,我們想先介紹下面這個關鍵字
__align(n)
__align 關鍵字指示編譯器在 n 字節邊界上對齊變量。
__align 是一個存儲類修飾符。它不影響函數的類型。
其中:n
是對齊邊界。
對於局部變量,n 值可爲 1、2、4 或 8。
對於全局變量,n 可以具有最大爲 2 的 0x80000000 次冪的任何值。
__align 關鍵字緊靠變量名稱前面放置。
__attribute __((align(n))), 如果n大於此結構體中小大基本數據類型size,那麼依據最大基本數據類型size對齊;否則,依據n進行對齊;
在數組中我們用__align(32)關鍵字修飾,則這個數組的首地址在32字節的邊界上(以空間換時間)

綜上所述,我們已經知道爲什麼要對變量進行對其,以及__attribute __(at)去對我們申請的變量進行一個定位,這也是我們可以區分3個內存區域 內部SRAM 0x2000 0000 ,外部SRAM 0x6800 0000 ,CCMRAM 0x1000 0000的原因所在。

對於內存管理的理解

我們這裏的內存管理採用正點原子的內存管理,原子的內存管理其實本質上就是圈一大塊內存,我們在圈的這塊內存裏面進行申請變量,釋放變量的操作。我自己理解爲原子自己畫了一片堆區(這個區域其實是在靜態存儲區的,即不是HEAP也不是STACK),在這個堆區裏面定義了自己的mymalloc(),和myfree()。非常的巧妙,代碼寫的也很簡潔,我這裏就不細說了。我們先看一下原子分配的3個自己的”堆區”:
在這裏插入圖片描述
這裏的各種參數,我們其實可以自己定義,定義成自己項目需要的memxbase就是每個”堆區”的首地址,原子的程序其實就是從這個堆區的末地址往首地址尋找,找到連續的內存塊滿足我們的需要後返回這個連續內存塊的第一塊的地址。

我們來類比一下,如果我們想從堆區申請一個u8類型的數組,數組成員100個,傳統的方法就是 u8* pBuffer = (u8*) malloc(100)。而在原子的內存管理中,我們需要這樣寫,u8* pBuffer = mymalloc(memx,800),就是從memx這個”堆區”,申請800個字節的內存,pBuffer 指向這個內存的首地址(其實也就相當於申請了100個u8類型的數組成員的數組)。注意用完這段內存一定要free/myfree掉,不然會造成內存泄漏。

因爲是原子的程序,我這裏也只是把自己的理解寫出來,幫助大家更好地理解內存的概念。基於操作系統的內存管理會更復雜一點,以後有機會我們在說那一種!

關於stm32內存結構請參考我上一篇博客,那裏面有很詳細的介紹。
https://blog.csdn.net/su_fei_ma_su/article/details/104229453

發佈了7 篇原創文章 · 獲贊 5 · 訪問量 2871
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章