引言
目前,靈動微控制器產(chǎn)品體系中,適配了MicroPython的,有MM32F3(MM32F3273G9P,Arm Cortex-M3)和MM32F5(MM32F5277E9P,ArmChina STAR-MC1),從官方數(shù)據(jù)來看,使用星辰處理器(STAR-MC1)的MM32F5對指令的處理效率要高于使用Cortex-M3處理器的MM32F3。如圖x所示。
figure-arm-core-benchmark 圖x 星辰處理器同其他Arm處理器內(nèi)核對比
然而,同一份MicroPython的啟動過程,在使用同樣主頻(120MHz)的情況下,在MM32F5平臺上運行,總是莫名其妙地慢好多。。。昨天跟同事Hao聊SDK的樣例工程對Cache問題的處理策略時,偶然意識到,早期為MM32F5適配MicroPython的時候沒有考慮過Cache,隨即趕緊翻出來MicroPython的代碼,果然沒開。好吧,更新MicroPython項目下MM32F5平臺的啟動代碼,替換來自于SDK中的system_mm32f5277e.c和system_mm32f5277e.h文件。
/* *Copyright2022MindMotionMicroelectronicsCo.,Ltd. *Allrightsreserved. * *SPDX-License-Identifier:BSD-3-Clause */ #include"hal_device_registers.h" #ifdefined(__VTOR_PRESENT)&&(__VTOR_PRESENT==1U) externuint32_t__VECTOR_TABLE; #endif voidSystemInit(void) { #ifdefined(__FPU_PRESENT)&&(__FPU_PRESENT==1U) #ifdefined(__FPU_USED)&&(__FPU_USED==1u) SCB->CPACR|=(SCB_CPACR_CP10_MASK|SCB_CPACR_CP11_MASK);/*setCP10,CP11FullAccess*/ #endif #endif/*__FPU_PRESENT*/ #ifdefined(__ICACHE_PRESENT)&&(__ICACHE_PRESENT==1U) #ifndefICACHE_DISABLED if(SCB->CLIDR&SCB_CLIDR_IC_Msk) { SCB_EnableICache(); } #endif/*DCACHE_DISABLED*/ #endif/*__ICACHE_PRESENT*/ #ifdefined(__DCACHE_PRESENT)&&(__DCACHE_PRESENT==1U) #ifndefDCACHE_DISABLED if(SCB->CLIDR&SCB_CLIDR_IC_Msk) { SCB_EnableDCache(); } #endif/*DCACHE_DISABLED*/ #endif/*__DCACHE_PRESENT*/ } /*EOF.*/
其中,如果沒有調(diào)用SCB_EnableICache()和SCB_EnableDCache()函數(shù),默認關(guān)閉ICache和DCache,配置宏__ICACHE_PRESENT和__DCACHE_PRESENT來自于MM32F5270的芯片頭文件mm32f5277e.h。
#define__STAR_REV0x0100U/*Corerevisionr1p0*/ #define__SAUREGION_PRESENT0U/*SAUregionspresent*/ #define__MPU_PRESENT1U/*MPUpresent*/ #define__VTOR_PRESENT1U/*VTORpresent*/ #define__NVIC_PRIO_BITS3U/*NumberofBitsusedforPriorityLevels*/ #define__Vendor_SysTickConfig0U/*Setto1ifdifferentSysTickConfigisused*/ #define__FPU_PRESENT1U/*FPUpresent*/ #define__DSP_PRESENT1U/*DSPextensionpresent*/ #define__ICACHE_PRESENT1U/*DefineifanICACHEispresentornot*/ #define__DCACHE_PRESENT1U/*DefineifanDCACHEispresentornot*/
編譯,驗證。找來兩塊之前下載了MicroPython固件的MM32F5開發(fā)板,向其中一塊板子下載啟用ICache和DCache之后的新固件。運行程序后,同使用之前版本固件的程序相比,果然有明顯的提升。如圖x所示。
video-mm32f5-micropython 圖x 啟用Cache前后的MicroPython啟動過程對比實物
圖中板子運行程序啟動MicroPython啟動流程后,執(zhí)行文件系統(tǒng)中Python源文件,閃爍小燈。圖中下方的板子使用了啟用Cache的程序,明顯先完成MicroPython啟動過程,先開始執(zhí)行閃爍小燈的程序。
提交更新到代碼倉庫。Bingo!
commit46372ed15d5769b25775a209c56d62c4cfc3ac5d(HEAD->master,origin/master,origin/HEAD) Author:AndrewSUDate:WedJun1411062023+0800 updatethestartupcodetoenabletheicacheformm32f5. -thisfixwouldacceleratethespeedofrunningtheinstruction sequenceonmm32f5,whichhastheicacheanddcacheintegrated. Signed-off-by:AndrewSU
啟用Cache后,之前在MM32F5微控制器平臺上運行MicroPython小概率會出現(xiàn)hardfault的問題也得到的緩解,頗有“治好了某人多年老寒腿”的趕腳。^v^。
Cache的工作原理
Cache主要解決高速的CPU訪問低速的存儲器均衡速度差的問題,Cache通過預(yù)取數(shù)據(jù)/命令的機制,低速但整塊地從低速存儲器中取數(shù)據(jù)塊,然后快速但串行地向CPU送數(shù)據(jù)流。高速的處理器大多使用哈佛結(jié)構(gòu),即使用指令總線和數(shù)據(jù)總線分別取指令和數(shù)據(jù),對應(yīng)有ICache和DCache。
Cache能夠有效工作基于幾個基本前提:
空間局部性:在最近的未來,使用到的信息和當(dāng)前使用的信息在空間上會是鄰近的。這個因為數(shù)據(jù)大部分都是連續(xù)存儲的。所以主存當(dāng)中的數(shù)據(jù)都是成塊傳輸?shù)紺ache當(dāng)中。
時間局部性:在最近的未來,使用到的信息可能是當(dāng)前正在使用的信息。由于CPU本質(zhì)上一個死循環(huán),里面還有很多小循環(huán)的運行和操作,所以當(dāng)前使用到的數(shù)據(jù)很可能會在循環(huán)當(dāng)中,這樣當(dāng)前的數(shù)據(jù)有可能會在將來在再被調(diào)用一次。
另外,關(guān)于Cache還有其余部分需要了解:
Cache與主存的映射方式:解決主存內(nèi)數(shù)據(jù)塊和Cache當(dāng)中數(shù)據(jù)塊的對應(yīng)關(guān)系。
替換算法:Cache小,主存大。如果Cache中數(shù)據(jù)存滿了之后,如何操作。
Cache寫策略:如果CPU修改了Cache中的副本,如何確保Cache中的數(shù)據(jù)和主存中的母本數(shù)據(jù)保持一致。
關(guān)于Cache的工作原理,以及設(shè)計機制,可參考計算機專業(yè)考研四大專業(yè)課之《計算機體系結(jié)構(gòu)》,以及參考文獻中的《一文搞懂Cache基本原理》。
需要關(guān)閉DCache的情況
在微控制器系統(tǒng)中,有時會需要直接使用內(nèi)存里的數(shù)據(jù)同外設(shè)交互,而不進入CPU,例如使用DMA(另一個總線主機AHB Master,但不需要Cache功能)相關(guān),這種場景下,使用Cache的意義就不大了,甚至可能會出現(xiàn)數(shù)據(jù)不一致的風(fēng)險,此時,就需要關(guān)閉Cache才能讓系統(tǒng)正常工作。具體來說,ICache可以繼續(xù)啟用,畢竟指令都是送到CPU中執(zhí)行,但DCache需要關(guān)掉,否則通過CPU寫入到內(nèi)存的數(shù)據(jù)未能及時同步物理內(nèi)存時(基于Cache的寫策略),啟動DMA時搬運的數(shù)據(jù)不一定是實際需要傳送的數(shù)據(jù)。另外,所有使用到“內(nèi)嵌”DMA的外設(shè)模塊的工程中,也需要小心謹(jǐn)慎地使用DCache,例如一些USB外設(shè)、ENET外設(shè)、顯示加速器、以數(shù)據(jù)塊為操作單元的加速計算模塊等。
關(guān)ICache的情況雖然不多,但也存在,例如在涉及IAP應(yīng)用中,從存放指令的介質(zhì)中擦除指令、寫入新指令后,再讀指令,實際的新指令可能尚未替換到ICache中存放的舊指令,導(dǎo)致程序執(zhí)行錯誤。
魚和熊掌都想要
關(guān)閉DCache之后,CPU讀數(shù)據(jù)的速度會明顯慢很多,例如本文一開始展現(xiàn)的情況。怎樣才能提升訪問訪問速度的同時,又能確保數(shù)據(jù)一致性呢?總不會人為頻繁地開關(guān)Cache吧(很多微控制器對啟動Cache的時機也有特別要求,需要在運行應(yīng)用程序的一開始就要開啟)。這里有兩種可能的思路,供大家參考:
使用內(nèi)存保護單元MPU
使用內(nèi)存隔離/同步指令
這兩種方法,分別是在空間上和時間上對數(shù)據(jù)進行隔離,控制僅在必要的空間上或時間上啟用和關(guān)閉Cache。
使用內(nèi)存保護單元MPU
MPU(Memory Protection Unit)內(nèi)存保護單元在ARMv7-M架構(gòu)下被引入。在 ARMv7-M架構(gòu)下,Cortex-M3和Cortex-M4處理器對 MPU 都是選配的,不是必須的。ARMv8-M架構(gòu)下繼續(xù)沿用了MPU,星辰處理器STAR-MC1就使用了ARMv8-M。
MPU是一個可以編程的設(shè)備模塊,可用來定義內(nèi)存空間的屬性,比如特權(quán)指令和非特權(quán)指令,以及Cache是否可訪問。ARMv7-M通常支持8個region,每個region 代表一段連續(xù)的區(qū)域。
關(guān)于MPU的用法,可參見參考文獻中的《ARM-MPU內(nèi)存保護單元詳解》和《Armv8-M Architecture Reference Manual》。
使用內(nèi)存隔離/同步指令
ARM的指令集中,有內(nèi)存隔離指令DMB(Data Memory Barrier)、DSB(Data Synchronization Barrier)和ISB(Instruction Synchronization Barrier):
數(shù)據(jù)存儲器隔離。DMB 指令保證:僅當(dāng)所有在它前面的存儲器訪問操作都執(zhí)行完畢后,才提交(commit)在它后面的存儲器訪問操作。
數(shù)據(jù)同步隔離。比 DMB 嚴(yán)格:僅當(dāng)所有在它前面的存儲器訪問操作都執(zhí)行完畢后,才執(zhí)行在它后面的指令(亦即任何指令都要等待存儲器訪問操作——譯者注)。
指令同步隔離。最嚴(yán)格:它會清洗流水線,以保證所有它前面的指令都執(zhí)行完畢之后,才執(zhí)行它后面的指令。
在一些ARM程序代碼中,會用到__DSB() 指令,特別是在一些中斷處理函數(shù)中。例如:
//中斷定時器PIT中斷處理函數(shù) voidPIT_LED_HANDLER(void) { /*Clearinterruptflag.*/ PIT_ClearStatusFlags(PIT,kPIT_Chnl_0,kPIT_TimerFlag); pitIsrFlag=true; __DSB(); }
程序通過中斷信號進入中斷處理函數(shù)時,首先應(yīng)當(dāng)清除相應(yīng)的中斷標(biāo)志位,但有些CPU的時鐘太快,快于中斷使用的時鐘,就會出現(xiàn)清除中斷標(biāo)志的動作還未完成,CPU就又一次重新進入同一個中斷處理函數(shù),導(dǎo)致死循環(huán),__DSB() 指令的作用就是避免上述情況的發(fā)生。
總結(jié)
本文從修復(fù)MicroPython啟動程序在MM32F5微控制器上比較慢的問題,體驗了星辰處理器中Cache的作用。簡單介紹了Cache的工作原理和機制,重點介紹了使用Cache可能存在的風(fēng)險,并進一步探討了如何能用到Cache高速存取的同時避免數(shù)據(jù)不一致的情況。
-
微控制器
+關(guān)注
關(guān)注
48文章
7933瀏覽量
154110 -
處理器
+關(guān)注
關(guān)注
68文章
19852瀏覽量
234206 -
中斷
+關(guān)注
關(guān)注
5文章
905瀏覽量
42633 -
定時器
+關(guān)注
關(guān)注
23文章
3297瀏覽量
117608 -
Cache
+關(guān)注
關(guān)注
0文章
129瀏覽量
28992
原文標(biāo)題:Cache技術(shù)在星辰處理器中的應(yīng)用
文章出處:【微信號:pzh_mcu,微信公眾號:痞子衡嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
Arm中國自主研發(fā)堅挺,星辰處理器正式商用!
處理器在讀內(nèi)存的過程中,CPU核、cache、MMU如何協(xié)同工作?
ARM處理器使用虛擬地址來提供cache index和cache tag
星辰處理器是什么樣的內(nèi)核?相較于Arm Cortex-M系列內(nèi)核又有什么差別
ARM應(yīng)用處理器的Cache level進化歷史闡述
異構(gòu)多處理器系統(tǒng)Cache一致性解決方案
Cache中Tag電路的設(shè)計
處理器中非阻塞cache技術(shù)的研究
安謀中國“星辰”處理器正式商用
基于CACHE高速緩沖存儲器技術(shù)在嵌入式系統(tǒng)中的應(yīng)用

“星辰”處理器是什么樣的內(nèi)核?
“星辰”STAR-MC2:車規(guī)級高性能嵌入式處理器
小編科普一下超標(biāo)量處理器中的Cache
Cache技術(shù)在星辰處理器中的應(yīng)用

評論