新聞中心

ARM菜鳥成長記--之三

作者: 時(shí)間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
提起啟動(dòng)代碼,我就嗷嗷郁悶,IAR下的程序都死在了這里,Keil中出現(xiàn)的問題很多都是通過對啟動(dòng)代碼的修修補(bǔ)補(bǔ)才解決的,一句話:成也啟動(dòng)代碼,敗也啟動(dòng)代碼。
啟動(dòng)代碼應(yīng)該是剛接觸ARM的新手必須面對而又很頭痛的問題吧,剛開始我也很納悶,為什么搞個(gè)這玩意,學(xué)51的時(shí)候咋就沒見過呢。而且還都是匯編寫的,俺的匯編還停留在“MOV”階段,其他的不是很懂,沒辦法,誰讓匯編的效率高呢。提到啟動(dòng)代碼還不得不老生常談一下其中要完成的任務(wù):
1、建立異常中斷向量表,ARM從0X0開始給每個(gè)異常中斷分配4個(gè)字節(jié)的空間,一般存放一個(gè)跳轉(zhuǎn)指令(B)或PC的裝載指令(LDR PC,X_Vector),當(dāng)發(fā)生異常時(shí),ARM從此處取得相應(yīng)異常中斷處理程序入口地址,再跳轉(zhuǎn)執(zhí)行;
2、ARM都是高速處理器,而在高速下啟動(dòng)很可能會(huì)不穩(wěn)定,所以在啟動(dòng)代碼從慢時(shí)鐘開始運(yùn)行,在適當(dāng)?shù)奈恢?,?2.768K切換到高速運(yùn)行;
3、ARM一般帶有片外存儲(chǔ)器,F(xiàn)lash、SDRAM等,這些存儲(chǔ)器都需要初始化才能使用,這都是在啟動(dòng)代碼中完成,但是Norflash的初始化要在時(shí)鐘初始化之前;
4、ARM有不同的模式,每種模式都需要相應(yīng)的堆棧;
5、Copy異常中斷向量表到RAM,并實(shí)現(xiàn)REMAP,具體請參照上一節(jié);
6、Copy可執(zhí)行映像的數(shù)據(jù)段到RAM,并將ZI區(qū)清零。這個(gè)一般都是由編譯器完成的,IAR下是?main來實(shí)現(xiàn),Keil中由__main實(shí)現(xiàn)。
現(xiàn)在啟動(dòng)代碼可以看懂一些,不過自己寫啟動(dòng)代碼還是很遙遠(yuǎn)的事情。如果開始對啟動(dòng)代碼很抵觸,可以考慮使用Keil,因?yàn)镵eil由啟動(dòng)代碼的圖形化配置,直接點(diǎn)擊鼠標(biāo)操作就可以實(shí)現(xiàn)自己的啟動(dòng)代碼。下面結(jié)合我們at91sam9260的板子,說說Keil中的啟動(dòng)代碼。

打開Keil生成的SAM9260.S,點(diǎn)擊左下角的“Configuration Wizard”進(jìn)入圖形化配置向?qū)?,根?jù)你的需要選擇參數(shù),全部選擇完畢后,再點(diǎn)擊"Text Editor",將會(huì)看到生成的啟動(dòng)代碼。
我靠,不是吧,將近2000行,開始你可能會(huì)很泄氣,但仔細(xì)一看,前面不都是些宏定義嘛,跟圖形化配置向?qū)б灰粚?yīng)的,只有從1200多行的這一句開始的才是真正的啟動(dòng)代碼部分。
;----------------------- CODE --------------------------------------------------

PRESERVE8
開始是8個(gè)PC裝載指令,注意第六個(gè)向量,即地址0X14處,存放可執(zhí)行映像的大小,||Image
ERROM1
RO
Length||+||Image
RW_RAM1
RW
Length||
。
接下來是SMC、PMC的初始化,我們的板子外擴(kuò)了Norflash,如果在未初始化Norflash前,切換到快時(shí)鐘,系統(tǒng)起不來,所以應(yīng)該先初始化SMC,再初始化PMC,而Keil自帶的啟動(dòng)代碼中默認(rèn)PMC在前,怎么辦,可以將前面PMC的宏定義部分和初始化部分剪切,然后分別粘貼在SMC宏定義部分和初始化部分的后面,然后再看“Configuration Wizard”中,PMC自動(dòng)放到了SMC的后面了。
接下來是關(guān)閉看門狗(默認(rèn)是打開的),拷貝異常中斷表到RAM中,然后REMAP,建立緩存,建立各個(gè)模式的堆棧指針
最后進(jìn)入__main進(jìn)行數(shù)據(jù)段和代碼段的拷貝以及初始化C語言庫函數(shù),然后跳轉(zhuǎn)到main執(zhí)行。

Keil中有詳細(xì)的注釋,理解起來應(yīng)該不是很難,具體的語句無需明白,知道個(gè)大致意思就行了。無非是將某個(gè)外設(shè)的基地址裝載(LDR)到一個(gè)寄存器R0,將要向這個(gè)外設(shè)的某個(gè)寄存器賦的值裝載到另一個(gè)寄存器R1,然后加載(STR)。一般的模式就是這樣:
LDR R0,=Periphral_BASE ;某外設(shè)的基地址
LDR R1,=0XFFFF0000 ;向寄存器要賦的值
STR R1,[R0,#Periphral_Register_OFS] ;向外設(shè)Peripheral基地址偏移OFS的寄存器Register賦值0xFFFF0000

Keil的啟動(dòng)代碼部分有兩個(gè)注意的地方:
1、啟動(dòng)代碼中有很多IF語句,如:IF :DEF:RAM_INTVEC。這就可以通過在Options/Asm對話框中的Define中填入RAM_INTVEC就可以實(shí)現(xiàn)中斷向量從Flash到RAM的拷貝。同理,還有IF :DEF:REMAP等等;
2、帶有Keil特色的MICROLIB,通過在Options/Target中選擇“Used MICROLIB”,比不使用微庫相比生成的代碼較小。不過除此之外,應(yīng)該還有其他的關(guān)系,因?yàn)槲覀兊某绦蛉绻x擇不使用微庫的話,就執(zhí)行不成功。對于微庫只有這些很片面的理解,還請老手指教。

總而言之,Keil中的啟動(dòng)代碼還是比較好理解的,而且借助圖形化配置向?qū)В梢愿斓纳鲜?,以?shí)現(xiàn)自己的啟動(dòng)代碼。

下面要說說Keil下,怎樣實(shí)現(xiàn)程序在片外Norflash運(yùn)行、片外SRAM調(diào)試、片外SRAM運(yùn)行。


關(guān)鍵詞: ARM菜鳥成長

評論


技術(shù)專區(qū)

關(guān)閉