📄 os_cpu_a.asm
字号:
OR CCR, #40H ;
#endif
SAVE_REGISTERS_CONTEXT ; Save context of resister of interrupted task
;
#if MEMMODEL == SMALL || MEMMODEL == MEDIUM ; Save SP of the task to suspend for small and medium models
MOVW A,SP ;
MOVW A,_OSTCBCur ;
MOVW @AL,AH ; OSTCBCur->OSTCBStkPtr = SP
#endif
#if MEMMODEL == COMPACT || MEMMODEL == LARGE ; Save SSB:SP of the task to suspend for compact and large models
MOV A, #bnksym _OSTCBCur ;
MOV ADB, A ; Set bank of _OSTCBCur
MOVL A,ADB:_OSTCBCur ; Get OSTCBCur->OSTCBStkPtr
SWAPW ; Set bank for access to
MOV ADB, A ; *OSTCBCur->OSTCBStkPtr
SWAPW ;
MOVW A,SP ;
SWAPW ;
MOVW @AL,AH ; OSTCBCur->OSTCBStkPtr = SP
#endif
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
CALL _OSTaskSwHook ; Call user defined task switch hook
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
CALLP _OSTaskSwHook ; Call user defined task switch hook
#endif
;
#if MEMMODEL == SMALL || MEMMODEL == MEDIUM ;
MOV A,_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV _OSPrioCur,A ;
;
MOVW A,_OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
MOVW _OSTCBCur,A ;
MOVW A,@A ;
MOVW SP,A ; SP = *OSTCBHighRdy->OSTCBStkPtr
#endif
#if MEMMODEL == COMPACT || MEMMODEL == LARGE ;
MOV A, #bnksym _OSPrioHighRdy
MOV ADB, A
MOV A,ADB:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV ADB:_OSPrioCur, A ;
;
MOVL A,ADB:_OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
MOVL ADB:_OSTCBCur,A ;
PUSHW A ;
SWAPW ; Set bank for access to
MOV ADB, A ; *OSTCBHighRdy->OSTCBStkPtr
SWAPW ;
;
MOVW A,ADB:@A ;
POPW A ;
SWAPW ;
MOVW SP,A ; SP = *OSTCBHighRdy->OSTCBStkPtr
SWAPW ;
ADDW A,#2 ;
MOVW A,ADB:@A ;
MOV SSB,A
#endif
;
RESTORE_REGISTERS_CONTEXT ; Restore context of resisters of interrupted task
;
RETI ; Return to new task
;*********************************************************************************************************
; 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:
;
; (High memory)
; | | |
; | | | <- a value of SSP before the interrupt occurrence
; | AH |
; | AL |
; | DPR | ADB |
; | DTB | PCB |
; | PC |
; | PS | <- a value of SSP after the interrupt occurrence
; +---------------+----------------------------+
; | Return address to caller of OSIntExit() |
; +--------------------------------------------+-----------------+
; | RW0(RW1)-bank(ISRbank) saved by OSIntExit() |
; | (different for different memory models and critical methods) |
; +--------------------------------------------+-----------------+
; | Return address to caller of OSIntCtxSw() | <- a value of SSP after
; +---------------+----------------------------+ entry in OSIntCtxSw
; | | |
; (Low memory)
;
;
; 3) If task to suspend uses bank of registers other that #0, then the
; stack frame of the task must be changed as follows:
;
; (High memory)
; | | |
; | | | <- a value of SSP before the interrupt occurrence
; | AH |
; | AL |
; | DPR | ADB |
; | DTB | PCB |
; | PC |
; | PS | <- a value of SSP after the interrupt occurrence
; | | |
; (Low memory)
;
; 4) If task to suspend uses bank of registers #0, then
; OSIntCtxSw must save context of registers bank #0 in the stack.
; The stack frame of the task to suspend must be changed as follows:
;
; (High memory)
; | | |
; | | | <- a value of SSP before the interrupt occurrence
; | AH |
; | AL |
; | DPR | ADB |
; | DTB | PCB |
; | PC |
; | PS | <- a value of SSP after the interrupt occurrence
; | RW7-bank(0) |
; | RW6-bank(0) |
; | RW5-bank(0) |
; | RW4-bank(0) |
; | RW3-bank(0) |
; | RW2-bank(0) |
; | RW1-bank(0) |
; | RW0-bank(0) |
; | PS | <- a value of SSP must be here after registers context saved
; | | |
; (Low memory)
;
;
; 5) If task to resume uses bank of registers other that #0, then the
; stack frame of the task looks as follows:
;
; (High memory)
; | | |
; | | | <- a value of SSP must be here after reti instruction
; | AH |
; | AL |
; | DPR | ADB |
; | DTB | PCB |
; | PC |
; | PS | <- OSTCBHighRdy->OSTCBStkPtr
; | | |
; (Low memory)
;
; 6) If task to resume uses bank of registers #0, then the stack frame
; of the task looks as follows:
; (High memory)
; | | |
; | | | <- a value of SSP must be here after reti instruction
; | AH |
; | AL |
; | DPR | ADB |
; | DTB | PCB |
; | PC |
; | PS | <- a value of SSP must be here after registers context restored
; | RW7-bank(0) |
; | RW6-bank(0) |
; | RW5-bank(0) |
; | RW4-bank(0) |
; | RW3-bank(0) |
; | RW2-bank(0) |
; | RW1-bank(0) |
; | RW0-bank(0) |
; | PS | <- OSTCBHighRdy->OSTCBStkPtr
; | | |
; (Low memory)
;
;*********************************************************************************************************
_OSIntCtxSw:
#if MEMMODEL == SMALL ; Ignore calls to OSIntExit, OSIntCtxSw,
; saved RW0 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
#if OS_CRITICAL_METHOD == 1
ADDSP #6 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
ADDSP #8 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
#endif ; MEMMODEL == SMALL
#if MEMMODEL == COMPACT ; Ignore calls to OSIntExit, OSIntCtxSw,
; saved RW0,RW1 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
#if OS_CRITICAL_METHOD == 1
ADDSP #8 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
ADDSP #10 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
#endif ; MEMMODEL == COMPACT
#if MEMMODEL == MEDIUM ; Ignore calls to OSIntExit, OSIntCtxSw,
; saved RW0 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
#if OS_CRITICAL_METHOD == 1
ADDSP #10 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
ADDSP #12 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
#endif ; MEMMODEL == MEDIUM
#if MEMMODEL == LARGE ; Ignore calls to OSIntExit, OSIntCtxSw,
; saved RW0,RW1 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
#if OS_CRITICAL_METHOD == 1
ADDSP #12 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
ADDSP #14 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
#endif ; MEMMODEL == LARGE
SAVE_REGISTERS_CONTEXT ; Save context of resister of interrupted task
#if MEMMODEL == SMALL || MEMMODEL == MEDIUM ; Save SP of the task to suspend for small and medium models
MOVW A,SP ;
MOVW A,_OSTCBCur ;
MOVW @AL,AH ; OSTCBCur->OSTCBStkPtr = SP
#endif
#if MEMMODEL == COMPACT || MEMMODEL == LARGE ; Save SSB:SP of the task to suspend for compact and large models
MOV A, #bnksym _OSTCBCur ;
MOV ADB, A ; Set bank of _OSTCBCur
MOVL A,ADB:_OSTCBCur ; Get OSTCBCur->OSTCBStkPtr
SWAPW ; Set bank for access to
MOV ADB, A ; *OSTCBCur->OSTCBStkPtr
SWAPW ;
MOVW A,SP ;
SWAPW ;
MOVW @AL,AH ; OSTCBCur->OSTCBStkPtr = SP
#endif
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
CALL _OSTaskSwHook ; Call user defined task switch hook
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
CALLP _OSTaskSwHook ; Call user defined task switch hook
#endif
#if MEMMODEL == SMALL || MEMMODEL == MEDIUM ;
;
MOV A,_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV _OSPrioCur,A ;
;
MOVW A,_OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
MOVW _OSTCBCur,A ;
MOVW A,@A ;
MOVW SP,A ; SP = *OSTCBHighRdy->OSTCBStkPtr
#endif
#if MEMMODEL == COMPACT || MEMMODEL == LARGE ;
MOV A, #bnksym _OSPrioHighRdy
MOV ADB, A
MOV A,ADB:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV ADB:_OSPrioCur, A ;
;
MOVL A,ADB:_OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
MOVL ADB:_OSTCBCur,A ;
PUSHW A ;
SWAPW ; Set bank for access to
MOV ADB, A ; *OSTCBHighRdy->OSTCBStkPtr
SWAPW ;
;
MOVW A,ADB:@A ;
POPW A ;
SWAPW ;
MOVW SP,A ; SP = *OSTCBHighRdy->OSTCBStkPtr
SWAPW ;
ADDW A,#2 ;
MOVW A,ADB:@A ;
MOV SSB,A
#endif
;
RESTORE_REGISTERS_CONTEXT ; Restore context of resisters of interrupted task
;
RETI ; Return to new task
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: This is the system timer interrupt handler.
;
; Arguments : none
;
; Returns : none
;
; Note(s) : For reset the interrupt request flag the handler uses function OSTimeTickHook in OS_CPU_C.C
;*********************************************************************************************************
_OSTickISR:
MOV RP,#1 ; Set register bank 1 for TickISR
ASM_ISR_ENTER ;
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
CALL _OSTimeTick ; Process system tick
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
CALLP _OSTimeTick ; Process system tick
#endif
;
RETI
;*********************************************************************************************************
; Delayed Interrupt ISR
; Causes switching the context after completion of processing of all interrupts.
;
; Disable the interrupts for prevention of coming the more priority interrupt when switching the context.
; Reset the bit in register "dirr", avoiding reason Delayed Interrupt.
; Reset _OSIntNesting, reporting this OS about that that all interrupts are finished.
; Call _OSIntExit.
;*********************************************************************************************************
_iDIRR_ISR:
#if (OS_CRITICAL_METHOD == 1) || (OS_CRITICAL_METHOD == 2)
AND CCR, #191 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif OS_CRITICAL_METHOD == 12
MOV ILM,#1 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
;
MOVN A, #0
MOV I:__dirr, A ; Reset delayed interrupt request
;
MOV _OSIntNesting, A ; Notify OS about last interrupt
;
MOV RP,#1 ; Set register bank #1 for Delayed ISR
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
CALL _OSIntExit ; Reschedule, if necessary
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
CALLP _OSIntExit ; Reschedule, if necessary
#endif
;
RETI
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -