當(dāng)我們閱讀一些STM32F7或STM32H7系列芯片例程,或者基于這兩類芯片通過cubeMx進(jìn)行配置并用到MPU功能時,往往會在代碼里看到下面這段MPU配置。
對這段代碼可能有人有些疑問,這里重點(diǎn)一起聊聊其中的3個,供參考。
第一個疑問,那行做賦值0x87的代碼是什么意思?
第二個疑問,這段代碼的注釋【綠色】是說將未定義的區(qū)域配置為StronglyOrdered存儲屬性,這個未定義到底如何理解?從代碼看,這里清晰地對從0開始的整個4G空間做了配置,未定義區(qū)域到底指的哪里?
第三個疑問,這段代碼往往并不是開發(fā)者自己配置的。如果使用CubeMx進(jìn)行配置它會自動給我們加上這段,為什么要加這段?很多時候經(jīng)測試,即使沒這段代碼似乎也沒有什么問題。
這幾個問題,涉及到MPU和CortexM7內(nèi)核芯片試探性訪問的知識。我盡量通俗地加以介紹,知曉怎么回事即可。
我們知道,通過MPU可以配置特定地址空間的存儲屬性,給CPU約定訪問權(quán)限。我們在對某塊地址空間做MPU配置時,通常需要設(shè)置起始地址、空間大小、Cacheable、Bufferable、Shareable、子區(qū)屬性、區(qū)塊編號等。這里的地址空間,英文用Region來特指,后面都使用該詞。
實(shí)際應(yīng)用中我們往往會針對不同的Region做MPU配置,在做不同Region的MPU設(shè)置時,可能出現(xiàn)地址空間重疊的情況。比方像下面64KB空間內(nèi)做了3個不同Region的MPU配置,而且發(fā)生了不同Region的地址重疊。
這個時候,對于地址重疊空間的MPU屬性由Region編號大的決定。結(jié)合上圖,N+2編號Region的MPU屬性優(yōu)先級最高,Region N的最低。
剛才我在前面提到了子區(qū),它是什么意思呢?
子區(qū)也是個特定概念,英文用SubRegion。所謂Subregion,當(dāng)我們對某地址空間不小于256B的Region進(jìn)行MPU配置時,可以把該Region等分為8個子區(qū)【Subregion】,并把當(dāng)前Region的MPU屬性針對部分子區(qū)進(jìn)行排除性或說例外性設(shè)置。啥意思呢?比方說,本來當(dāng)前Region經(jīng)MPU配置后為WriteThough支持共享的存儲屬性,同時呢,又將其中的2個子區(qū)做排除性設(shè)置,即這2個子區(qū)不適用當(dāng)前的MPU配置。好比當(dāng)前舉國抗疫防新冠,要求全面強(qiáng)制核酸,但同時又可以做例外說明,那些基本足不出戶的老人或小孩不適用該要求。
在MPU配置寄存器MPU_RASR里有個8位字段SRD專門用來配置子區(qū)的排除屬性。每1位對應(yīng)一個子區(qū),高位對應(yīng)高地址子區(qū),低位對應(yīng)低地址子區(qū)。某位為0表示該子區(qū)使用當(dāng)前MPU配置,為1表示該子區(qū)不適用當(dāng)前配置,即被排除在外?!靖嗉?xì)節(jié)可以參考下圖】
不妨舉例說一下,假設(shè)我們選擇了某64KB區(qū)域進(jìn)行MPU設(shè)置,其中有2個SubRegion被做了MPU排除處理,即其中2個8KB空間不適用當(dāng)前的MPU配置。如下圖所示:
此時,對應(yīng)到MPU配置寄存器MPU_RASR里的SRD字段的內(nèi)容就是0x48。
聊到這里,我們就可以回答開篇的部分疑問了。
從上面這段代碼不難看出,首先將從0開始的4GB空間做了MPU配置,Region編號為0,最終被配置為Strongly Ordered存儲屬性。那句賦值0x87的代碼則是進(jìn)一步針對當(dāng)前Region里的SubRegion做屬性排除設(shè)置。這里的0x87就是給前面提到的給SRD字段的賦值?!具@里每個子區(qū)空間大小為512MB】
也就是說,這4GB空間中有4個子區(qū)不適用目前配置的MPU屬性,即下圖中幾個紅色方框內(nèi)區(qū)域。
換句話說,這里并沒有真正針對整個4GB空間做MPU配置,實(shí)際上只對上圖中的綠色區(qū)域做了StronglyOrder的存儲屬性設(shè)置。然而,代碼的注釋又說是針對未定義區(qū)域做MPU配置,怎么理解未定義區(qū)域呢?
這里說的未定義區(qū)域到底是上圖中紅色區(qū)域還是綠色區(qū)域呢?
顯然不是指紅色區(qū)域,因?yàn)檫@里特意對紅色區(qū)域做了MPU屬性排除處理,即當(dāng)前MPU配置根本就不適用它。那是指綠色區(qū)域?似乎也不對!因?yàn)榫G色區(qū)域的MPU配置不是很清晰嗎?Region編號、地址空間、訪問屬性等一應(yīng)俱全。何來未定義呢?
我們可以進(jìn)一步了解到,上圖中綠色區(qū)域?qū)?yīng)的是外部存儲設(shè)備的地址空間。如果我們需要用到外部存儲設(shè)備的話,往往還會針對外擴(kuò)的存儲單元再做MPU配置。比方我們基于STM32H7芯片外擴(kuò)了一個32MB的SDRAM,然后做了如下的MPU配置。
照樣,先對整個4GB空間做了MPU初始配置,即前面一直在解說的內(nèi)容。然后針對外擴(kuò)的32MB的SDRAM做了特定MPU配置,此時的Region標(biāo)號為1,訪問屬性為Write Through。此塊Region空間屬于前面初始配置中外部存儲空間的一部分,即出現(xiàn)不同Region地址重疊,所以這塊SDRAM所在Region的MPU訪問屬性就是Write Through,而不再是一開始配置的Strongly Ordered屬性了。見下圖中綠色區(qū)域中那部分黃色方塊。
當(dāng)然,如果說你還外擴(kuò)了其它的存儲單元,比方擴(kuò)個QSPI什么的,如果MPU屬性依然不同于Strongly Ordered、且Region編號大于0,更多綠色區(qū)域?qū)⒈恍碌狞S色區(qū)域替換。比方變成下面圖示的樣子。
也就是說,注釋代碼里提到的未定義區(qū)域,是指初始定義出來的綠色區(qū)域中沒有被用戶的實(shí)際外部存儲器所占用的剩余空間。即上面圖中摳除黃色區(qū)域以后剩下的綠色區(qū)域。
這里又衍生個問題,為什么要這樣做呢?
這個問題又涉及到M7內(nèi)核芯片的試探性訪問特性。試探性訪問可以提升芯片的性能,但有時可能也會導(dǎo)致些問題。比方,由于試探性訪問,在CPU訪問外部存儲器時,可能發(fā)生越界訪問。如果說它訪問到一個本不存在存儲設(shè)備的地址時,可能發(fā)生鎖死異常。結(jié)合上面圖形,黃色地址區(qū)域是實(shí)實(shí)在在的外部存儲器件所占用的空間,如果因?yàn)樵囂叫栽L問可能越界訪問不存在物理存儲單元的綠色區(qū)域而導(dǎo)致麻煩。
不過,由于CPU不會針對配置為Device 或Strongly Ordered存儲屬性的地址空間進(jìn)行試探性訪問。為了防止上面提到的問題,于是就有了前面談到的一上來就把所有用于外部訪問的存儲空間配置為StronglyOrdered屬性,顯然這個配置是個粗框架性的。用戶具體使用時根據(jù)實(shí)際存儲器的特性、容量等再配置特定的MPU屬性并覆蓋原來初始設(shè)置,其它未用區(qū)域依然保持StronglyOrdered屬性,正是為了防止在沒有放置實(shí)際存儲器的地方發(fā)生試探性訪問。
最后一個問題,有人發(fā)現(xiàn)即使不要那段針對4GB空間的MPU初始代碼,似乎也沒遇到啥問題。
這也正常。因?yàn)槟慵词雇鈹U(kuò)了存儲單元,并非一定會因?yàn)樵囂叫栽L問導(dǎo)致異常。比方你外擴(kuò)了32MB的存儲單元,未必就一定會要用到最后一個位置,說不定還剩余很多,遠(yuǎn)不至于讀到最后邊界而讓CPU試探到不存在存儲器的空間。但是事先做那段初始配置,對系統(tǒng)是一個很好的未雨綢繆。就好像河邊安置防護(hù)欄一樣,沒有,也不至于天天怎么樣;有,肯定要安全保險得多。
幾個小疑問,本以為可以很快寫完,不禁啰嗦了這么久,就此打住。祝君好運(yùn)!
審核編輯:湯梓紅
-
cpu
+關(guān)注
關(guān)注
68文章
11037瀏覽量
216013 -
MPU
+關(guān)注
關(guān)注
0文章
409瀏覽量
49657 -
STM32F7
+關(guān)注
關(guān)注
1文章
48瀏覽量
9349 -
CubeMx
+關(guān)注
關(guān)注
0文章
31瀏覽量
1583
原文標(biāo)題:一段有關(guān)MPU配置代碼的幾個小疑問
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
一段C代碼關(guān)聯(lián)的知識點(diǎn)

MPU6050勻速轉(zhuǎn)動一段時間后,偏航角不變怎么解決?
求一段人體紅外感應(yīng)設(shè)計代碼!
敲了一段verilog代碼,找到了努力的方向。
labview 如何調(diào)用HTML中的一段JS代碼
瑟瑟發(fā)抖:深度學(xué)習(xí)可以通過一段代碼找出代碼作者
Arduino 接MPU6050 9250使用IIC通訊,輸出數(shù)據(jù)一段時間后死機(jī)卡死的問題解決

STM32之FreeRTOS:(一) 中斷配置和臨界段的使用

評論