8051 與 AndesCoreTM 的軟件差異與移植
5. 中斷向量及異常處理函數(shù)例子
本文引用地址:http://2s4d.com/article/277992.htm以中斷向量及中斷處理函數(shù)的例子說明差異及移植。
5.1. 匯編實現(xiàn)中段向量表
[8051]
該例子顯示怎樣用匯編設(shè)置 8051 的中斷向量和中斷處理函數(shù),在 8051 匯編 中 ORG 指定了后面匯編代碼的位置,后面的中斷向量通常是一個跳轉(zhuǎn)語句。如 下例第一個向量跳到主函數(shù) MAIN 函數(shù)中,另外一個外部中斷 1,也是一個跳轉(zhuǎn)指 令:LJMP INT 到后面的用匯編實現(xiàn)的中斷處理函數(shù) INT 中。
ORG 0000H /*起始地址*/ LJMP MAIN /*跳轉(zhuǎn)到主程序*/ ORG 0013H /*外部中斷 1 的地址 LJMP INT /*跳轉(zhuǎn)到 INT 執(zhí)行*/ ORG 0100H /*主程序的起始地址 MAIN: MOV A,#0FEH /*將 FEH 送給 A*/ SETB IT1 /*外部中斷 1 跳變沿觸發(fā)方式*/ SETB EX1 /*外部中斷 1 開中斷*/ SETB EA /*CPU 開中斷*/ MOV P0,A /*將 A 送給 P0*/ LOP: LJMP LOP /*循環(huán)等待*/ INT: RL A /*A 循環(huán)左移*/ MOV P0,A /*將 A 的數(shù)值送給 P0*/ RETI /*中斷返回*/ END /*程序結(jié)束*/ |
[AndesCore?]
該例子顯示怎樣用匯編設(shè)置 AndesCore?的中斷向量表和中斷處理函數(shù),該 例子中 exception_vector 是中斷向量表的 label, 后面分別表示第 0,1,2,3…個中 斷向量,它們只是簡單的跳轉(zhuǎn)指令,跳到具體的執(zhí)行實體中去,如 vector 0 跳到_start,做系統(tǒng)相關(guān)的初始化操作,_start 是系統(tǒng)啟動代碼,用匯編語言來實現(xiàn)。vector 9 后面對應(yīng)的是外部中斷,中斷處理函數(shù)如 OS_Trap_Interrupt_HW0, OS_Trap_Interrupt_HW1… 它通常用 C 來實現(xiàn),可以參考后面 5.2 章節(jié)的 AndesCore?中斷處理函數(shù)范例。
! 中斷向量表所在的 section,該 section 在鏈接后會被存放在第一條指令 執(zhí)行處,通常是 0 位置 .section .vector, "ax" !==================================================== ! Vector table !==================================================== .align 3 exception_vector: ! 以下是中斷向量表 j _start ! (0) Trap Reset j OS_Trap_TLB_Fill ! (1) Trap TLB fill j OS_Trap_PTE_Not_Present ! (2) Trap PTE not present j OS_Trap_TLB_Misc ! (3) Trap TLB misc j OS_Trap_TLB_VLPT_Miss ! (4) Trap TLB VLPT miss j OS_Trap_Machine_Error ! (5) Trap Machine error j OS_Trap_Debug_Related ! (6) Trap Debug related j OS_Trap_General_Exception ! (7) Trap General exception j OS_Trap_Syscall ! (8) Syscall j OS_Trap_Interrupt_HW0 ! (9) Interrupt HW0 j OS_Trap_Interrupt_HW1 ! (10) Interrupt HW1 ....... ....... ....... ! _start 函數(shù),是中斷向量 0 對應(yīng)的中斷處理函數(shù) .align 2 _start: ! ******** Begin of do-not-modify ************ ! Please don’t modify this code ! Initialize the registers used by the compiler #ifndef CONFIG_NO_NDS32_EXT_EX9 ! make sure the instruction before setting ITB ! will not be optimized with ex9 .no_ex9_begin ! disable ex9 generation #endif ! Support Relax, Set $gp to _SDA_BASE_ la $gp, _SDA_BASE_ ! init GP for small data access #ifndef CONFIG_NO_NDS32_EXT_EX9 ! Initialize the table base of EX9 instruction la $r0, _ITB_BASE_ ! init ITB mtusr $r0, $ITB .no_ex9_end #endif !*********** End of do-not-modify************ la $fp, _FP_BASE_ ! init $fp la $sp, _stack ! init $sp 初始化堆棧寄存器 #ifdef CFG_LLINIT bal _nds32_init_mem ! 初始化 DRAM #endif bal __init ! 初始化 CPU,SoC,C 運(yùn)行環(huán)境等 bal main ! 最后跳轉(zhuǎn)到 main 函數(shù) 1: b 1b |
在上面用匯編設(shè)置 AndesCore?的中斷向量表的例子中,我們需要將中斷向量表最終設(shè)定在 0 地址處,可以通過 section 語法配合 sag 工具實現(xiàn),例子中我們設(shè)定 該段 的 section 名為 .vector, 所 以在 sag 中 ,我 們自 定義一個 USER_SECTION 為.vector,并將.vector 放在 0 開始的地方并作為第一個 section。
USER_SECTIONS .vector SDRAM 0x00000000 0x00800000 ; address base 0x00000000, max_size=8M ;指定 LMA 為從 0 開始 { EXEC 0x00000000 ;指定 VMA 為 0 { * (.vector) ;放在 0 開始的地方并作為第一個 section * (+RO,+RW,+ZI) STACK = 0x00800000 } } |
通過上面的 sag 語法,并使用 andes 提供的 sag 轉(zhuǎn) ld 的工具,可以產(chǎn)生類似以下的 ld,在工程進(jìn)行鏈接的時候選擇該 ld 時就能確保 .vector 鏈接的地址位 于 0 處。
/* This file is generated by nds_ldsag (version 20140127). */ ENTRY(_start) SECTIONS { PROVIDE (__executable_start = 0x00000000); NDS_SAG_LMA = 0x00000000 ; SDRAM_BEGIN = NDS_SAG_LMA; . = 0x00000000; ; 起始地址為 0 .vector : { *(.vector) } ; .vector 在 0 開始的位置 .nds32_init : { KEEP(*(.nds32_init)) } .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } ...... |
關(guān)于詳細(xì)的 SAG 使用,可以參考我們的另一篇文章:《Andes 的分散聚合(SAG)機(jī)制》http://www.andestech.com/cn/news-events/technical-article/2014/Andes20141008.pdf
5.2. 中斷處理函數(shù)的 C 實現(xiàn)
[8051]
怎樣用 C 寫 8051 的中斷處理函數(shù)范例
/* com interrupt handler */ void com_int(void) interrupt 4 // 有指定 interrupt 號 { /* com interrupt handler here */ } |
[AndesCore?]
怎樣用 C 寫 AndesCore?的中斷處理函數(shù)范例
void syscall_handler() // 和普通函數(shù)的寫法相同 { puts("this is syscall handlern"); } |
6. 適用于 MCU 的 Andes CPUs
Andes 有三款非常適用于 MCU 應(yīng)用的 CPU,分別是:N705,N801,N968A,如 下圖所列:
N705 和 N801 分別采用了兩級和三級流水線,都具有很低的功耗和很好的性 能,當(dāng)應(yīng)用需要的頻率較低時,使用兩級流水線的 N705 能發(fā)揮出更好的性能和 更低功耗的特性,相比于 8051,兩級流水線的 N705 在頻率方面高出許多,比 如在 TSMC 40nm LP 工藝下能跑到超過 240MHz,所以完全能勝任 8051 的應(yīng) 用需求。N968A 使用了五級的流水線,同樣有低功耗的特性和很好的性能,同 時該款 CPU 具有很強(qiáng)的可配置性,如支持多種總線接口,還支持了專門為 audio 的加速指令,N968A 是一個多面手,性能好,功耗低,又具備強(qiáng)大的可配置特 性,適合于多種應(yīng)用。
7. 總結(jié)
AndesCore?使用標(biāo)準(zhǔn)的 C 語法開發(fā),方便快捷,同時作為 32 位 RISC(精 簡指令集)架構(gòu)的 CPU,AndesCore?有多款適用于 MCU 應(yīng)用的 CPU,相對于8051 具有功耗,性能方面優(yōu)勢。想了解更多 AndesCore?細(xì)節(jié),可以登陸www.andestech.com。
存儲器相關(guān)文章:存儲器原理
評論