?? os_cpu_a.s
字號:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
; All Rights Reserved
;
;
; 80x86/80x88 Specific code
; LARGE MEMORY MODEL
;
; Borland C/C++ V4.51
; (IBM/PC Compatible Target)
;
; File : OS_CPU_A.ASM
; By : Jean J. Labrosse
;********************************************************************************************************
AREA |.text|, CODE, READONLY
;********************************************************************************************************
; PUBLIC and EXTERNAL REFERENCES
;********************************************************************************************************
EXPORT OSTickISR
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw
IMPORT OSIntEnter
IMPORT OSIntExit
IMPORT OSTimeTick
IMPORT OSTaskSwHook
IMPORT OSIntNesting
IMPORT OSPrioHighRdy
IMPORT OSPrioCur
IMPORT OSRunning
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
OSStartHighRdy FUNCTION
MSR CPSR_c, #0xd3 ; Switch to SVC mode with IRQ and FIQ disabled
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSRunning ; OSRunning = TRUE;
MOV r1, #1 ; (Indicates that multitasking has started)
STRB r1, [r0]
LDR r0, =OSTCBHighRdy ; sp = OSTCBHighRdy->OSTCBStkPtr
LDR r1, [r0]
LDR sp, [r1]
LDR r0, [sp], #4 ; Load task's context
MSR SPSR_cxsf, r0
LDMFD sp!, {r0 - r12, lr, pc}^ ; Run task
ENDFUNC
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level)
; void OSCtxSw(void)
;
; Note(s): 1) Upon entry,
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;
;*********************************************************************************************************
OSCtxSw FUNCTION
STR lr, [sp, #-4]! ; Save current task's context
STMFD sp!, {r0 - r12, lr}
MRS r0, CPSR
STR r0, [sp, #-4]!
LDR r0, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = sp
LDR r1, [r0]
STR sp, [r1]
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
LDR r1, =OSPrioCur
LDRB r2, [r0]
STRB r2, [r1]
LDR r0, =OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
LDR r1, =OSTCBCur
LDR r2, [r0]
STR r2, [r1]
LDR sp, [r2] ; sp = OSTCBHighRdy->OSTCBStkPtr
LDR r0, [sp], #4 ; Load task's context
MSR SPSR_cxsf, r0
LDMFD sp!, {r0 - r12, lr, pc}^ ; Run task
ENDFUNC
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From an ISR)
; void OSIntCtxSw(void)
;
; Note(s): 1) Upon entry,
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;
;*********************************************************************************************************
OSIntCtxSw FUNCTION
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
LDR r1, =OSPrioCur
LDRB r2, [r0]
STRB r2, [r1]
LDR r0, =OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
LDR r1, =OSTCBCur
LDR r2, [r0]
STR r2, [r1]
LDR sp, [r2] ; sp = OSTCBHighRdy->OSTCBStkPtr
LDR r0, [sp], #4 ; Load task's context
MSR SPSR_cxsf, r0
LDMFD sp!, {r0 - r12, lr, pc}^ ; Run task
ENDFUNC
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
; tick rate of 18.20648 Hz. Thus every 11th time, the normal DOS tick handler is called.
; This is called chaining. 10 times out of 11, however, the interrupt controller on the PC
; must be cleared to allow for the next interrupt.
;
; Arguments : none
;
; Returns : none
;
;*********************************************************************************************************
OSTickISR FUNCTION
STMFD sp!, {r0 - r2} ; Save working registers onto IRQ stack
SUB r2, lr, #4
MOV r0, sp
MRS r1, SPSR
ADD sp, sp, #12
MSR CPSR_c, #0xd3 ; Switch to SVC mode
STR r2, [sp, #-4]! ; Save task's context onto task's stack
STMFD sp!, {r3 - r12, lr}
LDMFD r0!, {r3 - r5} ; Move task's r0-r2 from IRQ stack to task's stack
STMFD sp!, {r3 - r5}
STR r1, [sp, #-4]! ; Save task's CPSR
BL OSIntEnter ; Notify uC/OS-II of ISR
LDR r0, =OSIntNesting ; if (OSIntNesting == 1)
LDRB r1,[r0]
CMP r1, #1
BNE %F0
LDR r0, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = sp
LDR r1, [r0]
STR sp, [r1]
0
LDR r0, =0x0a80000c ; Clear interrupt source
MOV r1, #0
STR r1, [r0]
BL OSTimeTick ; Process system tick
BL OSIntExit ; Notify uC/OS-II of end of ISR
LDR r0, [sp], #4 ; Load task's context
MSR SPSR_cxsf, r0
LDMFD sp!, {r0 - r12, lr, pc}^ ; Run task
ENDFUNC
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -