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

📄 os_cpu_a.s

📁 ucos在atmel cpu上的移植案例
💻 S
字号:
;------------------------------------------------------------------------------
;-         ATMEL Microcontroller Software Support  -  ROUSSET  -
;------------------------------------------------------------------------------
; The software is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;-----------------------------------------------------------------------------
;- File source          : os_cpu.s
;- Object               : AT91 Ucos specific assembly functions
;-
;- 1.0 21/08/00 EL      : creation
;------------------------------------------------------------------------------


	AREA  |subr|, CODE, READONLY, INTERWORK


	INCLUDE targets/eb01/eb01.inc
	
	IMPORT OSTCBCur
	IMPORT OSTCBHighRdy
	IMPORT OSPrioCur
	IMPORT OSPrioHighRdy
        IMPORT OSRunning
        IMPORT OSIntNesting
        IMPORT OSTimeTick
        IMPORT OSIntEnter
        IMPORT OSIntExit
           
	EXPORT OSTickISR
 	EXPORT ARMDisableInt
	EXPORT ARMEnableInt
	EXPORT OSIntCtxSw
	EXPORT OS_TASK_SW
	EXPORT OSStartHighRdy


;--------------------------------------------------------------------------------------
ARMDisableInt             	    
	mrs     r12, CPSR           ;get current CPU mode
  	orr     r12, r12, #I_BIT    ;set the interrupt disable mode bit
  	msr     CPSR_c, r12         
  	bx	lr                  
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
ARMEnableInt
  	mrs 	r12, CPSR             ;move current processor status into reg 12
  	bic 	r12, r12, #I_BIT      ;clear the interrupt disable bit
  	msr 	CPSR_c, r12           
  	bx	lr                    
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OSIntCtxSw

; Interrupt Exit if higher priority task ready to run
; New Task Context switch 

	add	sp,sp, #4               ; adjust sp to compensate for the call to OSIntExit       
	msr     CPSR_c, #0x92           ; switch to IRQ mode and disable IRQ's                                      ; the following 2 lines keep the stack
                                      
  	ldmfd   sp!, {r12, r14}         ; restore the stack 
	ldmfd   sp!, {r12}   

	ldr     r12, =AIC_BASE
        str	r12, [r12, #AIC_EOICR]  ; write any value to EOICR to signal end of int
   	msr     CPSR_c, #ARM_MODE_SYS   ; switch back to system mode with IRQ and FIQ enabled
       
	b  	OSCtxSw                 ; perform the context switch
                                      
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OS_TASK_SW
; Call from OSSched()
; New Task Context switch  
  	stmfd 	sp!, {r0-r12, r14}	; store current context
	b  	OSCtxSw                 ; perform the context switch                                   
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OSCtxSw                  	        
  	mrs 	r4, CPSR                ; load current psr to r4
  	stmfd 	sp!, {r4}               ; save current PSR to stack
  	mrs 	r4, SPSR                ; load saved psr to r4
  	stmfd 	sp!, {r4}               ; saved saved psr to stack

  ;OSPrioCur = OSPrioHighRdy
  	ldr 	r4, =OSPrioCur          ; load the current priority pointer
  	ldr 	r5, =OSPrioHighRdy      ; load address of highest prio task
  	ldrb  	r6, [r5]                ; load value of highest prio task
  	strb  	r6, [r4]                ; store value of highest in current

  ; Get current task TCB address
  	ldr 	r4, =OSTCBCur           ; load pointer
  	ldr 	r5, [r4]                ; load current tcb sp
  	str 	sp, [r5]                ; store sp in preempted tasks's TCB

  ; Get highest priority task TCB address
  	ldr	r6, =OSTCBHighRdy
  	ldr 	r6, [r6]                ; get highrdy's sp
  	ldr 	sp, [r6]                ; set sp = highrdy[sp]

  ; OSTCBCur = OSTCBHighRdy
 	str 	r6, [r4]                ; set new current task TCB address
  	ldmfd 	sp!, {r4}               ; load saved SPSR from stack
  	msr 	SPSR_c, r4                ; spsr = saved spsr
  	ldmfd 	sp!, {r4}               ; load saved cpsr from stack
  	msr 	CPSR_c, r4                ; cpsr = saved cpsr
  	ldmfd 	sp!, {r0-r12, r14}      ; restore r0-r12 and lr interworking
  	bx  	r14                     ; interworking branch on lr
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OSStartHighRdy
        ; Set OSRunning == TRUE
  	ldr 	r4, =OSRunning          ;point r4 to OSRunning  	
	mov 	r5, #1                  ;move 1 into r5	
	str 	r5, [r4]                ;store r5 in [r4]

        ; Get current task TCB address
  	ldr 	r4, =OSTCBCur           ;point to current tcb  

        ; Get highest priority task TCB address
  	ldr 	r5, =OSTCBHighRdy       ;point to highest tcb  	
	ldr 	r5, [r5]                ; get stack pointer  	
	ldr 	sp, [r5]                ; sp = highrdy[sp]  	
	str 	r5, [r4]                ; set current tcb = highrdy tcb

	ldmfd 	sp!, {r4}               ; get spsr  	
	ldmfd 	sp!, {r4}               ; get cpsr new state from top of the stack  	
	msr 	CPSR_c, r4              ; set cpsr = saved CPSR   	
	ldmfd 	sp!, {r0-r12, r14}      ; restore registers r0-r12 and lr	
	bx	r14                     ; branch on new task
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OSTickISR
;- Adjust and save LR_irq in IRQ stack
        sub     r14, r14, #4
        stmfd   sp!, {r14}

;- Save SPSR and r0 in IRQ stack
        mrs     r14, SPSR
        stmfd   sp!, {r12, r14}

;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
        ldr     r14, =AIC_BASE
        str     r14, [r14, #AIC_IVR]
    
;read the interrupt status reg to clear it
        ldr     r12,=TC0_BASE       	; load tc0  base address
        ldr     r12,[r12, #0x020]   	; read from status register offse

;- Enable Interrupt and Switch in SYS Mode
        mrs     r12, CPSR
        bic     r12, r12, #I_BIT
        orr     r12, r12, #ARM_MODE_SYS
        msr     CPSR_c, r12              

;- Save scratch/used registers and LR in SYS Stack
        stmfd   sp!, { r0-r12,r14}
	            	
        ldr     r12, =OSIntEnter         
        mov     r14,pc                   
        bx      r12			 ; Branch to OsIntEnter 
        ldr     r12, =OSTimeTick         
        mov     r14,pc                   
        bx      r12                      ; Branch to OsTimeTick           
        ldr     r12, =OSIntExit          
        mov     r14,pc                   
        bx      r12                      ; Branch to OSIntExit 
 
; Interrupt Exit if no higher priority task ready to run
         
; restore interrupted task  
;- Restore scratch/used registers and LR from System Stack
        ldmfd   sp!, { r0-r12, r14}
                    
;- Disable Interrupt and switch back in IRQ mode
        mrs	r12, CPSR
        bic     r12, r12, #ARM_MODE_SYS
        orr     r12, r12, #I_BIT:OR:ARM_MODE_IRQ
        msr     CPSR_c, r12
        
;- Mark the End of Interrupt on the AIC
        ldr     r12, =AIC_BASE
        str	r12, [r12, #AIC_EOICR]
;- Restore SPSR_irq and r0 from IRQ stack
        ldmfd   sp!, {r12, r14}
        msr     SPSR_c, r14
;- Restore adjusted  LR_irq from IRQ stack directly in the PC
        ldmfd   sp!, {pc}^
        END
;--------------------------------------------------------------------------------------


END

⌨️ 快捷键说明

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