📄 os_cpu_a.asm
字号:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
; All Rights Reserved
;
;
; Texas Instruments TMS320C40 Specific Code
; SMALL MEMORY MODEL
;
;
; File : OS_CPU_A.ASM
; By : Jean J. Labrosse
; Modified by: Ran Cabell
;********************************************************************************************************
.def _OSTickISR
.def _OSStartHighRdy
.def _OSCtxSw
.def _OSIntCtxSw
.ref _OSIntExit
.ref _OSTimeTick
; .ref _OSTaskSwHook
.ref _OSIntNesting
.ref _OSPrioHighRdy
.ref _OSPrioCur
.ref _OSRunning
.ref _OSTCBCur
.ref _OSTCBHighRdy
.text
;*********************************************************************************************************
;
; Define some useful macros
; Note save/restore order for extended precision registers R0-R11
;*********************************************************************************************************
SAVE_CTX .MACRO
PUSH ST ; Status register
; Re-enable interrupts here?
PUSH AR0 ; Save aux registers
PUSH AR1
PUSH AR2
PUSH AR3
PUSH AR4
PUSH AR5
PUSH AR6
PUSH AR7
PUSH IR0
PUSH IR1
PUSH BK
PUSH RS ; Repeat start address
PUSH RE ; Repeat end address
PUSH RC ; Repeat counter
ADDI 1, SP, AR0
LDI 2, IR0
ADDI 1, AR0, AR1
ADDI 16, SP
STI R0, *AR0++(IR0)
|| STI R1, *AR1++(IR0)
STI R2, *AR0++(IR0)
|| STI R3, *AR1++(IR0)
STI R4, *AR0++(IR0)
|| STI R5, *AR1++(IR0)
STI R6, *AR0++(IR0)
|| STI R7, *AR1++(IR0)
STF R0, *AR0++(IR0)
|| STF R1, *AR1++(IR0)
STF R2, *AR0++(IR0)
|| STF R3, *AR1++(IR0)
STF R4, *AR0++(IR0)
|| STF R5, *AR1++(IR0)
STF R6, *AR0++(IR0)
|| STF R7, *AR1++(IR0)
PUSH R8
PUSH R9
PUSH R10
PUSH R11
PUSHF R8
PUSHF R9
PUSHF R10
PUSHF R11
.ENDM
RESTORE_CTX .MACRO
POPF R11
POPF R10
POPF R9
POPF R8
POP R11
POP R10
POP R9
POP R8
LDI SP, AR0
LDI 2, IR0
SUBI 1, AR0, AR1
LDF *AR0--(IR0), R7
|| LDF *AR1--(IR0), R6
LDF *AR0--(IR0), R5
|| LDF *AR1--(IR0), R4
LDF *AR0--(IR0), R3
|| LDF *AR1--(IR0), R2
LDF *AR0--(IR0), R1
|| LDF *AR1--(IR0), R0
LDI *AR0--(IR0), R7
|| LDI *AR1--(IR0), R6
LDI *AR0--(IR0), R5
|| LDI *AR1--(IR0), R4
LDI *AR0--(IR0), R3
|| LDI *AR1--(IR0), R2
LDI *AR0--(IR0), R1
|| LDI *AR1--(IR0), R0
SUBI 16, SP
POP RC
POP RE
POP RS
POP BK
POP IR1
POP IR0
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR2
POP AR1
POP AR0
POP ST
.ENDM
.page ; /*$PAGE*/
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;
; Interrupts not enabled yet.
;
;*********************************************************************************************************
_OSStartHighRdy:
LDI @_OSTCBHighRdy, AR0 ;
LDI *AR0, SP ; SP = OSTCBHighRdy->OSTCBStkPtr
;
; CALL _OSTaskSwHook ; Call user defined task switch hook
;
LDI 1, AR0 ; OSRunning += 1
ADDI @_OSRunning, AR0
STI AR0, @_OSRunning
RESTORE_CTX
RETI
.page ; /*$PAGE*/
;*********************************************************************************************************
; 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:
;
; (see SAVE_CTX macro)
;
; 3) The stack frame of the task to resume looks as follows:
;
; (see RESTORE_CTX macro)
;
; Interrupts disabled for duration of OSCtxSw
;
;*********************************************************************************************************
_OSCtxSw:
;
SAVE_CTX
;
LDI @_OSTCBCur, AR0
STI SP, *AR0
;
;
; CALL _OSTaskSwHook ; Call user defined task switch hook
;
LDI @_OSTCBHighRdy, AR0
STI AR0, @_OSTCBCur
LDI *AR0, SP
LDI @_OSPrioHighRdy, AR0
STI AR0, @_OSPrioCur
RESTORE_CTX
;
RETI ; Return to new task
;
.page ; /*$PAGE*/
;*********************************************************************************************************
; 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:
;
; (see SAVE_CTX macro)
;
; 3) The stack frame of the task to resume looks as follows:
;
; (see RESTORE_CTX macro)
;
; Interrupts disabled for duration of OSIntCtxSw
;
;*********************************************************************************************************
_OSIntCtxSw:
; Ignore calls to OSIntExit and OSIntCtxSw
; SUBI 3, SP ; OS_CRITICAL_METHOD 1
; ; 3 = 2 return addresses + FP in OSIntExit
SUBI 4, SP ; OS_CRITICAL_METHOD 2
; 4 = 2 return addresses + FP + pushed ST
;
;
LDI @_OSTCBCur, AR0 ; Save SP in task being switched out
STI SP, *AR0
;
; CALL _OSTaskSwHook ; Call user defined task switch hook
;
LDI @_OSTCBHighRdy, AR0 ; Set new current task
STI AR0, @_OSTCBCur
LDI *AR0, SP ; SP = OSTCBHighRdy->OSTCBStkPtr
;
LDI @_OSPrioHighRdy, AR0 ; Set new running priority
STI AR0, @_OSPrioCur
;
RESTORE_CTX
;
RETI ; Return to new task
;
.page ; /*$PAGE*/
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: Service the timer tick interrupt.
;
; 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++;
; 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;
;
; Assumed to be interruptible, though interrupts currently not reenabled after entering here.
;
;*********************************************************************************************************
;
_OSTickISR:
;
SAVE_CTX
;
BRD $+4 ; Disable interrupts for next 3 instructions
LDI 1, AR0
ADDI @_OSIntNesting, AR0
STI AR0, @_OSIntNesting ; Notify uC/OS-II of ISR
;
CALL _OSTimeTick ; Process system tick
;
CALL _OSIntExit ; Notify uC/OS-II of end of ISR
;
RESTORE_CTX
;
RETI ; Return to interrupted task
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -