新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 初探WindowsCE異常和中斷服務程序

        初探WindowsCE異常和中斷服務程序

        作者: 時間:2012-10-31 來源:網絡 收藏

        PROLOG_END

        和上面一樣,的入口處都是例行公事的計算返回位置以抵消流水線誤差。再將要用到的寄存器壓入STACK_IRQ。

        ; Test interlocked API status.

        ;INTERLOCKED_START EQU USER_KPAGE 0x380

        ;INTERLOCKED_END EQU USER_KPAGE 0x400

        sub r0, lr, #INTERLOCKED_START

        cmp r0, #INTERLOCKED_END-INTERLOCKED_START

        bllo CheckInterlockedRestart

        上面這部分的內容是關于互鎖的檢測,由于如信號量這些同步手段都必須作為原子操作進行,不允許打斷。所以如果發生在互鎖API的執行過程中,就需要專門的處理了。這些API都是放在INTERLOCKED_START和INTERLOCKED_END之間的,通過LR很容易就檢查出是否是INTERLOCKEDXXX的過程中。這里并不關心互鎖的實現就繞開這部分代碼繼續往下看,當作沒有發生在interlock過程處理。

        ;

        ; CAREFUL! The stack frame is being altered here. It's ok since

        ; the only routine relying on this was the Interlock Check. Note that

        ; we re-push LR onto the stack so that the incoming argument area to

        ; OEMInterruptHandler will be correct.

        ;

        mrs r1, spsr ; (r1) = saved status reg

        stmfd sp!, {r1} ; save SPSR onto the IRQ stack

        mov r0,lr ; parAMEter to OEMInterruptHandler

        msr cpsr_c, #SVC_MODE:OR:0x80 ; switch to supervisor mode w/IRQs disabled

        stmfd sp!, {lr} ; save LR onto the SVC stack

        stmfd sp!, {r0} ; save IRQ LR (in R0) onto the SVC stack (param)

        ;

        ; Now we call the OEM's interrupt handler code. It is up to them to

        ; enable interrupts if they so desire. We can't do it for them since

        ; there's only on interrupt and they haven't yet defined their nesting.

        ;

        CALL OEMInterruptHandler

        ldmfd sp!, {r1} ; dummy pop (parameter)

        ldmfd sp!, {lr} ; restore SVC LR from the SVC stack

        msr cpsr_c, #IRQ_MODE:OR:0x80 ; switch back to IRQ mode w/IRQs disabled

        ; Restore the saved program status register from the stack.

        ;

        ldmfd sp!, {r1} ; restore IRQ SPSR from the IRQ stack

        msr spsr, r1 ; (r1) = saved status reg

        ldr lr, =KData ; (lr) = ptr to KDataStruct

        cmp r0, #SYSINTR_RESCHED ;->時間片已到,進行調度

        beq

        %B20

        ; interrupted, reschedule again

        msr  spsr, r2

        ldr  lr, [r0, #TcxPc-TcxR3]

        ldmdb  r0,

        movs  pc,

        lr

        ; return to user or system mode

        HandleException是實際進行處理的函數,針對上面沒有處理完的進一步分析并進行處理。這個函數是沒有公開代碼的,所以沒有辦法進一步深入下去。由于處理的類型比較多所以這個異常處理函數的代碼量是相當大的,因此會耗費相對比較多的時鐘周期,在之前的代碼中我們都是在關閉的情況下進行異常處理,如果在這里還不打開中斷的話整個異常處理過程會相當的長,這樣會很大程度上影響系統的實時性,所以在這里調用HandleException之前是將中斷重新打開的,待到處理完成再將中斷關閉。對于這些異常,如果不能處理就只有兩種情況:1.結束該進程/線程。2.掛起系統。第二種情況下掛起系統HandleException是不會返回的。因此,只有異常處理正常流程和結束線程的可能。對于返回的情況,這個時候如果返回觸發異常的地址繼續運行的話,仍然會導致異常,所以結束進程/線程都需要重新調度才能完成了。對于異常處理成功的情形,就不必調度了,直接就可以返回產生異常的地方繼續執行。在這里還要考慮套嵌(這里僅僅是指系統模式和兼管模式的異常套嵌)的情形,也就是中斷/異常已經進入調度狀態又再次產生中斷/異常,這個時候就強行取消上一次調度,進而重新調度。這用于調度過程中遇到異常恢復和剝奪的情況,如果不屬于這種情況的話就直接恢復寄存器狀態并且返回中斷點繼續執行。

        ; Return to a non-preemptible privileged mode.

        ;

        ;   (r0) = ptr to THREAD structure

        ;   (r2) = target mode

        30  msr  cpsr,

        r2

        ; switch to target mode

        add  r0, r0, #TcxR0

        ldmia  r0,

        ; reload all registers return

        通過HandleException處理以后,已經完成了所有異常的處理,所以這里只是考慮反回的情況,由于這里不包含用戶模式下的處理,所以這里處理的都是特權模式,完全可以訪問kdata區域,這里就直接利用Kdata區域中的線程備份來完成恢復寄存器和返回。


        上一頁 1 2 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 泰兴市| 蓬安县| 汪清县| 民勤县| 大埔区| 博客| 盐津县| 库车县| 徐闻县| 沈丘县| 农安县| 红河县| 肇源县| 攀枝花市| 炉霍县| 金湖县| 巴楚县| 衢州市| 合川市| 康平县| 洞头县| 渝中区| 武乡县| 钦州市| 天水市| 西吉县| 宣化县| 阜新| 奎屯市| 沿河| 临洮县| 泸定县| 彭州市| 禹城市| 桐乡市| 永登县| 江津市| 阳城县| 萨迦县| 杨浦区| 崇信县|