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

📄 os_cpu_a.s

📁 一个可以在实验室的实验箱运行的UC/OS—II系统
💻 S
字号:
;#********************************************************************************************************
;#                                               uC/OS-II
;#                                         The Real-Time Kernel
;#
;#                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
;#                                          All Rights Reserved
;#
;# File : OS_CPU_A.ASM
;# By   : Jean J. Labrosse
;#********************************************************************************************************
;
;#********************************************************************************************************
;#                                               ARM Port
;#
;#                 Target           : ARM (Includes ARM7, ARM9)
;#                 Ported by        : Michael Anburaj
;#                 URL              : http://geocities.com/michaelanburaj/    Email : michaelanburaj@hotmail.com
;#
;#********************************************************************************************************



 ;       .text
    
    PRESERVE8
	CODE32
    AREA    OSStartHighRdy_CODE32, CODE, READONLY
;#*********************************************************************************************************
;#                                          START MULTITASKING
;#                                       void OSStartHighRdy(void)
;#
;# Note : OSStartHighRdy() MUST:
;#           a) Call OSTaskSwHook() then,
;#           b) Set OSRunning to TRUE,
;#           c) Switch to the highest priority task.
;#*********************************************************************************************************

        IMPORT  OSTaskSwHook
        IMPORT  OSRunning
        IMPORT  OSTCBHighRdy

        EXPORT  OSStartHighRdy

OSStartHighRdy  

        bl OSTaskSwHook             ;@ Call user defined task switch hook

        ldr r4,=OSRunning           ;@ Indicate that multitasking has started
        mov r5,#1
        strb r5,[r4]

        ldr r4,=OSTCBHighRdy        ;@ Get highest priority task TCB address

        ldr r4,[r4]                 ;@ get stack pointer
        ldr sp,[r4]                 ;@ switch to the new stack

        ldmfd sp!,{r4}              ;@ pop new task's spsr
        msr SPSR_cxsf,r4		   
        ldmfd sp!,{r4}             ; @ pop new task's psr
        msr CPSR_cxsf,r4
        ldmfd sp!,{r0-r12,lr,pc}    ;@;; pop new task's r0-r12,lr & pc

	;	END

;#*********************************************************************************************************
;#                                PERFORM A CONTEXT SWITCH (From task level)
;#                                           void OSCtxSw(void)
;#
;# Note(s):    Upon entry, 
;#             OSTCBCur     points to the OS_TCB of the task to suspend
;#             OSTCBHighRdy points to the OS_TCB of the task to resume
;#
;#*********************************************************************************************************

     ;   	CODE32
    ;AREA    OSCtxSW_CODE32, CODE, READONLY
		
		IMPORT  OSTCBCur
        IMPORT  OSTaskSwHook
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy

        EXPORT  OSCtxSw

OSCtxSw
;# Special optimised code below:
        stmfd sp!,{lr}             ; @ push pc (lr should be pushed in place of PC)
        stmfd sp!,{r0-r12,lr}      ; @ push lr & register file
        mrs r4,cpsr
        stmfd sp!,{r4}              ;@ push current psr
        mrs r4,spsr
        stmfd sp!,{r4}            ;  @ push current spsr

       ; @ OSPrioCur = OSPrioHighRdy
        ldr r4,=OSPrioCur
        ldr r5,=OSPrioHighRdy
        ldrb r6,[r5]
        strb r6,[r4]
        
      ;  @ Get current task TCB address
        ldr r4,=OSTCBCur
        ldr r5,[r4]
        str sp,[r5]                ; @ store sp in preempted tasks's TCB

        bl OSTaskSwHook           ;  @ call Task Switch Hook

       ; @ Get highest priority task TCB address
        ldr r6,=OSTCBHighRdy
        ldr r6,[r6]
        ldr sp,[r6]                ; @ get new task's stack pointer

       ; @ OSTCBCur = OSTCBHighRdy
        str r6,[r4]                ; @ set new current task TCB address

        ldmfd sp!,{r4}             ; @ pop new task's spsr
        msr SPSR_cxsf,r4
        ldmfd sp!,{r4}             ; @ pop new task's psr
        msr CPSR_cxsf,r4
        ldmfd sp!,{r0-r12,lr,pc}    ;@ pop new task's r0-r12,lr & pc

	;	END
;#*********************************************************************************************************
;#                                PERFORM A CONTEXT SWITCH (From an ISR)
;#                                        void OSIntCtxSw(void)
;#
;# Note(s): This function only flags a context switch to the ISR Handler
;#
;#*********************************************************************************************************
	;		CODE32
    ;AREA    OSIntCtxSw_CODE32, CODE, READONLY
        IMPORT  OSIntCtxSwFlag

        EXPORT  OSIntCtxSw

OSIntCtxSw

        ;#OSIntCtxSwFlag = True
        ldr r0,=OSIntCtxSwFlag
        mov r1,#1
        str r1,[r0]
        mov pc,lr
        
	;	END
;#*********************************************************************************************************
;#                                            IRQ HANDLER
;#
;#        This handles all the IRQs
;#        Note: FIQ Handler should be written similar to this
;#
;#*********************************************************************************************************
	;		CODE32
    ;AREA    TickHandler_CODE32, CODE, READONLY
        IMPORT  Timer0Interrupt
        IMPORT  OSIntEnter
        IMPORT  OSIntExit

        IMPORT  OSIntCtxSwFlag
        IMPORT  OSTCBCur
        IMPORT  OSTaskSwHook
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy

NOINT  EQU  0xC0

        EXPORT  TickHandler
TickHandler

        stmfd sp!,{r0-r3,r12,lr}

        bl OSIntEnter
        bl Timer0Interrupt
        bl OSIntExit

        ldr r0,=OSIntCtxSwFlag
        ldr r1,[r0]
        cmp r1,#1
        beq _IntCtxSw

        ldmfd sp!,{r0-r3,r12,lr}
        subs pc,lr,#4

	;	END
			
	;		CODE32
    ;AREA    _IntCtxSw_CODE32, CODE, READONLY


_IntCtxSw
        mov r1,#0
        str r1,[r0]

        ldmfd sp!,{r0-r3,r12,lr}
        stmfd sp!,{r0-r3}
        mov r1,sp
        add sp,sp,#16
        sub r2,lr,#4

        mrs r3,spsr
        orr r0,r3,#NOINT
        msr spsr_c,r0

        ldr r0,=.+8
        movs pc,r0

        stmfd sp!,{r2}            ;  @ push old task's pc
        stmfd sp!,{r4-r12,lr}     ;  @ push old task's lr,r12-r4
        mov r4,r1                 ;  @ Special optimised code below
        mov r5,r3
        ldmfd r4!,{r0-r3}
        stmfd sp!,{r0-r3}         ;  @ push old task's r3-r0
        stmfd sp!,{r5}            ;  @ push old task's psr
        mrs r4,spsr
        stmfd sp!,{r4}             ; @ push old task's spsr
        
      ;  @ OSPrioCur = OSPrioHighRdy
        ldr r4,=OSPrioCur
        ldr r5,=OSPrioHighRdy
        ldrb r5,[r5]
        strb r5,[r4]
        
      ;  @ Get current task TCB address
        ldr r4,=OSTCBCur
        ldr r5,[r4]
        str sp,[r5]               ;  @ store sp in preempted tasks's TCB

        bl OSTaskSwHook           ;  @ call Task Switch Hook

      ;  @ Get highest priority task TCB address
        ldr r6,=OSTCBHighRdy
        ldr r6,[r6]
        ldr sp,[r6]                ; @ get new task's stack pointer
	  
      ;  @ OSTCBCur = OSTCBHighRdy
        str r6,[r4]                 ;@ set new current task TCB address

        ldmfd sp!,{r4}              ;@ pop new task's spsr
        msr SPSR_cxsf,r4
        ldmfd sp!,{r4}              ;@ pop new task's psr
        msr CPSR_cxsf,r4

        ldmfd sp!,{r0-r12,lr,pc}    ;@ pop new task's r0-r12,lr & pc


	;	END
;#*********************************************************************************************************
;#                                   CRITICAL SECTION METHOD 3 FUNCTIONS
;#
;# Description: Disable/Enable interrupts by preserving the state of interrupts.  Generally speaking you
;#              would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
;#              disable interrupts.  'cpu_sr' is allocated in all of uC/OS-II's functions that need to 
;#              disable interrupts.  You would restore the interrupt disable state by copying back 'cpu_sr'
;#              into the CPU's status register.
;#
;#              OS_CPU_SR OSCPUSaveSR()
;# Arguments  : none
;#
;# Returns    : OS_CPU_SR
;#
;#              OSCPURestoreSR(OS_CPU_SR cpu_sr)
;# Arguments  : OS_CPU_SR
;#
;# Returns    : none
;#
;# Note(s)    : These functions are used in general like this,
;#
;#            void Task (void *data)
;#            {
;#                    #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
;#                          OS_CPU_SR  cpu_sr#
;#                    #endif
;#                         :
;#                         :
;#                    OS_ENTER_CRITICAL()# /* cpu_sr = OSCPUSaveSR()# */
;#                         :
;#                         :
;#                    OS_EXIT_CRITICAL()#  /* OSCPURestoreSR(cpu_sr)# */
;#                         :
;#                         :
;#            }
;#*********************************************************************************************************
		
	;		CODE32
    ;AREA    OSCPUSaveSR_CODE32, CODE, READONLY
            EXPORT  OSCPUSaveSR
OSCPUSaveSR

        mrs r0,CPSR
        orr r1,r0,#NOINT
        msr CPSR_c,r1
        mov pc,lr

     ;   END

		
		;	CODE32
    ;AREA    OSCPURestoreSR_CODE32, CODE, READONLY

        EXPORT  OSCPURestoreSR
OSCPURestoreSR

        ; msr CPSR_c,r0
        ;mov pc,lr
		;bic  r0,r0, #NOINT
		msr CPSR_c,r0
		mov pc,lr

        END
        

⌨️ 快捷键说明

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