⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intasm.s

📁 包括EPA协议栈
💻 S
字号:
          INCLUDE AT91RM9200.inc

;-------------------------------------------------------------------------------
;- IRQ Handler Macro Definition                                                -
;-----------------------------                                                 -
;- Just disable FIQ and Saves context. Not support interrupt nesting.          -
;-------------------------------------------------------------------------------
          Macro
          IRQ_HDLR $c_handler, $s_handler
          
          IMPORT $c_handler
          EXPORT $s_handler
          
$s_handler

;-------------------------------------------------------------------------------
;-                            Enter Interrupt
;-
;- Save context in current (IRQ / FIQ) stack, According to ATPCS, only r0 - r3
;- and lr should be saved, others will be saved by compiler in C codes 
;- when needed.
;-------------------------------------------------------------------------------
          stmfd     sp!, {r0 - r3, lr};

;-------------------------------------------------------------------------------
;-                            Exit Interrupt
;- Diable IRQ and FIQ
;-------------------------------------------------------------------------------
          mrs       r0, CPSR
          orr       r0, I_BIT:OR:F_BIT
          msr       CPSR_c, r0

;-------------------------------------------------------------------------------
;-                            Hadle Interrupt
;- Jump to c intterupt handler
;-------------------------------------------------------------------------------
          ldr       r0, =$c_handler
          mov       lr, pc
          bx        r0

;-------------------------------------------------------------------------------
;- Mark the end of intterupt on AIC
;-------------------------------------------------------------------------------
          ldr       r0, =AT91C_BASE_AIC
          str       r0, [r0, #AIC_EOICR]

;-------------------------------------------------------------------------------
;- Restore context from stack
;-------------------------------------------------------------------------------
          ldmfd     sp!, {r0 - r3, pc}^

          MEND




          IMPORT OSIntNesting
          IMPORT OSTCBCur
          IMPORT OSIntExit


;-------------------------------------------------------------------------------
;- OS FRQ Handler Macro Definition                                             -
;-----------------------------                                                 -
;- Notify OS of entering fast interrupt, Support interrupt nestint.            -
;-------------------------------------------------------------------------------
          MACRO
          OS_IRQ_HDLR $c_handler, $s_handler
	
          IMPORT $c_handler
          EXPORT $s_handler

$s_handler          ROUT

          MEND





	
;-------------------------------------------------------------------------------
;- OS IRQ Handler Macro Definition                                             -
;-----------------------------                                                 -
;- Notify OS of entering interrupt, Support interrupt nestint.                 -
;-------------------------------------------------------------------------------
  
          MACRO
          OS_IRQ_HDLR $c_handler, $s_handler
	
          IMPORT $c_handler
          EXPORT $s_handler

$s_handler          ROUT

;-------------------------------------------------------------------------------
;-                            Enter Interrupt
;-
;- Save context
;- Task-s stack orgernized like below, that is a full decrease stack.
;- All task runs in SVC mode, task stack pointer is put in SP_svc
;-   SP --> LR_irq (PC for return)
;-          LR
;-          R12
;-          R11
;-          R10
;-          R9
;-          R8
;-          R7
;-          R6
;-          R5
;-          R4
;-          R3
;-          R2
;-          R1
;-          R0
;-          SPSR_irq (CPSR_svc)-
;-------------------------------------------------------------------------------
          stmfd     sp, {r0-r3}                                 ;- Store r0-r3 in irq stack temporiarily
          sub       r0, lr, #0x04                                ;- copy task-s PC(lr_irq)-
          mrs       r1, SPSR                                     ;- copy task-s CPSR(SPSR_irq)-
          sub       r2, sp, #0x10                                ;- copy IRQ mode stack pointer
          msr       CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT      ;- Switch back to SVC mode with IRQ and FIQ disabled
                                                            ;- Store task context in task stack
          stmfd     sp!, {r0}                                    ;-   Store task-s PC(lr_irq) in task-s stack
          stmfd     sp!, {r4-r12, lr}                            ;-   Store task-s register r4-r12, lr

          ldmfd     r2!, {r4-r7}                                 ;-   Move task-s register r0-r3 to task
          stmfd     sp!, {r4-r7}                                 ;-     stack from IRQ stack-

          stmfd     sp!, {r1}                                    ;-  Store task-s CPSR(SPSR_irq) in task stack
  
;-------------------------------------------------------------------------------
;- OSIntNesting++
;- These codes are relative with OS
;-------------------------------------------------------------------------------
          ldr       r0, =OSIntNesting
          ldrb      r1, [r0]
          add       r1, r1, #1
          strb      r1, [r0]
  
;-------------------------------------------------------------------------------
;- If OSIntNesting == 1, OSTCBCur->OSTCBStkPtr = SP
;- These codes are relative with OS
;-------------------------------------------------------------------------------
          cmp       r1, #1
          bne       %55
  
          ldr       r4, =OSTCBCur
          ldr       r5, [r4]
          str       sp, [r5]  
  
;-------------------------------------------------------------------------------
;- Enable IRQ and FIQ
;-------------------------------------------------------------------------------
55
          msr       CPSR_c, #ARM_MODE_SVC
  
;-------------------------------------------------------------------------------
;-                            Hadle Interrupt
;- Jump to c intterupt handler
;-------------------------------------------------------------------------------
          ldr       r0, =$c_handler
          mov       lr, pc
          bx        r0

;-------------------------------------------------------------------------------
;-                            Exit Interrupt
;- Switch back to SVC mode, at the same time diable IRQ and FIQ
;-------------------------------------------------------------------------------
          msr       CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT
  
;-------------------------------------------------------------------------------
;- Mark the end of intterupt on AIC
;-------------------------------------------------------------------------------
          ldr       r0, =AT91C_BASE_AIC
          str       r0, [r0, #AIC_EOICR]

;-------------------------------------------------------------------------------
;- OSIntExit()
;- Call this function will cause task switch if neccessery
;- These codes are relative with OS
;------------------------------------------------------------------------------
          ldr       r0, =OSIntExit
          mov       lr, pc
          bx        r0  
  
;-------------------------------------------------------------------------------
;- Restore context from stack
;-------------------------------------------------------------------------------
          ldmfd     sp!, {r0}
          msr       SPSR_cxsf, r0
          ldmfd     sp!, {r0-r12, lr, pc}^

          MEND

;-------------------------------------------------------------------------------
;- Interrupt definitions
;- 
;-------------------------------------------------------------------------------
          AREA      IntAsmHandlers, CODE, READONLY
  
          CODE32
  
          OS_IRQ_HDLR EtherInt, EtherIntHandler
  
          OS_IRQ_HDLR PTimerInt, PTimerIntHandler
  
          OS_IRQ_HDLR TC1Int, TC1IntHandler

          OS_IRQ_HDLR TC2Int, TC2IntHandler
          
          OS_IRQ_HDLR SttInt, SttIntHandler

          OS_IRQ_HDLR SpuriousInt, SpuriousHandler

          END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -