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

📄 os_cpu_a.s

📁 Atmel AT91FR40162上的uCOS移植,该处理器内核为ARM7 TDMI
💻 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/eb40/eb40.inc
	INCLUDE macros.inc
	
	IMPORT OSTCBCur
	IMPORT OSTCBHighRdy
	IMPORT OSPrioCur
	IMPORT OSPrioHighRdy
    IMPORT OSRunning
    IMPORT OSIntNesting
    IMPORT OSTimeTick
    IMPORT OSIntEnter
    IMPORT OSIntExit
;	IMPORT TmrMaintain
	IMPORT ARMIntNesting

           
	EXPORT OSTickISR
	EXPORT OSIntCtxSw
	EXPORT __OS_TASK_SW
	EXPORT __OSStartHighRdy

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

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

	add	    sp,sp, #8;                      ; adjust sp to compensate for the call to OSIntExit
;	ldr     r12, =AIC_BASE
;    str		r12, [r12, #AIC_EOICR]  ; write any value to EOICR to signal end of int
	;---------------------------------------------------------
	;If current interrupt entered from another low priority interrupt, no switch
	;mrs		r1,SPSR
	;and		r11,r1,#0x1F			; mask out all but the mode bits
	;teq		r11,#ARM_MODE_IRQ		; check for interrupted IRQ thread
	; if EQ then we can return immediately
	;bne		OSIntCtxSw_1
	;msreq	SPSR_cxsf,r1			; restore the SPSR
	;addeq	sp,sp,#4
	;ldmeqfd	sp!,{r0-r12,r14,pc}^		; and return to the interrupted thread

OSIntCtxSw_1                  	        
  ;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

	ldr     r12, =AIC_BASE
    str		r12, [r12, #AIC_EOICR]  ; write any value to EOICR to signal end of int
	;
  	ldmfd 	sp!, {r4}               ; load saved cpsr from stack
  	msr 	CPSR_cxsf, r4                ; cpsr = saved cpsr
  	ldmfd 	sp!, {r0-r12, r14,pc}      ; restore r0-r12 and lr interworking
                                      
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
__OS_TASK_SW
; Call from SWI interrupt 
; New Task Context switch  
	msr		CPSR_c,#I_BIT :OR: ARM_MODE_SYS	 ;enter SYS mode and save registers
  	stmfd 	sp!, {r0-r12,r14,pc}	
	msr		CPSR_c,#I_BIT :OR: ARM_MODE_SVC	 ;return to SVC mode to get SPSR and R14
	mov		r12, r14
  	mrs 	r4, SPSR	           
	msr		CPSR_c,#I_BIT :OR: ARM_MODE_SYS  ;go back to SYS mode
	add		sp,sp,#15*4
	stmfd	sp!, {r12}          		     ;save r12(actually, r14 and pc when return)
	sub		sp,sp,#14*4
  	stmfd 	sp!, {r4}                        ;save SPSR to stack

;--------------------------------------------------------------------------------------
OSCtxSw                  	        
  ;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 cpsr from stack
  	msr 	CPSR_cxsf, r4                ; cpsr = saved cpsr
  	ldmfd 	sp!, {r0-r12, r14,pc}      ; restore r0-r12 and lr interworking

;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
;This function is called from SWI and after reaching here, the mode has been SYSTEM
__OSStartHighRdy
        ; Set OSRunning == TRUE
  	ldr 	r4, =OSRunning          ;point r4 to OSRunning  	
	mov 	r5, #1                  ;move 1 into r5	
	strb 	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 cpsr new state from top of the stack  	
	msr 	CPSR_cxsf, r4              ; set cpsr = saved CPSR   	
	ldmfd 	sp!, {r0-r12, r14,pc}      ; restore registers r0-r12 and lr	
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
OSTickISR

		ENTER_INTERRUPT

;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
		;
        ldr     r12, =OSTimeTick         
        mov     r14,pc                   
        bx      r12                      ; Branch to OsTimeTick           
      ;  ldr     r12, =TmrMaintain         
        ;mov     r14,pc                   
        ;bx      r12                      ; Branch to OsTimeTick           
 
; Interrupt Exit if no higher priority task ready to run
         
; restore interrupted task  
		EXIT_INTERRUPT
;--------------------------------------------------------------------------------------
		END

END

⌨️ 快捷键说明

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