新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM的異常處理過程分析

        ARM的異常處理過程分析

        作者: 時間:2016-12-01 來源:網絡 收藏
        異常類型
        Mode
        異常向量
        內容
        IRQ異常
        IRQ
        0x00000018
        LDR PC,[PC,#0x18]或者0xE59FF018
        IFQ異常
        IFQ
        0x0000001C
        LDR PC,[PC,#0x18]
        0xE59FF018
        0x00000038
        Address of OS_CPU_ARM_ExceptIrqHndlr()
        0x0000003C
        Address of OS_CPU_ARM_ExceptFiqHndlr()
        有必要的討論一下,為什么在向量中存儲的是指令: LDR PC,[PC,#0x18],我們從上面的地址可以知道,IRQ異常處理函數地址被存儲到了0x00000038中,異常向量與該地址之間的差值是0x20,那么為什么在其中存儲的值只是0x18呢?這還要討論ARM的流水線結構,當前執行的命令相比PC指向的地址差0x08。也就是當前執行的指令的地址是PC-0x08.當PC指向異常向量以后(取值),還需要等待一個時鐘(譯碼)之后才會被執行(真正意義上的執行操作),而這時PC值已經被更新了。指向了Vector+0x8的位置,因此我們可以知道,當執行向量中的代碼時,這時PC=Vector+0x8,而這時相對于固定的0x20-0x08=0x18,這也就是為什么是LDR PC,[PC,#0x18],而不是LDR PC,[PC,#0x20].
        采用上面的例子說明IRQ的向量為0x00000018,而設定好的固定地址用來存儲對應異常處理函數地址的地址是0x00000038,當CPU執行完PC = 0x00000018以后,還需要譯碼、才能被執行,這時候PC值已經更新為PC = 0x00000018 + 0x08;這時候固定地址距離PC的相對位置位0x00000038 – PC = 0x18,而該地址中保存了IRQ中斷的通用處理函數OS_CPU_ARM_ExceptIrqHndlr()的地址,LDR PC,[PC,#0x18]這條指令是指將PC+0x18地址處的內容加載到PC中,實質上也就完成跳轉到異常處理函數的操作。
        這樣處理的好處是因為LDR的加載范圍是一個固定值+-32M,我們不能保證異常處理程序的地址剛好在+-32M左右,采用這種LDR PC, ADDR(固定地址)的形式就能實現大范圍的跳轉操作。
        我們僅僅以FIQ中斷處理的形式進行討論,其他的異常有一定的相似性,只是在返回地址上存在差別。這段代碼主要是完成寄存器的壓棧,返回地址的調整,保存等操作。具體的看下面的分析:
        AREA CODE, CODE, READONLY
        CODE32
        OS_CPU_ARM_ExceptFiqHndlr
        ;修改中斷返回地址,這屬于進入真正處理函數前的返回地址調整,具體的返回地址依據前面保存的R14進行相應的修改。
        SUB LR, LR, #4 ; LR offset to return from this exception: -4.
        ;壓棧操作
        STMFD SP!, {R0-R12, LR} ; Push working registers.
        ;保存鏈接寄存器
        MOV R2, LR ; Save link register.
        ;設置好ID號,這是非常必要的,只有這樣才能辨別屬于那種異常
        MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID
        /*跳轉到通用的異常處理函數,傳遞的參數是異常ID號*/
        BOS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
        OS_CPU_ARM_ExceptHndlr(except_type)是一個通用的異常處理函數,可以對除了IRQ以外的其他異常進行控制操作。在這個通用處理函數中又調用了下面的函數OS_CPU_ARM_ExceptHndlr_BreakExcept()或者OS_CPU_ARM_ExceptHndlr_BreakTask()。這兩個函數中又調用了通用處理函數OS_CPU_ExceptHndlr(),然后OS_CPU_ExceptHndlr()中調用具體的中斷處理操作。
        一般的OS_CPU_ExceptHndlr()處理形式,可以認為是一個模板如下:
        void OS_CPU_ExceptHndlr (INT32U except_type)
        {
        /* Determine behavior according to exception type (except_type) */
        /* If an IRQ or FIQ,具體的可能要使用中斷向量等形式實現*/
        while (there are interrupting devices) {
        /* Clear interrupting device */
        OS_CPU_SR_INT_En(); /* Enable nesting, if desired */
        /* Handle interrupt */
        }
        }
        這是其中的一段關于IRQ中斷的文字復述:
        IRQ中斷的基本的流程圖如下:
        以上的uC/OS-II異常處理就分析完了,這種方式的實現實質上是采用了通用模板的形式,這樣實現出來的形式只需要控制一定的,具體的一些IRQ中斷處理函數(如定時器,GPIO等的中斷),與具體的廠商有很大的關系,有的廠商采用硬件寄存器的方式進行設計,有的采用軟件方式實現,因此具體的中斷。
        后面我再分析我們通常認為的中斷(實質上就是IRQ和IFQ中某一個具體中斷)處理方式
        上一頁 1 2 3 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 嵊州市| 永靖县| 丁青县| 河北省| 南丰县| 武清区| 富川| 萨嘎县| 香格里拉县| 淄博市| 乌拉特前旗| 泗洪县| 二手房| 巫山县| 汤原县| 彝良县| 怀远县| 文安县| 政和县| 岑溪市| 遂平县| 德阳市| 兴安县| 北碚区| 从江县| 黄冈市| 章丘市| 厦门市| 通榆县| 托克托县| 峡江县| 泰来县| 故城县| 荔浦县| 张家港市| 乌苏市| 姚安县| 依兰县| 西乡县| 资源县| 八宿县|