在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 設(shè)計(jì)應(yīng)用 > ARM中斷實(shí)現(xiàn)過程的個(gè)人筆記

            ARM中斷實(shí)現(xiàn)過程的個(gè)人筆記

            ——
            作者: 時(shí)間:2006-06-12 來源: 收藏
            決定開始學(xué)習(xí)嵌入式后,最先做的事情就是要熟悉ARM指令及其偽指令偽操作。ARM指令的助記符其實(shí)都是其具體功能的單次縮寫,所以學(xué)習(xí)的過程中最好利用網(wǎng)絡(luò),從一些文獻(xiàn)或書籍中找到ARM指令助記符的全稱,這樣方便記憶。學(xué)完之后,我做了整理了一個(gè)有關(guān)這方面的筆記,有需要的朋友請郵件聯(lián)系:[email protected]
             
                接下來的學(xué)習(xí)過程中,比較難以理解的是ARM的中斷過程和存儲系統(tǒng)。ARM中斷的實(shí)現(xiàn)有些書上看一兩遍也不見得能夠完全理解,當(dāng)然可能只對于像我一樣跨專業(yè)的朋友來說存在這個(gè)問題。這次只談中斷。由于是初學(xué)者,難免會出錯(cuò),敬請各位指正。
             
                當(dāng)一個(gè)程序正常執(zhí)行過程中,CPU可能檢測到有某個(gè)中斷源發(fā)出中斷請求,這時(shí)ARM硬件實(shí)現(xiàn)了程序強(qiáng)制跳轉(zhuǎn),在這之前保存了相關(guān)信息,以便程序正常返回。如果是發(fā)生了Reset中斷,程序?qū)崿F(xiàn)系統(tǒng)初始化設(shè)置。
                開始比較難以理解的是中斷產(chǎn)生后,程序都進(jìn)行了哪些操作。我就從跟蹤PC作為分析的主線。以發(fā)生FIQ中斷為例。(只以ROM起始地址為0為例,不為0的情況參照存儲地址映射)
                最簡單的是中斷發(fā)生后,PC=0x08,在此地址處存放一個(gè)跳轉(zhuǎn)指令,跳轉(zhuǎn)到相關(guān)處理程序。當(dāng)然多數(shù)情況中斷處理程序可能比較復(fù)雜,并且要處理多種中斷的情況下,采用一步映射兩步跳轉(zhuǎn)(我自己起的名字,不一定妥當(dāng))。如下圖所示:
                
            一步映射指,在RAM地址中建立一個(gè)中斷向量表,圖中該表起始地址為0x400000,在該表中存放的是中斷處理函數(shù)的入口地址。兩步跳轉(zhuǎn)是指,當(dāng)中斷發(fā)生時(shí),由于系統(tǒng)硬件強(qiáng)制程序跳轉(zhuǎn)到了0x08處,在該地址處是一個(gè)跳轉(zhuǎn)指令,跳轉(zhuǎn)到中斷函數(shù)地址解析程序IRQ_Handler,完成一步跳轉(zhuǎn)。解析程序(IRQ_Handler)的作用無非是把中斷向量表內(nèi)中斷處理函數(shù)(SystemIrqHandler)的入口地址賦值給 PC,如圖所示PC=0x003000280,完成第二步跳轉(zhuǎn),開始處理中斷。在中斷處理函數(shù)的最后,恢復(fù)中斷開始時(shí)保存的相關(guān)寄存器的值,完成中斷。
             
            下面以一個(gè)實(shí)例來具體說明中斷建立及實(shí)現(xiàn)的過程。
             
            首先通過偽指令建立一個(gè)中斷向量表,用于存放中斷程序的入口地址(如上圖中的中斷向量表,注意,此時(shí)表中還未賦值): 
            ;/* EXCEPTION HANDLER VECTOR TABLE */ 
             
            ^ DRAM_BASE 
            HandleReset # 4 
            HandleUndef # 4 
            HandleSwi # 4 
            HandlePrefetch # 4 
            HandleAbort # 4 
            HandleReserv # 4 
            HandleIrq # 4 
            HandleFiq # 4 
             
             
            然后定義一個(gè)連續(xù)的數(shù)據(jù)段,并把中斷處理函數(shù)的入口地址值賦給各字單元
            ExceptionHandlerTable 
            DCD UserCodeArea 
            DCD SystemUndefinedHandler 
            DCD SystemSwiHandler 
            DCD SystemPrefetchHandler 
            DCD SystemAbortHandler 
            DCD SystemReserv 
            DCD SystemIrqHandler 
            DCD SystemFiqHandler 
             
             
            下面從程序的開始處分析: 
            AREA Init, CODE, READONLY 
            ENTRY 
            /* ROM起始地址向量表 */
            B Reset_Handler 
            B Undefined_Handler 
            B SWI_Handler 
            B Prefetch_Handler 
            B Abort_Handler 
            NOP Reserved vector 
            B IRQ_Handler 
            B FIQ_Handler 
            /* B跳轉(zhuǎn)范圍限于+ -32M內(nèi)*/
             
             
            /* 以下是地址解析程序 */
            IRQ_Handler 
            SUB sp, sp, #4 
            STMFD sp!, {r0} FD滿遞減堆棧 執(zhí)行寄存器壓棧操作. 
            LDR r0, =HandleIrq  //對應(yīng)程序開始處以偽指令定義的向量表
            LDR r0, [r0]  //中斷處理函數(shù)的地址賦給R0. 
            STR r0, [sp, #4]  //中斷處理函數(shù)的地址入棧 
            LDMFD sp!, {r0, pc} //實(shí)現(xiàn)程序跳轉(zhuǎn),目前沒明白為什么又給r0賦值? 
             
             
            上面提到了還沒有給中斷向量表賦值,下面代碼把中斷處理函數(shù)的地址放到DRAM中斷向量表里
            EXCEPTION_VECTOR_TABLE_SETUP 
            LDR r0, =HandleReset 
            LDR r1, =ExceptionHandlerTable 
            MOV r2, #8 
            ExceptLoop 
            LDR r3, [r1], #4 
            STR r3, [r0], #4 
            SUBS r2, r2, #1 Down Count 
            BNE ExceptLoop ;; 
             
             
            下面是中斷處理函數(shù) 
            SystemIrqHandler 
            IMPORT ISR_IrqHandler 
            STMFD sp!, {r0-r7, lr} 
            BL ISR_IrqHandler 
            LDMFD sp!, {r0-r7, lr} 
            SUBS pc, lr, #4 
             
            它實(shí)際上只調(diào)用了下面的C語言的中斷處理函數(shù),其他什么也沒做。 
            void ISR_IrqHandler(void) 

            IntOffSet = (U32)INTOFFSET; 
            (IntOffSet>>2) 
            (*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine 

             
            以上編程思路是,先在系統(tǒng)初始化時(shí)重新建立一個(gè)中斷向量表,并把相關(guān)的中斷處理函數(shù)的地址放到中斷向量表中。當(dāng)系統(tǒng)監(jiān)測到有中斷源請求服務(wù)后,硬件實(shí)現(xiàn)pc跳轉(zhuǎn)到地址0x08處,執(zhí)行一個(gè)跳轉(zhuǎn)指令B IRQ_Handler  , 然后執(zhí)行地址解析程序,把中斷向量表中的中斷處理函數(shù)的入口地址賦給pc,開始響應(yīng)中斷。在中斷處理函數(shù)的最后,執(zhí)行
            LDMFD sp!, {r0-r7, lr} 
            SUBS pc, lr, #4 
            實(shí)現(xiàn)中斷的返回。


            評論


            相關(guān)推薦

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

            關(guān)閉