從8/16位向32位圖形MCU升級(jí)的技巧
測(cè)量性能本文引用地址:http://www.ex-cimer.com/article/173681.htm
在早期的一些日子里,我的好奇心促使我想知道PIC32究竟帶來(lái)什么好性能。在我的16位器件一書(shū)的第四章中,即“Numb3rs”,我對(duì)執(zhí)行基本的算術(shù)運(yùn)算所需的指令周期數(shù)進(jìn)行了統(tǒng)計(jì),并將它們與各類整數(shù)和浮點(diǎn)類型進(jìn)行了比較。這在時(shí)鐘周期與所執(zhí)行的指令密切相關(guān)的場(chǎng)合,如PIC24和dsPIC DSC內(nèi)核中那樣,這種方法是合理的。但在PIC32內(nèi)核中,由于采用了MIPS的傳統(tǒng),為“比賽”增加了“難度”。每個(gè)時(shí)鐘周期所執(zhí)行的指令是可變的,因?yàn)楫?dāng)執(zhí)行代碼快于閃存額定速度(每30MHz只插入一個(gè)時(shí)鐘周期)時(shí)可以插入等待狀態(tài),或者可以無(wú)關(guān),這要?dú)w功于預(yù)取狀態(tài)機(jī)(能夠一次預(yù)取四條指令)。最后,激活一個(gè)高速緩存,進(jìn)一步改進(jìn)了高速性能。
PIC32的高速緩存使得周期數(shù)有點(diǎn)不可預(yù)測(cè),也許變得沒(méi)有意義。我好像覺(jué)得我從貨物推車一下子升級(jí)到了一級(jí)方程式賽車一樣!于是,我決定需要在32位器件一書(shū)中增加一章關(guān)于PIC32的性能調(diào)整內(nèi)容。為了給PIC32加上重載荷,我找到我在大學(xué)讀書(shū)時(shí)學(xué)習(xí)基本數(shù)字信號(hào)處理的一個(gè)老代碼程序:即快速付里葉變換。我采用的是標(biāo)準(zhǔn)浮點(diǎn)結(jié)構(gòu),沒(méi)有手工和編譯器優(yōu)化。另外還用了一個(gè)32位定時(shí)器,讓PIC32自己計(jì)時(shí),隨后我逐步地開(kāi)始選用一些新的程序選項(xiàng)。
開(kāi)始時(shí),我激活指令預(yù)取,然后我找到高速緩存,再隨后我通過(guò)人工方式調(diào)整等待狀態(tài)。一開(kāi)始性能改善極大,并且隨著之后對(duì)配置進(jìn)行進(jìn)一步的細(xì)調(diào),性能改善更多。最終,我意識(shí)到最佳的配置必須隨應(yīng)用定制,但必須由標(biāo)準(zhǔn)器件庫(kù)中的SYSTEMConfigPerformance()提供一個(gè)好的起點(diǎn)。
學(xué)習(xí)外設(shè)庫(kù)
這是我第一次使用“標(biāo)準(zhǔn)”外設(shè)庫(kù),也是這種愛(ài)/恨關(guān)系的開(kāi)始。由于我在非常小型的8位器件上使用匯編進(jìn)行代碼開(kāi)發(fā)已經(jīng)許多年了,且通常都是需要采用手工優(yōu)化客戶代碼,我基本上都是自己親自工作,最終我開(kāi)發(fā)出了一些自己的器件庫(kù)。
這一次,在投放PIC32產(chǎn)品之前一年多的時(shí)間,我不僅移植了16位器件的庫(kù),還對(duì)它們進(jìn)行了擴(kuò)展來(lái)支持一系列新功能。我沒(méi)有更多的理由-唯一理由就是我自己必須掌握并學(xué)會(huì)如何使用它們。參見(jiàn)用于一個(gè)使用該外設(shè)庫(kù)的程序代碼段的Listings1和2,見(jiàn)圖2。
圖2:代碼移植時(shí)用于一個(gè)使用該外設(shè)庫(kù)的程序代碼段的Listings1和2。
通過(guò)利用這個(gè)新庫(kù),16位和32位應(yīng)用之間的代碼兼容“絕對(duì)”沒(méi)有問(wèn)題。即便是外設(shè)寄存器上的極小差別也可以通過(guò)應(yīng)用代碼完全消除。實(shí)際上,這使得一個(gè)應(yīng)用在16位器件和32位器件上都可以運(yùn)行,從而開(kāi)發(fā)人員面向兩種架構(gòu),卻維護(hù)統(tǒng)一的代碼基。
不過(guò),雖然在器件數(shù)據(jù)頁(yè)中對(duì)硬件控制寄存器名稱已有注明(甚至每一位都很詳細(xì)),但卻沒(méi)有所有的功能/宏名及其參數(shù)。很多時(shí)候,我發(fā)現(xiàn)必須將單個(gè)的包含文件與器件數(shù)據(jù)頁(yè)進(jìn)行比較,嘗試著去猜測(cè)究竟有哪些控制位與一個(gè)特定的庫(kù)參數(shù)相關(guān)。當(dāng)利用最簡(jiǎn)單的庫(kù)(比如I/O端口操作)時(shí),這是一件特別麻煩的事情,對(duì)我來(lái)說(shuō),在這里,庫(kù)抽象層的優(yōu)點(diǎn)更值得質(zhì)疑。
最終,我發(fā)現(xiàn)可以采取一個(gè)平衡折中。即可以采用傳統(tǒng)的方法訪問(wèn)絕大部分的基本外設(shè)(例如I/O端口和計(jì)時(shí)器),而在使用更復(fù)雜/新外設(shè)時(shí)才使用庫(kù)。于是,我迅速通過(guò)了有關(guān)代碼的幾個(gè)章節(jié),實(shí)際上什么都沒(méi)有改。這些章節(jié)包括:SD/MMC接口,F(xiàn)AT16文件I/O甚至包括WAV音樂(lè)文件重放。
當(dāng)我決定再深入地研究中斷時(shí),以及后來(lái)開(kāi)始使用PIC32的新DMA模塊時(shí),這些庫(kù)的好處就變得很明顯了。
中斷和決策
PIC32提供兩種中斷選擇:一種是非常類似于PIC16/18 8位架構(gòu)操作方式的單矢量模式(順便指出,與RTOS也更加友好),另一種是更類似于16位PIC24 MCU和dsPIC DSC工作模式的多矢量模式。利用interrupt.h庫(kù)來(lái)設(shè)置參數(shù)是輕而易舉的事情。
評(píng)論