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

📄 os_cpu_a.s

📁 Embest ATEB40x开发板已经移植的uCOS-II v2.0源代码。
💻 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


	.IFDEF AT91R40008
	.INCLUDE "EB40008.inc"
	.ENDIF

	.IFDEF AT91R40807
	.INCLUDE "EB40807.inc"
	.ENDIF

	.IFDEF AT91M40800
	.INCLUDE "EB40800.inc"
	.ENDIF
	
	.EXTERN OSTCBCur
	.EXTERN OSTCBHighRdy
	.EXTERN OSPrioCur
	.EXTERN OSPrioHighRdy
    .EXTERN OSRunning
    .EXTERN OSIntNesting
    .EXTERN OSTimeTick
    .EXTERN OSIntEnter
    .EXTERN OSIntExit
           
	.GLOBAL OSTickISR
 	.GLOBAL ARMDisableInt
	.GLOBAL ARMEnableInt
	.GLOBAL OSIntCtxSw
	.GLOBAL OS_TASK_SW
	.GLOBAL 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, #0x18             /* 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	        */
	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 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:
#- 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     r12, =AIC_BASE
        str     r12, [r12, #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  */

/* only for Timer using test...*/
#		subs pc,lr,#4
/* only for Timer using test...*/
		
#- 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}

#- 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|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 + -