📄 os_cpu_a.s.111019191938
字号:
;*******************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; ATmega128 Specific code
; ICC AVR Compiler
;
;
; File : OS_CPU_A.s
; By : Jean J. Labrosse
;*******************************************************************************
.include "..\source\CPU_Source\OS_CPU_A.h"
.area text(rel)
;/*$PAGE*/
;********************************************************************************************************
; DISABLE/ENABLE INTERRUPTS USING OS_CRITICAL_METHOD #3
;
; Description : These functions are used to disable and enable interrupts using OS_CRITICAL_METHOD #3.
;
; OS_CPU_SR OSCPUSaveSR (void)
; Get current value of SREG
; Disable interrupts
; Return original value of SREG
;
; void OSCPURestoreSR (OS_CPU_SR cpu_sr)
; Set SREG to cpu_sr
; Return
;********************************************************************************************************
_OS_CPU_SR_Save::
IN R16,SREG ; Get current state of interrupts disable flag
CLI ; Disable interrupts
RET ; Return original SREG value in R16
_OS_CPU_SR_Restore::
OUT SREG,R16 ; Restore SREG
RET ; Return
;*******************************************************************************
; START HIGHEST PRIORITY TASK READY-TO-RUN
;
; Description : This function is called by OSStart() to start the highest
; priority task that was created by your application before calling OSStart().
;
; Note(s):
; 1) The (data)stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> LSB of (return) stack pointer (Low memory)
; MSB of (return) stack pointer
; Flags to load in status register
; R31
; R30
; R7
; .
; .
; .
; R0 (High memory)
;
; where the stack pointer points to the task start address.
;
;
; 2) OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*******************************************************************************
_OSStartHighRdy::
CALL _OSTaskSwHook ; Invoke user defined context switch hook
LDS R16,_OSRunning ; Indicate that we are multitasking
INC R16
STS _OSRunning,R16 ;
LDS R30,_OSTCBHighRdy ; Let Z point to TCB of highest priority task
LDS R31,_OSTCBHighRdy+1 ; ready to run
LD R28,Z+ ; Load Y (R29:R28) pointer
LD R29,Z+ ;
POPSP ; restore stack pointer
POPSREG ; restore SREG
POPRS ; restore registers
RETI ; start task
;*******************************************************************************
; TASK LEVEL CONTEXT SWITCH
;
; Description : This function is called when a task makes a higher priority task
; ready-to-run.
;
; 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 --> LSB of task code address
; +1 MSB of task code address (High memory)
;
; 3) The saved context of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> LSB of (return) stack pointer (Low memory)
; MSB of (return) stack pointer
; Flags to load in status register
; R31
; R30
; R7
; .
; .
; .
; R0 (High memory)
;*******************************************************************************
_OSCtxSw::
//保存处理器寄存器
PUSHRS ; Save current task's context
PUSHSREG
PUSHSP
LDS R30,_OSTCBCur ; Z = OSTCBCur->OSTCBStkPtr
LDS R31,_OSTCBCur+1 ;
ST Z+,R28 ; Save Y (R29:R28) pointer
ST Z+,R29 ;
CALL _OSTaskSwHook ; Call user defined task switch hook
LDS R16,_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
STS _OSPrioCur,R16
LDS R30,_OSTCBHighRdy ; Let Z point to TCB of highest priority task
LDS R31,_OSTCBHighRdy+1 ; ready to run
STS _OSTCBCur,R30 ; OSTCBCur = OSTCBHighRdy
STS _OSTCBCur+1,R31 ;
LD R28,Z+ ; Restore Y pointer
LD R29,Z+ ;
POPSP ; restore stack pointer
LD R16,Y+ ;restores status register
SBRC R16,7 ;SKip next instruction in interrupt disabled
RJMP OSCtxSw_1
OUT SREG,R16 ;Interrupts of task to return to are disabled
POPRS ; restore registers
RET ;
OSCtxSw_1:
CBR R16,BIT07 ;Interrupts of task to return to are enabled
OUT SREG,R16
POPRS
RETI ;return form interrupt and enable interrupts
;*******************************************************************************
; INTERRUPT LEVEL CONTEXT SWITCH
;
; Description : This function is called by OSIntExit() to perform a context
; switch to a task that has been made ready-to-run by an ISR.
;
; 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 --> LSB of return address of OSIntCtxSw() (Low memory)
; +1 MSB of return address of OSIntCtxSw()
; +2 LSB of return address of OSIntExit()
; +3 MSB of return address of OSIntExit()
; +4 LSB of task code address
; +5 MSB of task code address (High memory)
;
; 3) The saved context of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> LSB of (return) stack pointer (Low mem)
; MSB of (return) stack pointer
; Flags to load in status register
; R31
; R30
; R7
; .
; .
; .
; R0 (High memory)
;*******************************************************************************
_OSIntCtxSw::
; IN R30,SPL ; Z = SP
; IN R31,SPH
; ADIW R30,4 ; (Uncomment if OS_CRITICAL_METHOD is 1, see OS_CPU.H)
; ADIW R30,5 ; Adjust Z to point to task return address
; ST -Y,R31 ; Save SP
; ST -Y,R30 ;
; LDS R30,_OSTCBCur ; Z = OSTCBCur->OSTCBStkPtr
; LDS R31,_OSTCBCur+1 ;
; ST Z+,R28 ; Save Y pointer
; ST Z+,R29 ;
CALL _OSTaskSwHook ; Call user defined task switch hook
LDS R16,_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
STS _OSPrioCur,R16 ;
LDS R30,_OSTCBHighRdy ; Z = OSTCBHighRdy->OSTCBStkPtr
LDS R31,_OSTCBHighRdy+1 ;
STS _OSTCBCur,R30 ; OSTCBCur = OSTCBHighRdy
STS _OSTCBCur+1,R31 ;
LD R28,Z+ ; Restore Y pointer
LD R29,Z+ ;
POPSP ; restore stack pointer
LD R16,Y+ ; restore stuatus register
SBRC R16,7
RJMP OSIntCtxSw_1
OUT SREG,R16 ; restore SREG
POPRS ; restore registers
RET
OSIntCtxSw_1:
CBR R16,BIT07;
OUT SREG,R16
POPRS
RETI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -