本文以RT1050為例,講解如何提升RT1050的代碼運(yùn)行速度,使其發(fā)揮最大性能,并列出在提升性能過程中可能會(huì)遇到的問題以及解決辦法。
1.是誰影響了代碼運(yùn)行速度?
在一般的MCU開發(fā)中,我們習(xí)慣性的將代碼直接下載到MCU的內(nèi)部Flash中,并直接在內(nèi)部Flash中運(yùn)行,在I-CODE、D-CODE總線以及自帶的Flash加速器加持下,這么做似乎也沒什么問題。但作為一款高性能并擁有最高600M主頻的跨界MCU,RT1050并沒有內(nèi)置Flash。那么在實(shí)際開發(fā)中,就必須外置一塊 NOR Flash用于代碼的存儲(chǔ)。
如果此時(shí)我們還像之前開發(fā)一般MCU那樣,讓代碼在Flash運(yùn)行,就會(huì)受限于Flash的讀寫速度,以及MCU與Flash之間的通信速度。那感覺,就像開著V12引擎的布加迪,跑在限速40的公路上,完全發(fā)揮不出來600M主頻的性能,更別談讓代碼的運(yùn)行速度飛起來了。
2. 如何讓代碼運(yùn)行速度飛起來!
代碼必須存儲(chǔ)在Flash中實(shí)現(xiàn)掉電不丟失,而與此同時(shí),我們又要求發(fā)揮600M主頻的最大性能,讓代碼的運(yùn)行速度飛起來,可能你還沒想好怎么做,那就跟著小編一起,由淺到深,用實(shí)際可行的方案,一步步提升代碼運(yùn)行速度,并解決在提升代碼速度時(shí)遇到的阻礙,最后讓代碼的運(yùn)行速度飛起來。
2.1運(yùn)行域和加載域的概念
既然在Flash中運(yùn)行代碼效率不高,那我們首先想到的辦法,就是不讓代碼在Flash中運(yùn)行,那就不得不提到運(yùn)行域和加載域的概念。
代碼在通過編譯器鏈接器的處理后生成了固件文件,此時(shí)有兩個(gè)相關(guān)概念需要留意,就是加載域和運(yùn)行域。
加載域的意思是代碼要下載到哪里。這里肯定要選擇下載到Flash中。運(yùn)行域的意思是代碼在哪里運(yùn)行。例如我們可以指定代碼在RAM中運(yùn)行,那么在__main中,就會(huì)將相關(guān)代碼都拷貝到RAM中,在程序運(yùn)行時(shí),就會(huì)去RAM空間取指、譯碼、執(zhí)行。加載域和運(yùn)行域的定義可以在分散加載文件中完成。
聽起來是個(gè)不錯(cuò)的想法,但是在實(shí)施的過程中,就會(huì)遇到一個(gè)問題,我們所說的代碼,也就是固件的CODE部分,也包含了中斷復(fù)位函數(shù)。我們知道,程序在上電時(shí),硬件會(huì)去相對(duì)地址0x00處取棧指針,而后偏移一個(gè)字,取復(fù)位中斷函數(shù)地址,并在復(fù)位中斷函數(shù)中執(zhí)行系統(tǒng)初始化函數(shù)SystemInit和__mian函數(shù),并在__mian函數(shù)中實(shí)現(xiàn)不同運(yùn)行域的代碼拷貝。按照這種硬件機(jī)制,有一些代碼是要在代碼拷貝之前運(yùn)行的。
因此我們并不能將所有代碼的運(yùn)行域都拷貝到RAM中運(yùn)行。這也是為什么分散加載文件規(guī)定,加載域中的第一個(gè)運(yùn)行域,其起始地址必須和該加載域起始地址相同。
一種可行的辦法是將不能更改運(yùn)行域的代碼提出來,放在加載域的第一個(gè)運(yùn)行域,用于上電啟動(dòng)過程,然后將其他代碼段的運(yùn)行域放在RAM中,這樣一來,在上電啟動(dòng)過程完成,進(jìn)入到mian函數(shù)后,代碼都是在RAM中運(yùn)行的,其速度會(huì)有飛一樣的提升。分散加載文件中相關(guān)示例配置和注釋如圖1所示。
圖1 運(yùn)行域分配
2.2RAM空間的優(yōu)化
以為上述的配置完成之后就可以起飛了嗎?不,還差一點(diǎn)。如果再對(duì)RT1050的存儲(chǔ)結(jié)構(gòu)多點(diǎn)了解,就會(huì)發(fā)現(xiàn)其內(nèi)部的RAM空間被分成了三個(gè)部分。包括ITCM、DTCM和OCRAM。這三個(gè)部分共享512K的RAM空間。在默認(rèn)配置下,ITCM和DTCM各占128K、OCRAM占256K。
根據(jù)RT1050的內(nèi)部總線結(jié)構(gòu),將代碼段放在ITCM、數(shù)據(jù)段放在DTCM中,可以帶來更高的性能和更快的代碼速度。其分散加載的示例配置如圖2所示。
圖2 DTCM空間和ITCM空間分配
講道理,經(jīng)過這樣的處理之后,我們已經(jīng)將代碼和數(shù)據(jù)的運(yùn)行域放在了整個(gè)RT1050運(yùn)行最快的位置,其600M主頻的性能也能最大力度的發(fā)揮出來。但是這樣做是不是就大功告成了呢?可能還不是,在實(shí)際的項(xiàng)目開發(fā)中,還會(huì)遇到一些其他的問題。
2.3其他的一些問題
2.3.1 代碼和數(shù)據(jù)容量的問題
如果不考慮整個(gè)工程的代碼大小,之前所做的一切都是很OK的,但是往往會(huì)遇到一種情況,就是代碼量或者數(shù)據(jù)量太大,已經(jīng)超出了范圍。
如果只是超過了RAM默認(rèn)的配置范圍,那可以將RAM的空間重新分配,以32K為單位,可以按照實(shí)際需要調(diào)整ITCM和DTCM的空間大小,不過有兩點(diǎn)需要注意,一是OCRAM至少要保留32K的空間大小、二是一定要在__main之前調(diào)整好RAM的分區(qū),否則在__mian函數(shù)中拷貝函數(shù)拷貝代碼時(shí)就會(huì)因?yàn)榭臻g不足而產(chǎn)生硬件錯(cuò)誤。
一種可行的辦法是在復(fù)位中斷函數(shù)的起始位置通過匯編指令去調(diào)整RAM的分區(qū),示例代碼如圖3所示。主要是修改三個(gè)寄存器中內(nèi)容,詳細(xì)信息可查閱參考手冊(cè)中相關(guān)的部分。
圖3 通過匯編指令調(diào)整RAM分區(qū)
如果代碼或者數(shù)據(jù)的容量已經(jīng)超出了RAM區(qū)域能調(diào)整的范圍,那就不能將代碼和數(shù)據(jù)的運(yùn)行域都放在RAM中了。例如使用libpng解碼庫(kù)解碼png圖片,可能需要1M以上的堆空間。在這種情況下,可以使用一塊大容量的SDRAM作為輔助,雖然代碼運(yùn)行的速度沒有在RAM中高,但是解決了RAM空間本身不是很充足的問題,且在SDRAM中運(yùn)行代碼肯定會(huì)比在Flash中運(yùn)行代碼要快上很多。
有了SDRAM的加持,就可以選擇性的將需要高速運(yùn)行的代碼或者關(guān)鍵數(shù)據(jù)放在RAM的空間。一些不需要高速運(yùn)行的代碼或者數(shù)據(jù)放在SDRAM的空間。如果需要使用的堆太大,也可以將堆的空間放在SDRAM中。
通過這種策略靈活的調(diào)整之后,在最佳性能和代碼量之間能找到一個(gè)平衡點(diǎn),以更好的應(yīng)用于一些大型的工程,例如帶了操作系統(tǒng)、lwip協(xié)議棧、emWin等。
2.3.2 中斷響應(yīng)的問題
在前面的操作中,我們一直沒有留意中斷這個(gè)對(duì)嵌入式系統(tǒng)十分重要的部分。由前面的操作可知,我們將中斷向量表加載到了Flash中用于上電啟動(dòng),而后就一直沒有管它,只是專注于代碼的運(yùn)行域。但是如果中斷向量表還在Flash中,那么當(dāng)產(chǎn)生中斷的時(shí)候,硬件還是會(huì)到Flash中的中斷向量表位置去查找相應(yīng)的中斷服務(wù)函數(shù),這樣一去一回,無疑就拖慢了中斷的響應(yīng)速度,要知道,在零等待的情況下,RT1050的中斷響應(yīng)時(shí)間可是能達(dá)到20ns的。
可以將中斷向量表也拷貝到RAM中,然后重新對(duì)中斷向量表的地址進(jìn)行映射。一種可行的方式是修改啟動(dòng)文件。在啟動(dòng)文件中再命名一個(gè)中斷向量表,該中斷向量表中添加原中斷向量表中除復(fù)位中斷函數(shù)之外的其他部分,而原中斷向量表中只保留復(fù)位中斷函數(shù)和棧指針。將新做的中斷向量表的運(yùn)行域放在RAM的起始位置。這樣在程序上電的時(shí)候。__main會(huì)將該中斷向量表拷貝到RAM的起始地址,而后在main函數(shù)的開頭,對(duì)中斷向量表進(jìn)行重映射。不過需要注意的是,這種操作有一個(gè)弊端,就是需要保證在復(fù)位到執(zhí)行中斷向量表重映射期間,不能產(chǎn)生除了復(fù)位中斷之外的其他中斷,否則會(huì)造成硬件異常。
3. 代碼運(yùn)行速度已經(jīng)起飛
經(jīng)過上面的處理之后,怎么能不感受一下實(shí)際的起飛效果,可做一個(gè)LED燈翻轉(zhuǎn)的小例程用于測(cè)試,在例程中用軟件延時(shí)的方式翻轉(zhuǎn)小燈。先在Flash中運(yùn)行,讓軟件延時(shí)達(dá)到200ms左右的延時(shí)效果。能正常顯示之后,不改變代碼內(nèi)容,只是將代碼運(yùn)行域放在RAM中,再次運(yùn)行代碼,就能看到,此時(shí)小燈翻轉(zhuǎn)的頻率,已經(jīng)達(dá)到了起飛的效果。
-
mcu
+關(guān)注
關(guān)注
146文章
17173瀏覽量
351622 -
代碼
+關(guān)注
關(guān)注
30文章
4798瀏覽量
68725 -
編譯器
+關(guān)注
關(guān)注
1文章
1635瀏覽量
49171
原文標(biāo)題:如何讓RT1050的代碼運(yùn)行速度飛起來
文章出處:【微信號(hào):Zlgmcu7890,微信公眾號(hào):周立功單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論