<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > UCOS-II中OS_CPU_IRQ_ISR移植過(guò)程分析

          UCOS-II中OS_CPU_IRQ_ISR移植過(guò)程分析

          作者: 時(shí)間:2016-12-01 來(lái)源:網(wǎng)絡(luò) 收藏
          在uc/os-II的移植過(guò)程中存在一個(gè)通用的irq中斷處理函數(shù),其中的實(shí)現(xiàn)過(guò)程如下:

          本文引用地址:http://www.ex-cimer.com/article/201612/324516.htm

          OS_CPU_IRQ_ISR
          STMFD SP!, {R1-R3} ; We will use R1-R3 as temporary registers
          MOV R1, SP
          ADD SP, SP, #12 ;Adjust IRQ stack pointer
          SUB R2, LR, #4 ;Adjust PC for return address to task
          MRS R3, SPSR ; Copy SPSR (Task CPSR)
          MSR CPSR_cxsf, #SVCMODE|NOINT ;Change to SVC mode
          ; SAVE TASKS CONTEXT ONTO OLD TASKS STACK
          STMFD SP!, {R2} ; Push tasks PC
          STMFD SP!, {R4-R12, LR} ; Push tasks LR,R12-R4
          LDMFD R1!, {R4-R6} ; Load Tasks R1-R3 from IRQ stack
          STMFD SP!, {R4-R6} ; Push Tasks R1-R3 to SVC stack
          STMFD SP!, {R0} ; Push Tasks R0 to SVC stack
          STMFD SP!, {R3} ; Push tasks CPSR
          LDR R0,=OSIntNesting ;OSIntNesting++
          LDRB R1,[R0]
          ADD R1,R1,#1
          STRB R1,[R0]
          CMP R1,#1 ;if(OSIntNesting==1){
          BNE %F1
          LDR R4,=OSTCBCur ;OSTCBHighRdy->OSTCBStkPtr=SP;
          LDR R5,[R4]
          STR SP,[R5] ;}
          1 MSR CPSR_c,#IRQMODE|NOINT ;Change to IRQ mode to use IRQ stack to handle interrupt
          LDR R0, =INTOFFSET
          LDR R0, [R0]
          LDR R1, IRQIsrVect
          MOV LR, PC ; Save LR befor jump to the C function we need return back
          LDR PC, [R1, R0, LSL #2] ; Call OS_CPU_IRQ_ISR_handler();
          MSR CPSR_c,#SVCMODE|NOINT ;Change to SVC mode
          BL OSIntExit ;Call OSIntExit
          LDMFD SP!,{R4} ;POP the tasks CPSR
          MSR SPSR_cxsf,R4
          LDMFD SP!,{R0-R12,LR,PC}^ ;POP new Tasks context
          IRQIsrVect DCD HandleEINT0

          這個(gè)函數(shù)是irq中斷的通用處理形式,我對(duì)其中的代碼做一下簡(jiǎn)要的分析和討論。
          首先我需要簡(jiǎn)要的分析一下中斷處理過(guò)程中我們應(yīng)該完成的任務(wù),首先cpu會(huì)自動(dòng)完成一些操作,其中包括中斷的關(guān)閉已經(jīng)返回地址的保存,還有模式的切換等。我們程序員則需要完成一些寄存器的保存工作以及跳轉(zhuǎn)到具體的處理函數(shù)中,最后完成返回控制。
          需要注意的是,本文中的UC/OS-II任務(wù)都運(yùn)行在SVC模式下,而不是SYS模式下。任務(wù)棧中保存的寄存器也是這種模式下對(duì)應(yīng)的值。
          我按照注釋號(hào)對(duì)代碼進(jìn)行解釋:
          2、STMFD SP!, {R1-R3}; 主要是完成幾個(gè)寄存器的壓棧操作,為什么這么做呢?因?yàn)槲覀兘酉聛?lái)將要使用這寫寄存器。為什么需要呢?這是因?yàn)楫?dāng)前CPU工作的irq模式下,因此這里的SP并不是SVC模式下的SP指針,但是在UC/OS-II的移植過(guò)程中通常將各個(gè)任務(wù)工作在SVC模式下,同時(shí)還需要對(duì)寄存器的保存,在中斷發(fā)生以后,需要保存所有的寄存器以及CPSR的值,而當(dāng)前的SP并不是任務(wù)的棧,此時(shí)除了SP、R14的值發(fā)生了變化以外,其他的寄存器并沒(méi)有發(fā)生變化。但是由于后面需要使用這些寄存器,因此需要壓棧。
          3、MOV R1, SP; 將R14_irq的值保存到R1中,這個(gè)SP的保存主要是為了通過(guò)這個(gè)值訪問(wèn)IRQ模式下的堆??臻g,實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問(wèn)。
          4、ADD SP, SP, #12; 調(diào)整IRQ模式下的堆棧指針SP_irq,將這個(gè)指針指向IRQ堆棧的開(kāi)始位置,方便下一次中斷的處理操作。
          5、SUB R2, LR, #4 ;這個(gè)操作主要是調(diào)整返回地址,了解異常返回地址的理解其中的含義,這時(shí)候的返回地址實(shí)質(zhì)上就是任務(wù)的返回地址,也就是將來(lái)需要加載到PC中的值。
          6、MRS R3, SPSR;因?yàn)榘l(fā)生了IRQ中斷,此時(shí)CPU進(jìn)入IRQ模式中,這時(shí)的SPSR_irq中保存了svc模式下的CPSR狀態(tài)。而任務(wù)堆棧中保存的剛好是SVC模式下的狀態(tài)寄存器,因此需要將SVC模式下的狀態(tài)寄存器首先讀出來(lái),然后保存進(jìn)任務(wù)的堆棧中,因此用R3來(lái)保存CPSR值。
          7、MSR CPSR_cxsf, #SVCMODE|NOINT; 因?yàn)槿蝿?wù)的堆棧空間位于SVC模式下,因此首先需要將CPU的狀態(tài)切換到SVC模式下,然后進(jìn)行任務(wù)情景的切換操作。

          9、STMFD SP!, {R2}; 這時(shí)候的SP是指在SVC模式下的R13_svc。中斷發(fā)生以后,SVC模式下的SP并沒(méi)有發(fā)生改變,返回以后,該值仍然存在,仍然指向任務(wù)的棧頂位置。根據(jù)任務(wù)??臻g的分布,首先需要保存PC值,然后是R14-R0,CPSR的值,最后是保存SP到任務(wù)中,這種分布狀態(tài)是和堆棧初始化過(guò)程的分布一致的。而通過(guò)調(diào)整的返回地址剛好就保存在了R2中,因此需要壓棧保存PC值。
          10、STMFD SP!, {R4-R12, LR};因?yàn)樵谥暗囊幌盗胁僮髦?,并沒(méi)有對(duì)R4-R12,R14的值進(jìn)行破壞,因此可以直接進(jìn)行壓棧操作,實(shí)現(xiàn)任務(wù)堆棧中R4-R12,LR的保存操作。

          接下來(lái)的幾句代碼是重點(diǎn):實(shí)現(xiàn)了在對(duì)其他模式下堆??臻g的訪問(wèn)問(wèn)題。
          11、LDMFD R1!, {R4-R6};是指將R1地址處加載一些數(shù)據(jù)到R4-R6,這三個(gè)寄存器的值已經(jīng)被壓入棧中,對(duì)他們的修改并不會(huì)導(dǎo)致錯(cuò)誤的產(chǎn)生,因此這三個(gè)寄存器實(shí)質(zhì)上是作為中間地址。其中加載的順序滿足高地址對(duì)應(yīng)高的高編號(hào)的寄存器值。R1我在前面就強(qiáng)調(diào)了用來(lái)訪問(wèn)IRQ模式堆棧空間的參考地址。從這個(gè)地址向上分別保存了壓入棧中的R1-R3寄存器的值,也就是被中斷任務(wù)R1-R3的值。
          12、STMFD SP!, {R4-R6};也就是完成了對(duì)任務(wù)寄存器R1-R3的壓棧操作。
          13、STMFD SP!, {R0} ;前面的代碼中并沒(méi)有修改R0的值,因此其中的值仍然是任務(wù)的R0值,因此也需要壓棧操作。通過(guò)上面的幾句代碼就完成了任務(wù)的R0-R15所有寄存器的保存操作。接下的就應(yīng)該完成CPSR的保存。
          14、STMFD SP!, {R3};當(dāng)前的R3中保存了實(shí)際上是前面所說(shuō)的SPCR_irq中的值,也就是SVC模式下的狀態(tài)寄存器的值,因此可以認(rèn)為就是完成了任務(wù)的狀態(tài)寄存器的保存。


          上一頁(yè) 1 2 下一頁(yè)

          評(píng)論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();