1. 程式人生 > >STM32F10xxx20xxx21xxxL1xxxx Cortex-M3程式設計手冊 閱讀筆記四(2):記憶體保護單元

STM32F10xxx20xxx21xxxL1xxxx Cortex-M3程式設計手冊 閱讀筆記四(2):記憶體保護單元

這一部分描述在一些stm32微控制器應用的記憶體保護單元。參看相應的裝置手冊檢查在我們使用的stm32型別中是否存在。

       記憶體保護單元劃分記憶體地圖為許多區域,而且定義了每一區域的定位、大小、訪問許可權和記憶體屬性。它支援:每一區域獨立屬性設定;重疊區;將記憶體屬性匯出到系統。

       記憶體屬性影響到區域記憶體訪問的行為。Cortex-M3記憶體管理單元定義:8個獨立的記憶體區域,0-7;一個背景區域。

       當記憶體區域重疊時,區域編號最高的區域屬性影響記憶體訪問。例如,區域7的屬性優先於任何與區域7重疊區域的屬性。

       背景區域和預設記憶體地圖有相同的記憶體訪問屬性,但它只能由特權程式碼訪問。

       Cortex-M3記憶體管理單元記憶體地圖是統一的,這意味著指令訪問和資料訪問有相同的區域設定。

       如果一個程式訪問一個被MPU禁止的記憶體地址,處理器將會產生一個記憶體管理錯誤。這導致一個錯誤異常,可能導致一個作業系統環境中的程序中止。

       在一個作業系統環境中,核心可以根據要執行的程序動態的更新MPU區域設定。典型的,一個嵌入式作業系統使用MPU進行記憶體保護。

       MPU區域的配置基於記憶體型別,以下列出了可能的MPU區域屬性。

MPU訪問許可屬性,MPU_RASR暫存器的訪問許可位TEX,C,B,S,AP和XN,控制相應記憶體區域的訪問。如果一個記憶體區域的訪問沒有需要的許可,MPU產生一個許可權錯誤。


當一個訪問違反了MPU許可,處理器產生一個記憶體管理錯誤,MMFSR指示錯誤的原因。

       為了更新一個MPU區域的屬性,更新MPU_RNR,MPU_RBAR和MPU_RASR暫存器。我們可以單獨地編寫每一個暫存器,或者使用多字寫程式設計所有的這些暫存器。我們可以使用MPU_RBAR和MPU_RASR別名,使用一個STM指令同時編寫最多4個區域。

       使用單獨的字更新MPU區域:

       如果在先前已啟用要修改的區域,在向MPU寫入新區域設定前先失能這個區域。

       軟體必須使用記憶體障礙指令:在MPU設定前,如果那裡有未解決的記憶體傳送,如緩衝寫,它們可能在MPU設定變化時收到影響;在MPU設定後,如果包含必須使用新MPU設定的記憶體傳輸。

       然而,如果MPU設定處理在進入一個異常處理時開始或後邊緊跟一個異常返回,不需要記憶體障礙指令,因為異常進入和異常返回機制導致記憶體障礙行為。

       軟體在MPU設定中不需要記憶體屏障指令,因為它通過PPB訪問MPU,PPB是一個強有序記憶體區域。

       例如,如果你想所有的記憶體訪問行為在程式設計順序後迅速見效,使用一個DSB指令和一個ISB指令。在改變MPU設定後需要使用一個DSB指令,例如在上下文切換的結尾。如果程式設計MPU區域的程式碼使用分支或呼叫進入,一個ISB指令需要使用。如果使用異常返回或採用一個異常輸入程式設計序列,我們不再需要一個ISB指令。

       使用多字寫更新MPU區域:

       我們可以根據資訊如何分離,直接使用多位元組寫。

       子區域:

       256或更多位元組的區域被分為8個大小相等的子區域。設定RASR中的SRD區域的相應位失能子區。SRD的最低有效位控制第一個子區域,SRD的最高有效位控制最後一個子區域。失能一個子區域意味著另一個重疊失能範圍的區域匹配代替。如果沒有其它的使能區域重疊這個失能這個子區域,MPU發行一個錯誤。

       32,64,128位元組的區域不支援子區域,對於這些區域,我們必須設定SRD域為0x00,否則,MPU的行為是不可預測的。

       SRD的例子,兩個區域有相同的地址重疊。區域1是128KB,區域2是512KB。為了確保區域1的屬性應用於第一個128KB區域,設定區域2的SRD域為b00000011,失能前兩個子區域。如圖所示;


MPU設計提示和技巧

為了避免意外的行為,在更新一箇中斷處理可能訪問的區域屬性前失能中斷。

確保軟體使用正確大小的對齊訪問方式訪問MPU暫存器:除了RASR,必須使用對齊字訪問;對於RASR,可以使用位元組或半字對齊或字訪問。

處理器不支援對MPU暫存器的不對齊訪問。

在設定MPU時,如果MPU在先前已經被程式設計,失能不用的區域避免任何先前區域設定影響新的MPU設定。

建議的MPU配置,STM32微控制系統只有一個處理器,所以我們應該程式設計MPU如下,


在stm32實現,共享性和緩衝策略屬性不影響系統的行為。但是,對MPU使用那些設定可以使應用程式碼更有移植性。給出的值可用於典型的場景。

MPU屬性不影響DMA對記憶體/外設地址空間的資料訪問。因此,為了保護記憶體區域免受無意的DMA訪問,MPU必須控制SW/CPU訪問DMA暫存器。

MPU典型暫存器 (MPU_TYPER)

地址偏移:0x00

復位值:0x00000800

需要的特權:特權的

MPU典型暫存器指示MPU是否存在,如果存在,它支援多少區域。


位31:24 保留,硬體強制為0

位23:16 IREGION[7:0] MPU指令區域的數量。這些位指示支援的MPU指令區域的數量,一致含0x00.MPU記憶體地圖由DREGION域描述和統一。

位15:8 DREGION[7:0] MPU資料區域的數量

位7:1 保留,硬體強制為0

為0 SEPARATE:分開標誌。這一位指示支援統一的或單獨的指令和資料記憶體地圖:0,統一的;1,單獨的。

MPU控制暫存器(MPU_CR)

地址偏移0x04

復位值 0x0000 0000

需要的特權 特權的

MPU_CR暫存器,使能MPU,使能預設記憶體地圖背景區域,在硬體錯誤,不可遮蔽中斷和錯誤遮蔽升級處理時使能MPU的使用。

當ENABLE和PRIVDEFENA都設定為1:對於特權訪問,預設的記憶體地圖,任何特權程式的訪問在沒有定位任何使能記憶體區域的行為將會當作預設的記憶體地圖。

任何非特權程式的訪問沒有定位任何使能的地址區域將會導致一個記憶體管理錯誤。

不可執行和強有序規則同樣適用於系統控制空間不管ENABLE位的值。

當使能位設定為1時,除非PRIVDEFENA位設定為1,至少記憶體地圖的一個區域必須使能為了系統正常工作。如果PRIVDEFENA位設定為1而且沒有區域被使能,那麼僅有特權程式可以執行。

當使能為設定為0,系統使用預設的記憶體地圖。這和當MPU沒有被執行時有相同的記憶體屬性。預設的記憶體地圖應用於特權和不特權程式訪問。

當MPU被使能,系統控制空間和向量表的訪問總是被允許的。其它區域的訪問性基於區域和PRIVDEFENA是否設定為1。

除非HFNMIENA設定為1,否則在處理去執行優先順序為-1或-2異常處理時MPU不被使能。這些優先順序僅僅可能在處理一個硬體錯誤或NIM異常或FAULTMASK被使能時。設定HFNMIENA位為1使能在兩種優先順序執行時的MPU。

位31:3 保留,硬體強制為0

位2 PRIVDEFENA 使能特權程式訪問預設記憶體地圖。

       0如果MPU被使能,失能預設記憶體地圖的使用。任何對一位置的記憶體訪問沒有覆蓋任何使能的區域導致一個錯誤。

       1如果MPU使能,使能預設記憶體地圖的使用對特權程式訪問作為背景區域。

       注意:當使能時,背景區域行為好像它的區域編號為-1,任何被定義和使能的區域有超過預設地圖的優先順序。如果MPU未使能,處理器忽略這一位。

位1 HFNMIENA 在硬體錯誤、NMI和錯誤遮蔽處理時使能MPU的操作。

       當MPU使能時,

1, 在硬體錯誤、NMI和錯誤遮蔽處理時,使能MPU

注意:當MPU被使能,如果這一位被設定為1,行為是不可預測的。

位0 ENABLE 使能MPU

       0MPU失能

       1MPU使能

MPU區域編號暫存器(MPU_RNR)

地址偏移0x08

復位值 0x0000 0000

需要的特權 特權的

MPU_RNR暫存器選擇哪一個記憶體區域被MPU_RBAR和MPU_RASR暫存器引用。

位31:8 保留,硬體強制為0.

位7:0 REGION[7:0] MPU區域。這些位表明被MPU_RBAR和MPU_RASR暫存器應用的MPU區域。MPU支援8個記憶體區域,所以這一域允許的值為0-7。通常地,在訪問MPU_RBAR或MPU_RASR之前,我們寫需要的區域編號到這一暫存器。然而,你可以通過寫MPU_RBAR暫存器的VALID位為1,改變區域的編號,這個寫操作將會更新REGION域。

MPU區域基地址暫存器(MPU_RBAR)

地址偏移0x0C

復位值 0x0000 0000

需要的特權 特權的

MPU_RBAR暫存器定義了被MPU_RNR暫存器選中的MPU區域基地址,而且可以更新MPU_RNR暫存器的值·。將VALID位設定為1寫入MPU_RBAR暫存器改變當前區域的編號和更新MPU_RNR暫存器。


位31:N 區域基地址域。N的值依賴於區域的大小。區域的大小,由RASR中的SIZE域明確,定義N=log2(區域的大小位元組)。如果在MPU_RASR暫存器中區域的大小配置為4GB,則沒有有效的ADDR域。在這種情況下,區域佔據全部的記憶體地圖,基地址為0x0000 0000。基地址對齊為區域的大小。例如,一個64KB區域必須對齊64KB的倍數,例如,在0x0001 0000或0x0002 0000。

位N-1:5 保留,硬體強制為0

位4 VALID MPU暫存器編號生效

       寫:

0     MPU_RNR暫存器不發生變化,處理器更新在RNR中明確的區域基地址,忽略REGION域的值。

1     處理器更新RNR的值為REGION域的值,更新區域基地址的值為REGION域明確的區域。

讀:一直讀為0

位3:0 REGION[3:0] MPU區域域。對於寫的行為,看VAILD域的描述。在讀時,返回由MPU_RNR暫存器明確的當前區域編號。

MPU區域屬性和大小暫存器(MPU_RASR)

地址偏移:0x10

復位值 0x0000 0000

需要的特權 特權的

MPU_RASR暫存器定義了由MPU_RNR明確的MPU區域的區域的大小和記憶體屬性,和使能區域及子區域。MPU_RASR可以使用字或半字訪問。高有效位的半字儲存區域的屬性;低有效位的半字儲存區域的大小和區域及子區域的使能位。


位28 XN:指令獲取失能位

0, 指令獲取使能

1, 指令獲取失能

位27      保留,硬體強制為0

位26:24 AP[2:0] 訪問許可

位23:22 保留,硬體強制為0

位21:19 TEX[2:0] 記憶體屬性

位18 S:可分享記憶體屬性

位17 C:記憶體屬性

位16 B:記憶體屬性

位15:8 SRD 子區域失能位。對於域中的每一位,0,相應的子區域使能;1,相應的子區域失能。區域大小128位元組和更少的不支援子區域,當對這樣的區域寫入屬性時,寫入SRD域為0x00。

位7:6 保留,硬體強制為0

位5:1 SIZE MPU保護區域的大小。最小的許可值為3。

       SIZE域的值,SIZE域的值定義了由MPU_RNR明確的MPU記憶體區域大小,區域位元組大小=2(SIZE+1)。最小的許可區域大小為32B,相應你給的SIZE值為4。

位0 ENABLE 區域使能位。