免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
ARM系統(tǒng)中斷向量表的動(dòng)態(tài)配置
通常情況下32位ARM嵌入式系統(tǒng)的中斷向量表是程序編譯前設(shè)置好的。在編寫(xiě)32位ARM 嵌入式系統(tǒng)的中斷

服務(wù)程序、設(shè)置和修改ARM體系結(jié)構(gòu)的中斷向量表時(shí),常感到相當(dāng)麻煩,不得不修改匯編代碼,對(duì)不喜歡

使用匯編代碼編程的程序員尤其如此。 當(dāng)需要在程序運(yùn)行過(guò)程中動(dòng)態(tài)修改中斷向量的程序時(shí)會(huì)感到更為

不便,不得不增加很多分支處理指令才能實(shí)現(xiàn)。為此本文提出一種簡(jiǎn)便高效的配置方法,實(shí)現(xiàn)了 ROM固

化程序在運(yùn)行時(shí)動(dòng)態(tài)配置ARM嵌入式系統(tǒng)中斷向量表的功能。
1 ARM中斷向量?jī)煞N設(shè)置方法
在32位ARM系統(tǒng)中,一般都是在中斷向量表中放置一條分支指令或PC寄存器加載指令,實(shí)現(xiàn)程序跳轉(zhuǎn)到中

斷服務(wù)例程的功能。例如:
IRQEntry B HandleIRQ ;跳轉(zhuǎn)范圍較小
B HandleFIQ
或IRQEntry LDR PC,=HandleIRQ ;跳轉(zhuǎn)的范圍是任意32位地址空間
LDR PC,=HandleFIQ
LDR偽指令等效生成1條存儲(chǔ)讀取指令和1條32位常數(shù)定義指令。32位常數(shù)存儲(chǔ)在LDR指令四周的存儲(chǔ)單元

中,相對(duì)偏移小于4KB。該32位數(shù)據(jù)就是要跳轉(zhuǎn)到的中斷服務(wù)程序入口地址。
之所以使用LDR偽指令,是因?yàn)锳RM的RISC指令為單字指令,不能裝載32位的立即數(shù) (常數(shù)),無(wú)法直接

把一個(gè)32位常數(shù)數(shù)據(jù)或地址數(shù)據(jù)裝載到寄存器中。下面一般程序與上述偽指令功能等效,但中斷向量表

描述得更為清楚。其中 VectorTable為相對(duì)LDR指令的偏移量:
IRQEntry LDR PC,VectorTable 0
;與LDR PC,=HandleIRQ等效
LDR PC,VectorTable 4
;與LDR PC,=HandleFIQ等效
……
VectorTable DCD HandleTRQ
DCD HandleFIQ
……
HandleIRQ
……
HandleFIQ
一般ARM嵌入式系統(tǒng)的程序都是固化在從00000000H開(kāi)始的低端ROM空間中,中斷 向量表VectorTable也是

固化在ROM中,所以上述兩種方法都無(wú)法在程序運(yùn)行時(shí)動(dòng)態(tài)隨機(jī)修改中斷向量表。不論對(duì)于初學(xué)ARM處理

器的程序員還是有 經(jīng)驗(yàn)的程序員,設(shè)置中斷向量都相當(dāng)繁瑣,必須修改ARM的C程序的啟動(dòng)代碼。一段晦

澀的匯編代碼很不方便,比較輕易出錯(cuò)。
2 X86與ARM處理器中斷向量表比較
實(shí)模式X86程序員都熟悉,在X86體系結(jié)構(gòu)的PC系統(tǒng)中,不論是用匯編還是用C語(yǔ)言,都可以動(dòng)態(tài)隨機(jī)地設(shè)

置、修改中斷向量表—只需要簡(jiǎn)單地把中斷程序例程的入口地址寫(xiě)入到中斷向量表數(shù)據(jù)區(qū),即可完成向

量表的設(shè)置。
X86向量表設(shè)置方便的原因有兩個(gè)。其一是中斷向量表與程序代碼完全分離,中斷向量表設(shè)置 在RAM數(shù)據(jù)

空間,向量表存放的數(shù)據(jù)是純粹地址數(shù)據(jù);而在ARM向量表中存放的是與中斷服務(wù)例程入口有關(guān)的一條分

支指令。另一個(gè)原因是,除BIOS外,大 多數(shù)PC程序都是在運(yùn)行時(shí)加載到RAM中的,程序數(shù)據(jù)是不加區(qū)別

的,所以可以很輕易在程序運(yùn)行的過(guò)程中從數(shù)據(jù)生成程序,并可以很輕易把CPU控制權(quán)轉(zhuǎn)到新 生成的程

序中。
表面上看,在ARM第二種中斷向量設(shè)置方法的向量表VectorTable中也是純地址數(shù) 據(jù),不含指令代碼,似

乎可以把VectorTable設(shè)置在RAM數(shù)據(jù)段中。然而一般ARM體系的ROM代碼段和RAM數(shù)據(jù)段間的偏移遠(yuǎn)大于2

12,故超出了LDR使用PC為基址的相對(duì)尋址范圍。
代碼中的VectorTable是一個(gè)與當(dāng)前PC間的一個(gè)偏移,LDR指令的相對(duì)地址是在 編譯時(shí)計(jì)算的,要求

VectorTable<2 12,所以VectorTable不能隨意安排在RAM空間中。VectorTable一般只能安排在中斷跳轉(zhuǎn)

指令四周的代碼區(qū)內(nèi)中。
3 ARM結(jié)構(gòu)中中斷向量表的動(dòng)態(tài)配置方法
要在ARM結(jié)構(gòu)中實(shí)現(xiàn)與X86中一樣方便的在中斷向量的隨機(jī)存取功能,向量表的地址數(shù)據(jù)必須可以安排在

任意32位地址的RAM空間中。為此,中斷處理必須增加一條指令,先跳轉(zhuǎn)到向量表,然后執(zhí)行向量表中動(dòng)

態(tài)生成的跳轉(zhuǎn)指令,跳轉(zhuǎn)到中斷服務(wù)程序,參見(jiàn)下列初始化代碼:
;******向量表******
ENTRY
B ResetHandle ;原向量偏移 ,中斷號(hào)
B ReseHandle ;0x00 ,00
LDR PC,=NewVectorTable 0x08 ;0x04,未定義 ,01
LDR PC,=NeWVector Table 0x10 ;0x08,SWI,02
LDR PC,=NewVectorTable 0x18 ;0x0c,未定義 ,03
LDR PC,=NewVectorTable 0x20 ;0x10,未定義 ,04
LDR PC,=NewVectorTable 0x28;0x14,未定義 0,05
LDR PC,=NewVectorTable 0x30 ;0x18,IRQ ;06
LDR PC,=NewVectorTable 0x38 ;0x1c,FIQ ,07
……
;******代碼段******
ResetHandle

……

;***數(shù)據(jù)段,為NewVectorTable分配數(shù)據(jù)空間***

NewVectorTable # 128;大小根據(jù)需要定義,每向量2個(gè)字(8字節(jié));

程序運(yùn)行時(shí),中斷服務(wù)的初始化 程序必須設(shè)置好新的中斷向量表,即在NewVectorTable表中動(dòng)態(tài)生成下
列指令:

NewVectorTable;表安排在RAM頂端0x0c1fff00處(由硬件設(shè)定)

LDR PC,[PC,#4];指令代碼為0xe51ff004,功能為PC〈-[PC 4]

nVt00 DCD ISR_RESET_HANDLE

LDR PC,[PC,#4];與LDR PC,nVt01指令等效

nVt01 DCD ISR_UNDEF_HANDLE

LDR PC,[PC,#4]

nVt02 DCD ISR_SWI_HANDLE

LDR pC,[PC,#4]

nVt03 DCD ISR_UNDEF_HANDLE

LDR PC,[PC,#4]

nVt04 DCD ISR_UNDEF_HANDLE

LDR PC,[PC,#4]

nVt05 DCD ISR_UNDEF_HANDLE

LDR PC,[PC,#4]

NVt06 DCD ISR_IRQ_HANDLE

LDR PC,[PC,#4]

nVt07 DCD ISR_FIQ_HANDLE

……

可用C函數(shù)在NweVectorTable中生成含上述指令的向量表,具體實(shí)現(xiàn)如下:

#define VECTOR_TABLE 0x0c1fff00

//向量表首地址,根據(jù)實(shí)際硬件來(lái)配置

#define INSTRUCTION_LDR_PC 0xe51ff004

//加載PC寄存器的指令碼

//設(shè)置向量C函數(shù),ISR_Handle中斷服務(wù)程序地址

void SetVector(unsigned char no,unsigned long int ISR_Handle){

unsigned long int * pVectorTable;

//定義32位無(wú)符號(hào)數(shù)指令,指向向量表

pVectorTable=((unsigned long int *)(VECTOR_TABLE (no<<3)));

*pVectorTable =INSTRUCTION_LDR_PC;

//在向量表中放置LDR PC,[PC,#4]指令

*pVectorTable=ISR_Handle;//設(shè)置中斷服務(wù)例程入口地址}

//讀取向量C函數(shù),no代表中斷號(hào)

unsigned long int GetVector(unsigned char no){

unsigned long int *pVectorTable;

pVectorTable=((unsigned long int *)(VECTOR_TABLE (no<<3)));

return *( pVectorTable);//返回中斷處理程序入口地址

}

使用上述初始化代碼和向量設(shè)置函數(shù),除復(fù)位向量外,其它所有中斷向量都可以指向了在RAM 數(shù)據(jù)區(qū)中
的新向量表,并給定一個(gè)統(tǒng)一的中斷編號(hào)。中斷服務(wù)程序可以放在任何模塊文件中編譯連接,不需要修
改原向量表代碼,但在打開(kāi)中斷使用中斷服務(wù)例程前必須使用C函數(shù)SetVector()設(shè)置中斷向量。

4 結(jié)論

本文提出的中斷向量表配置策略和實(shí)現(xiàn)方法,簡(jiǎn)便高效,僅比標(biāo)準(zhǔn)處理方法增加一條指令的執(zhí)行時(shí)間。
當(dāng)把ARM的C初始化匯編代碼中所有中斷源(包括擴(kuò)展的內(nèi)外部中斷源)的向量都指向了新向量表,并統(tǒng)
一編號(hào),此后編寫(xiě)任何中斷服務(wù)程序幾乎不需要修改匯編代碼,C初始化代碼完全可以對(duì)C程序員隱藏起
來(lái),并可以像在X86體系下一樣動(dòng)態(tài)地設(shè)置和修改中斷向量。初始化應(yīng)用程序執(zhí)行環(huán)境
   映像一開(kāi)始總是存儲(chǔ)在ROM/Flash里面的,其RO部分即可以在ROM/Flash里面執(zhí)行,也可以轉(zhuǎn)移到
速度更快的RAM中執(zhí)行;而RW和ZI這兩部分是必須轉(zhuǎn)移到可寫(xiě)的RAM里去。所謂應(yīng)用程序執(zhí)行環(huán)境的初始化
,就是完成必要的從ROM到RAM的數(shù)據(jù)傳輸和內(nèi)容清零。

下面是在ADS下,一種常用存儲(chǔ)器模型的直接實(shí)現(xiàn):
LDR  r0,=|Image$$RO$$Limit| 得到RW數(shù)據(jù)源的起始地址
LDR  r1,=|Image$$RW$$Base| RW區(qū)在RAM里的執(zhí)行區(qū)起始地址
LDR  r2,=|Image$$ZI$$Base| ZI區(qū)在RAM里面的起始地址
CMP  r0,r1         比較它們是否相等
   BEQ  %F1
0   CMP  r1,r3
   LDRCC r2,[r0],#4STRCC r2,[r1],#4
   BCC  %B0
1   LDR  r1,=|Image$$ZI$$Limit|
   MOV  r2,#0
2   CMP  r3,r1
   STRCC r2,[r3],#4
   BCC  %B2
   程序?qū)崿F(xiàn)了RW數(shù)據(jù)的拷貝和ZI區(qū)域的清零功能。其中引用到的4個(gè)符號(hào)是由鏈接器第一輸出的。
|Image$$RO$$Limit|:表示RO區(qū)末地址后面的地址,即RW數(shù)據(jù)源的起始地址
|Image$$RW$$Base|:RW區(qū)在RAM里的執(zhí)行區(qū)起始地址,也就是編譯器選項(xiàng)RW_Base指定的地址
|Image$$ZI$$Base|:ZI區(qū)在RAM里面的起始地址
|Image$$ZI$$Limit|:ZI區(qū)在RAM里面的結(jié)束地址后面的一個(gè)地址

   程序先把ROM里|Image$$RO$$Limt|開(kāi)始的RW初始數(shù)據(jù)拷貝到RAM里面|Image$$RW$$Base|開(kāi)始的地
址,當(dāng)RAM這邊的目標(biāo)地址到達(dá)|Image$$ZI$$Base|后就表示RW區(qū)的結(jié)束和ZI區(qū)的開(kāi)始,接下去就對(duì)這片ZI
區(qū)進(jìn)行清零操作,直到遇到結(jié)束地址|Image$$ZI$$Limit|

改變處理器模式
   因?yàn)樵诔跏蓟^(guò)程中,許多操作需要在特權(quán)模式下才能進(jìn)行(比如對(duì)CPSR的修改),所以要特別注
意不能過(guò)早的進(jìn)入用戶(hù)模式。

   內(nèi)核級(jí)的中斷使能也可以考慮在這一步進(jìn)行。如果系統(tǒng)中另外存在一個(gè)專(zhuān)門(mén)的中斷控制器,這么做
總是安全的。

呼叫主應(yīng)用程序

   當(dāng)所有的系統(tǒng)初始化工作完成之后,就需要把程序流程轉(zhuǎn)入主應(yīng)用程序。最簡(jiǎn)單的一種情況是:
IMPORT main


B   main
直接從啟動(dòng)代碼跳轉(zhuǎn)到應(yīng)用程序的主函數(shù)入口,當(dāng)然主函數(shù)名字可以由用戶(hù)隨便定義。
在ARM ADS環(huán)境中,還另外提供了一套系統(tǒng)級(jí)的呼叫機(jī)制。
IMPORT __mainB   __main
__main()是編譯系統(tǒng)提供的一個(gè)函數(shù),負(fù)責(zé)完成庫(kù)函數(shù)的初始化和初始化應(yīng)用程序執(zhí)行環(huán)境,最后自動(dòng)跳
轉(zhuǎn)到main()函數(shù)
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
AT91初始化代碼手冊(cè)中文翻譯版
ARM啟動(dòng)代碼分析
44B0 中斷分析(一)
ARM7在嵌入式應(yīng)用中啟動(dòng)程序的實(shí)現(xiàn) --zbxuhqu
ARM7TDMI的存儲(chǔ)器及其地址映射
u-boot中.lds連接腳本文件的分析
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服