📄 ucos_asm.s03
字号:
mov DPH, WORK ;Complete pointer update
inc dptr ;Skip pointer type again
mov a, WORK+1 ;Load pointer to 'xstack' base (high)
movx @dptr, a ;Pass it to tcb
inc dptr ;Increment pointer
mov a, WORK+2 ;Load pointer to 'xstack' base (low)
movx @dptr, a ;Pass it to tcb
; Now we proceed to make next higher priority task ready to run, the new current task:
mov dptr, #OSTCBHighRdy + 1 ;Get OSTCBHighRdy
movx a, @dptr ;Read pointer high
mov WORK, a ;Save it in the work area
inc dptr ;Increment pointer
movx a, @dptr ;Read pointer low
mov WORK+1, a ;Save it in the work area
mov dptr, #OSTCBCur + 1 ;Get OSTCBCur
mov a, WORK ;Load pointer high
movx @dptr, a ;Update tcb
inc dptr ;Increment pointer
mov a, WORK+1 ;Load pointer low
movx @dptr, a ;Update tcb
mov DPL, WORK+1 ;Point to OSTCBHighRdy->STCKPTR
mov DPH, WORK ;Update pointer high
; Now we proceed to restore the task context to run scheduled task.
inc dptr ;Increment pointer to skip pointer type (01)
movx a, @dptr ;Get pointer high
mov WORK, a ;Save in work area
inc dptr ;Increment pointer
movx a, @dptr ;Get pointer low
mov DPL, a ;Update pointer low
mov DPH, WORK ;Load pointer high
; We are now pointing to the top of the 'xstack' of the task to be switched in
movx a, @dptr ;First byte is number of bytes on external stack
mov WORK, a ;Save it in work area
clr c ;Clear carry
mov a, DPL ;Load pointer low
subb a, WORK ;Substract number of bytes from the DPTR
mov DPL, a ;Update pointer low
jnc cs_01 ;If no carry, skip on
dec DPH ;DPTR now points to the base of the task's stack
cs_01: mov R0, #60h ;Hardware stack ('istack at IRAM), starts at 60h
mov R1, WORK ;Load number of bytes on stack in R1
cs_02: movx a, @dptr ;Get byte from task's external stack
mov @R0, a ;Pass it to internal stack
inc dptr ;Increment source pointer
inc R0 ;Increment destination pointer
djnz R1, cs_02 ;Copy the whole 'xstack' back into 'istack'
mov a, WORK ;Load number of bytes on stack
add a, #5Fh ;Add offset (SP points to a byte)
mov SP, a ;Restore the stack pointer
pop XSP+1 ;Restore 'xstack' base pointer
pop XSP ;..(high and low)
pop DPL ;Restore pointer low
pop DPH ;Restore pointer high
pop Bk0_r7 ;Restore register R7 (Bank #0)
pop Bk0_r6 ;Restore register R6 (Bank #0)
pop Bk0_r5 ;Restore register R5 (Bank #0)
pop Bk0_r4 ;Restore register R4 (Bank #0)
pop Bk0_r3 ;Restore register R3 (Bank #0)
pop Bk0_r2 ;Restore register R2 (Bank #0)
pop Bk0_r1 ;Restore register R1 (Bank #0)
pop Bk0_r0 ;Restore register R0 (Bank #0)
pop b ;Restore register B
pop ACC ;Restore accumulator
pop PSW ;Restore PSW
setb EA ;Exit critical section
reti ;Jump to execute scheduled task
ENDMOD
;----------------------------------------------------------------------------------------+ PERFORM A CONTEXT SWITCH (From interrupt level) |
; PERFORM A CONTEXT SWITCH (From interrupt level) |
; |
; void OSIntCtxSw(void) |
; |
; This module is used to perform a task switch as a result of an interrupt event. |
;----------------------------------------------------------------------------------------+
MODULE OSINTCTXSW ;Module name
RSEG CODE ;Relocatable Segment
;<---[ Symbols available for other modules: ]-------------------------------------------->
PUBLIC OSIntCtxSw ;Performs a task-level context switch
;<---[ Module definition for 'C' calls: ]------------------------------------------------>
$DEFFN OSIntCtxSw(0,0,0,0,32768,0,0,0)
;<---[ Symbols referenced, in other modules: ]------------------------------------------->
EXTERN OSTCBHighRdy ;TCB of highest priority task ready to run
EXTERN OSTCBCur ;TCB of current task
EXTERN OSPrioHighRdy ;Priority of highest priority task ready to run
EXTERN OSPrioCur ;Priority of current task
;<--------------------------------------------------------------------------------------->
OSIntCtxSw: ;Module entry point
clr EA ;Enter critical section
clr c ;Clear carry
mov a, SP ;Load Stack Pointer
subb a, #04 ;Substract 4 bytes because there have been two function calls
mov SP, a ;Now SP points to the base of current xstack
; On the stack the first two bytes are XSP (the pointer to the base of the stack).
; We pop the XSP into DPTR because we need it to copy the internal stack to.
pop DPL ;Get XSP+1
pop DPH ;Get XSP
push DPH ;Save it again to keep the stack intact
push DPL ;..(high and low)
clr c ;Clear accumulator
subb a, #5Fh ;See how many bytes are on stack
mov R1, a ;Save result in R1
mov WORK, a ;Save to move on top of 'xstack'
mov R0, #60h ;Bottom of internal stack
loop: mov a, @R0 ;Get byte from 'istack'
movx @dptr, a ;Move to 'xstack'
inc dptr ;Increment destination pointer
inc R0 ;Increment source pointer
djnz R1, loop ;Copy the whole 'istack' over to 'xstack'
mov a, WORK ;Load number of bytes in stack
movx @dptr, a ;Pass this data to xstack
; The current tasks context has been saved over external RAM.
mov XSP, DPH ;Update 'xstack' pointer high
mov XSP+1, DPL ;Update 'xstack' pointer low
; Now, we'll update the piority buffers:
mov dptr, #OSPrioHighRdy ;Point to buffer of top priority ready to run
movx a, @dptr ;Read it
mov dptr, #OSPrioCur ;Point to buffer of current priority
movx @dptr, a ;Update current priority
mov dptr, #OSTCBCur + 1 ;Point to TCB of current task (skip pointer type)
movx a, @dptr ;Read pointer high
mov WORK, a ;Save in the work area
inc dptr ;Increment pointer
movx a, @dptr ;Read pointer low
mov DPL, a ;Point TO OSTCBCUR->STCKPTR
mov DPH, WORK ;Complete pointer update
inc dptr ;Skip pointer type
mov a, XSP ;Load pointer to task (high)
movx @dptr, a ;Pass it to tcb
inc dptr ;Increment pointer
mov a, XSP+1 ;Load pointer to task (low)
movx @dptr, a ;Pass it to tcb
mov dptr, #OSTCBHighRdy + 1 ;Point to OSTCBHighRdy (skip pointer type)
movx a, @dptr ;Read pointer high
mov WORK, a ;Save it in the work area
inc dptr ;Increment pointer
movx a, @dptr ;Read pointer low
mov WORK+1, a ;Save it in the work area
mov dptr, #OSTCBCur + 1 ;Point to OSTCBCur (skip pointer type)
mov a, WORK ;Load pointer high
movx @dptr, a ;Update tcb
inc dptr ;Increment pointer
mov a, WORK+1 ;Load pointer low
movx @dptr, a ;Update tcb
mov DPL, WORK+1 ;Point to OSTCBHighRdy->STCKPTR
mov DPH, WORK ;Update pointer high
; Now we proceed to restore the task context to run scheduled task.
inc dptr ;Increment pointer to skip pointer type
movx a, @dptr ;Get pointer high
mov WORK, a ;Save in work area
inc dptr ;Increment pointer
movx a, @dptr ;Get pointer low
mov DPL, a ;Update pointer low
mov DPH, WORK ;Load pointer high
movx a, @dptr ;First byte is number of bytes on 'xstack'
mov WORK, a ;Save it in work area
clr c ;Clear carry
mov a, DPL ;Load pointer low
subb a, WORK ;Substract number of bytes from the DPTR
mov DPL, a ;Update pointer low
jnc cs_00 ;If no carry, skip on
dec DPH ;DPTR now points to the base of the task's stack
cs_00: mov R0, #60h ;Hardware stack ('istack' at IRAM), starts at 60h
mov R1, WORK ;Load number of bytes on stack in R1
cs_01: movx a, @dptr ;Get byte from task's external stack
mov @R0, a ;Pass it to internal stack
inc dptr ;Increment source pointer
inc R0 ;Increment destination pointer
djnz R1, cs_01 ;Copy the whole 'xstack' back into 'istack'
mov a, WORK ;Load number of bytes on stack
add a, #5Fh ;Add offset (SP points to a byte)
mov SP, a ;Restore the stack pointer
pop XSP+1 ;Restore the 'xstack' base pointer
pop XSP ;..(high and low)
pop DPL ;Restore pointer low
pop DPH ;Restore pointer high
pop Bk0_r7 ;Restore register R7 (Bank #0)
pop Bk0_r6 ;Restore register R6 (Bank #0)
pop Bk0_r5 ;Restore register R5 (Bank #0)
pop Bk0_r4 ;Restore register R4 (Bank #0)
pop Bk0_r3 ;Restore register R3 (Bank #0)
pop Bk0_r2 ;Restore register R2 (Bank #0)
pop Bk0_r1 ;Restore register R1 (Bank #0)
pop Bk0_r0 ;Restore register R0 (Bank #0)
pop B ;Restore register B
pop ACC ;Restore accumulator
pop PSW ;Restore PSW
setb EA ;Exit critical section
reti ;Jump to execute scheduled task
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -