ARM處理器架構——內存管理

一、內存映射

1.什麼是內存映射
內存映射指的是在ARM存儲系統中,使用內存管理單元(MMU)實現虛擬地址到實際物理地址的映射,如下圖所示。
在這裏插入圖片描述
【注】圖中的地址轉化器即MMU,CPU操作的稱爲虛擬地址MMU操作的爲實際的物理地址

2、爲什麼要內存映射
ARM的地址總線爲32位,故CPU可尋址範圍爲0x00000000~0xffffffff尋址空間爲4GB,所有的內部和外部存儲或者外設單元都需要通過對應的地址來操作,他不同的的芯片外設的種類數量尋址空間都不一樣,爲了能讓內核更方便的管理不同的芯片設計,ARM內核會先給出預定義的存儲映射,如下圖所示
在這裏插入圖片描述
芯片設計公司需要根據內核提供的預定義的存儲器映射來定義芯片內部外設和外部的保留接口,這樣做的好處是極大地減少了同一內核不同芯片間地址轉化的麻煩(cpu操作統一的虛擬地址,實際物理地址交由MMU管理)。

二、位帶操作

1、什麼是位帶操作
舉個簡單的例子,在使用51單片機操作P1.0爲低電平時我們知道這背後實際上就是往某個寄存器某個比特位中寫1或0的過程,但在CPU操作的過程中每一個地址所對應的都是一個8位字節,怎麼實現對其中某一位的直接操作,這就需要位帶操作的幫助。
2、那些地址可以進行位帶操作
上圖中有兩個區中實現了位帶。其中一個是 SRAM 區的最低 1MB 範圍(Bit band region),第二個則是片內外設區的最低 1MB 範圍。這兩個區中的地址除了可以像普通的 RAM 一樣使用外,它們還都有自己的“位帶別名區”,位帶別名區把每個比特膨脹成一個 32 位的字。位帶操作所使用的膨脹地址原本位於位帶別名區(Bit band Alias),由於現在都指向了位帶區的特殊位,這些膨脹地址都不能在指向一個8位的空間。

三、具體寄存器的地址計算

在ARM中所有的外設地址基本都是掛載在AHP或者APBx總線上,因此我們往往採用基地址+偏移地址+結構體的方式,來快速明瞭計算某一外設具體寄存器的地址,如下圖所示。
在這裏插入圖片描述
舉個例子,當我們想要操作GPIOA模塊中的ODR寄存器時只需要直接操作GPIO->ODR即可,該寄存器的的實際地址已經通過外設基地址 PERIPHA_BASE(內核預定義地址)+AHB1總線偏移地址(具體芯片設計公司決定)+GPIOA的偏移地址(具體芯片設計公司決定)+GPIO模塊的寄存器分佈結構體決定。再將模塊的寄存器分佈結構體指針指向模塊基地址(#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)),這樣做的好處是我們在調用GPIOA時直接就定位到了該模塊的基地址及內部個寄存器的地址偏移。

【注】當你使用位帶功能時,要訪問的變量必須用 volatile 來定義。因爲 C 編譯器並不知道同一個比特可以有兩個地址。所以就要通過 volatile,使得編譯器每次都把新的數值寫入寄存器,而不會進行優化操作。

四、堆和棧作用

一般情況下,一個程序本質上都是由 bss段、data段、text段三個組成的
.bss段:(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文Block Started by Symbol的簡稱.bss段屬於靜態內存分配。
.data段 :數據段(data segment)通常是指用來存放程序中 已初始化 的 全局變量 的一塊內存區域。數據段屬於靜態內存分配。
.text/.code段: 代碼段(code segment/text segment)通常是指用來存放 程序執行代碼 的一塊內存區域。這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於 只讀 , 某些架構也允許代碼段爲可寫,即允許修改程序。在代碼段中,也有可能包含一些 只讀的常數變量 ,例如字符串常量等。程序段爲程序代碼在內存中的映射.一個程序可以在內存中多有個副本.
在單片機上RAM存放data段,bss段,堆棧段;ROM(EPROM,EEPROM,Flash等非易失性存儲設備)存放代碼,只讀數據段。
對單片機編程後,程序的代碼段.data段.bss段.rodata段等都存放在Flash中。當單片機上電後,初始化彙編代碼將data段,bss段,複製到RAM中,並建立好堆棧,開始調用程序的main函數。

一個由C/C++編譯的程序佔用的內存分爲以下幾個部分
1>棧區(stack)——由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2>堆區(heap)——一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3>全局區(靜態區)(static)——全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束後由系統釋放
4>文字常量區——常量字符串就是放在這裏的(不可修改)。 程序結束後由系統釋放
5>程序代碼區——存放函數體的二進制代碼。
其中堆區和棧區存放在RAM中,而全局區、文字常量區、程序代碼區存放在ROM(Flash)中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章