📄 os_cpu_a.asm
字号:
.mmregs
.def _OSTickISR
.def _OSStartHighRdy
.def _OSCtxSw
.def _OSIntCtxSw
.ref _OSIntExit
.ref _OSTimeTick
.ref _OSTaskSwHook
.ref _OSIntEnter
.ref _OSIntNesting
.ref _OSPrioHighRdy
.ref _OSPrioCur
.ref _OSRunning
.ref _OSTCBCur
.ref _OSTCBHighRdy
CONTEXT_SAVE .macro
PSHM ST0
PSHM ST1
PSHM AL
PSHM AH
PSHM AG
PSHM BL
PSHM BH
PSHM BG
PSHM T
PSHM TRN
PSHM AR0
PSHM AR1
PSHM AR2
PSHM AR3
PSHM AR4
PSHM AR5
PSHM AR6
PSHM AR7
PSHM BK
PSHM BRC
PSHM RSA
PSHM REA
.endm
CONTEXT_RESTORE .macro
POPM REA
POPM RSA
POPM BRC
POPM BK
POPM AR7
POPM AR6
POPM AR5
POPM AR4
POPM AR3
POPM AR2
POPM AR1
POPM AR0
POPM TRN
POPM T
POPM BG
POPM BH
POPM BL
POPM AG
POPM AH
POPM AL
POPM ST1
POPM ST0
.endm
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> REA (Low memory)
; RSA
; BRC
; BK
; AR7
; AR6
; AR5
; AR4
; AR3
; AR2
; AR1
; AR0
; TRN
; T
; BG
; BH
; BL
; AG
; AH
; AL
; ST1
; ST0 (High memory)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
_OSStartHighRdy:
CALL #_OSTaskSwHook ;
ST #1, *(_OSRunning) ;
LD *(_OSTCBHighRdy), A ;
NOP
NOP
STLM A, AR0
NOP
NOP
LD *AR0(0), A ;
NOP
NOP
STLM A, SP
NOP
NOP
CONTEXT_RESTORE ;
NOP
NOP
RETE
;*********************************************************************************************************
; 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
;
; 2) The stack frame of the task to suspend looks as follows:
;
; SP -> Address of task to suspend
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> REA (Low memory)
; RSA
; BRC
; BK
; AR7
; AR6
; AR5
; AR4
; AR3
; AR2
; AR1
; AR0
; TRN
; T
; BG
; BH
; BL
; AG
; AH
; AL
; ST1
; ST0
; IMR (High memory)
;*********************************************************************************************************
_OSCtxSw:
CONTEXT_SAVE ; Save task context
NOP
NOP
LD *(_OSTCBCur), A ; Load OSTCBCur->OSTCBStkPtr addr to reg AR0
NOP
NOP
STLM A, AR0 ;
LDM SP, B ; Save SP to *AR0(0)
NOP ; that is OSTCBCur->OSTCBStkPtr
NOP
STL B, *AR0(0) ;
CALL #_OSTaskSwHook ; Call hook func
LD *(_OSTCBHighRdy), A ; Let OSTCBCur=OSTCBHighRdy
LD *(_OSPrioHighRdy), B ; Let OSPrioCur=OSPrioHighRdy
NOP
NOP
STL A, *(_OSTCBCur)
STL B, *(_OSPrioCur)
STLM A, AR0 ; Load SP from *AR0(0)
NOP ; that is OSTCBCur->OSTCBStkPtr
NOP
LD *AR0(0), A ;
NOP
NOP
STLM A, SP ;
NOP
NOP
CONTEXT_RESTORE ; Restore task context
NOP
NOP
RETE ; Start HPT
;*********************************************************************************************************
; 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
;
; 2) The stack frame of the task to suspend looks as follows:
;
; SP+0 -->
; Return address of OSIntCtxSw()
; PSHM 11H in OSIntExit
; Return address of OSIntExit()
; REA
; RSA
; BRC
; BK
; AR7
; AR6
; AR5
; AR4
; AR3
; AR2
; AR1
; AR0
; TRN
; T
; BG
; BH
; BL
; AG
; AH
; AL
; ST1
; ST0
; Task code address
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> REA (Low memory)
; RSA
; BRC
; BK
; AR7
; AR6
; AR5
; AR4
; AR3
; AR2
; AR1
; AR0
; TRN
; T
; BG
; BH
; BL
; AG
; AH
; AL
; ST1
; ST0 (High memory)
;*********************************************************************************************************
_OSIntCtxSw:
FRAME 3 ; Adjust SP
LD *(_OSTCBCur), A ; Load OSTCBCur->OSTCBStkPtr addr to reg AR0
NOP
NOP
STLM A, AR0 ;
LDM SP, B ; Save SP to AR0(0)
NOP ; that is OSTCBCur->OSTCBStkPtr
NOP
STL B, *AR0(0) ;
CALL #_OSTaskSwHook ; Call hook func
LD *(_OSTCBHighRdy), A ; Let OSTCBCur=OSTCBHighRdy
LD *(_OSPrioHighRdy), B ; Let OSPrioCur=OSPrioHighRdy
NOP
STL A, *(_OSTCBCur) ;
STL B, *(_OSPrioCur) ;
STLM A, AR0 ; Load OSTCBCur->OSTCBStkPtr to SP
NOP
NOP
LD *AR0(0), A ;
NOP
NOP
STLM A, SP ;
NOP
NOP
CONTEXT_RESTORE ; Restore task context
NOP
NOP
RETE ; Start HPT
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: This function is called 1000 times per second
;
; Arguments : none
;
; Returns : none
;
; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
; Save all registers on the current task's stack;
; OSIntNesting++ or OSIntEnter()
; OSTimeTick(); Notify uC/OS-II that a tick has occured
; OSIntExit(); Notify uC/OS-II about end of ISR
; Restore all registers that were save on the current task's stack;
; Return from Interrupt;
;*********************************************************************************************************
;
_OSTickISR:
CONTEXT_SAVE
NOP
NOP
CALL #_OSIntEnter
CALL #_OSTimeTick
CALL #_OSIntExit
CONTEXT_RESTORE
NOP
NOP
RETE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -