在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于44b0的中斷調(diào)用的問題

            關(guān)于44b0的中斷調(diào)用的問題

            作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
            關(guān)于44b0的中斷調(diào)用的問題:

            我在網(wǎng)上下了一個(gè)源碼,在閱讀的過程中,我的理解來說。希望各位指教下,具體是這樣的:

            本文引用地址:http://www.biyoush.com/article/201611/317184.htm

            下面的代碼因?yàn)?4b0中的各個(gè)中斷類型相似的,所以只是以timer為例。

            在init.s中有這樣的代碼:
            首先是一個(gè)宏的定義:
            MACRO
            $HandlerLabel HANDLER $HandleLabel

            $HandlerLabel
            sub sp,sp,#4 ;decrement sp(to store jump address)
            stmfd sp!,{r0} ;PUSH the work register to stack(lr doest push because it return

            to original address)
            ldr r0,=$HandleLabel;load the address of HandleXXX to r0
            ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
            str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
            ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
            MEND
            然后有一個(gè)vector_branch
            ......
            entry
            ......
            VECTOR_BRANCH
            ......
            ldr pc,=HandlerTIMER1
            ......
            IRQ_Handler
            IMPORTISR_IrqHandler
            STMFDsp!, {r0-r12, lr}
            BLISR_IrqHandler
            LDMFDsp!, {r0-r12, lr}
            SUBSpc, lr, #4

            EXPORT IRQ_Handler
            ......
            HandlerTIMER1HANDLER HandleTIMER1
            ......
            ;Setup IRQ handler
            ldr r0,=HandleIRQ;This routine is needed
            ldr r1,=IRQ_Handler;=IsrIRQ,if there isnt subs pc,lr,#4 at 0x18,

            0x1c
            str r1,[r0]

            然后,在另外的文件isr_address.s中有下面的語句:

            AREA ISR_STARTADDRESS, DATA, NOINIT
            ......
            EXPORTHandleTIMER1
            ......
            HandleTIMER1SPACE4
            ......
            END

            另外,在scat_ram.scf中對(duì)存儲(chǔ)空間的分配有:
            RAM_LOAD 0x00008000
            {
            RAM_EXEC 0x00008000
            {
            init.o (init, +First)
            * (+RO)
            }

            RAM 0x0x00100000
            {
            * (+RW,+ZI)
            }

            HEAP +0 UNINIT
            {
            heap.o (+ZI)
            }

            STACKS 0x0020000 UNINIT
            {
            stack.o (+ZI)
            }

            ISR_STARTADDRESS 0x0020000
            {
            isr_address.o (+ZI)
            }

            }
            在uHALr_InterruptRequestInit()中,有定義下面的東西
            void uHALr_InterruptRequestInit()
            {
            pISR_UNDEF= (unsigned) DebugUNDEF;
            pISR_SWI= (unsigned) DebugSWI;
            ......
            SetISR_Interrupt(INT_TIMER1_OFFSET,OSTimeTick,NULL);
            ......
            pISR_ADC= (unsigned) BreakPoint;
            pISR_RTC= (unsigned) BreakPoint;
            }
            然后,在文件isr.c和isr.h中定義下面的函數(shù)和數(shù)據(jù)結(jié)構(gòu)。
            void (*InterruptHandlers[MAXHNDLRS])(void)={NULL,};
            有函數(shù)
            void SetISR_Interrupt(int vector, void (*handler)(), int Exint)
            {
            ......
            InterruptHandlers[vector] = handler;
            ......
            }

            在說的理解之前,要謹(jǐn)記44b0提供了兩種向量和非向量的中斷mode。
            下面是我的理解:
            (1)在向量中斷時(shí)采取的操作
            從scat_ram.scf和isr_address.s中,可以得到從0x0020000處開始的位置,為每一個(gè)中斷留出了4個(gè)字節(jié)

            的空間,其中包括timer1.這些空間應(yīng)該是用來存儲(chǔ)isr的地址(指針)的。

            繼續(xù),從scat_ram.scf也可以得到,從0x00008000開始存放init.s的數(shù)據(jù)。
            將HandlerTIMER1HANDLER HandleTIMER1的宏展開,得到

            HandlerTIMER1
            sub sp,sp,#4
            stmfd sp!,{r0}
            ldr r0,=HandleTIMER1
            ldr r0,[r0]
            str r0,[sp,#4]
            ldmfd sp!,{r0,pc}
            這里結(jié)合VECTOR_BRACH中的代碼
            ldr pc,=HandlerTIMER1
            來看,假設(shè)現(xiàn)在timer1中斷到來,那么執(zhí)行該ldr命令,pc值指向sub處開始執(zhí)行。ldr

            r0,=HandleTIMER1會(huì)將isr_address.s中export的HandleTIMER1加載到r0中,這里的r0中所放的實(shí)際上也

            是一個(gè)地址,指向相應(yīng)isr指針的指針,執(zhí)行l(wèi)drr0,[r0]后,r0中才是指向isr的指針(地址),通過

            堆棧的巧妙操作,pc指向了isr,開始執(zhí)行相應(yīng)的isr。這個(gè)isr怎樣是怎樣和相應(yīng)的Handle對(duì)應(yīng)的呢?在

            函數(shù)uHALr_InterruptRequestInit()中,有pISR_UNDEF= (unsigned) DebugUNDEF等,這些的意思是在

            pISR_UNDEF所代表的地址處放置指向DebugUNDEF的指針(地址)。
            (2)非向量中斷下的操作

            回到init.s中,有語句
            ;Setup IRQ handler
            ldr r0,=HandleIRQ;This routine is needed
            ldr r1,=IRQ_Handler;=IsrIRQ,if there isnt subs pc,lr,#4 at 0x18,

            0x1c
            str r1,[r0]
            這里要注意了,HandleIRQ也是isr_address.s中的那個(gè),只是這里將IRQ_Handler的地址放到HandleIRQ預(yù)

            留的空間中。
            同樣,如果在這種mode下,有一個(gè)irq中斷到來,那么首先系統(tǒng)也會(huì)像(1)那樣找到HandleIRQ,但是現(xiàn)在

            那里放置的是IRQ_Handle的地址,所以轉(zhuǎn)向IRQ_Handle,繼而轉(zhuǎn)向ISR_IrqHandler。在ISR_IrqHandler中

            ,利用I_ISPC寄存器找到中斷源,然后調(diào)用相應(yīng)源的處理函數(shù)。
            借用linux的概念,這個(gè)執(zhí)行的isr應(yīng)該在系統(tǒng)初始化的時(shí)候被注冊(cè)。這個(gè)任務(wù)應(yīng)該是由函數(shù)
            SetISR_Interrupt完成的,在SetISR_Interrupt中,調(diào)用了(*InterruptHandlers[MAXHNDLRS])(void),

            有InterruptHandlers[vector] = handler;這個(gè)vector明顯是44b0定義的若干irq中斷的相對(duì)偏移。



            關(guān)鍵詞: 44b0的中斷調(diào)

            評(píng)論


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

            關(guān)閉