📄 os_cpu_c.c
字号:
* - 9 PRODH register
* - 8 AARGB3 memory location
* - 7 AARGB2 memory location
* - 6 AARGB1 memory location
* - 5 AARGB0 memory location
*
* (end repeating, based on number of items)
* - 4 TOSL (top of return stack, low)
* - 3 TOSH (top of return stack, high)
* - 2 TOSU (top of return stack, upper)
* (start repeating, based on number of items)
*
* - 1 (number of return stack items)
*
* OSTCBHighRdy->OSTCBStkPtr - 0 ----> (free item)
* HIGH MEMORY
*
* 2) OSStartHighRdy() MUST:
* a) Call OSTaskSwHook()
* b) Set OSRunning to TRUE
* c) Switch to the highest priority task.
*********************************************************************************************************
*/
void OSStartHighRdy (void)
{
// Call user definable OSTaskSwHook();
OSTaskSwHook();
// Set OSRunning to TRUE
OSRunning = TRUE;
// Get the stack pointer of the task to resume.
// Stack Pointer = OSTCBHighRdy->OSTCBStkPtr;
_asm
MOVFF OSTCBHighRdy, FSR0L // load the STCBHighRdy->OSTCBStkPtr into the free indirect register
MOVFF OSTCBHighRdy+1, FSR0H
MOVFF POSTINC0, FSR1L // copy the variable into the stack pointer
MOVFF POSTDEC0, FSR1H
_endasm
// delete the contents of the hardware return stack - In OSStartHighRdy() ONLY
while(STKPTR & 0x1F)
{
_asm
POP // discard the return address pointer
_endasm
}
if(STKPTR)
STKPTR = 0;
// restore the hardware return stack
_asm
MOVF POSTDEC1, 1, 0 // decrement one to set it on the first item
MOVF POSTDEC1, 0, 0 // number of function pointers in hardware return stack
MOVWF FSR0L, 0 // user FSR0 as a temperary counter
_endasm
do
{
_asm
PUSH // push current address onto hardware stack
MOVF POSTDEC1, 0, 0 // then change to the function pointer in stack
MOVWF TOSU, 0
MOVF POSTDEC1, 0, 0
MOVWF TOSH, 0
MOVF POSTDEC1, 0, 0
MOVWF TOSL, 0
_endasm
} while(--FSR0L); // decrement counter and loop if not finished
// restore all processor registers from the new task's stack:
_asm
MOVFF POSTDEC1, AARGB0
MOVFF POSTDEC1, AARGB1
MOVFF POSTDEC1, AARGB2
MOVFF POSTDEC1, AARGB3
MOVFF POSTDEC1, PRODH
MOVFF POSTDEC1, PRODL
MOVFF POSTDEC1, TBLPTRU
MOVFF POSTDEC1, TBLPTRH
MOVFF POSTDEC1, TBLPTRL
MOVFF POSTDEC1, FSR2H
MOVFF INDF1, FSR2L
MOVF POSTDEC1, 1, 0
MOVFF POSTDEC1, FSR0H
MOVFF POSTDEC1, FSR0L
MOVF POSTDEC1, 0, 0
MOVFF POSTDEC1, BSR
MOVFF POSTDEC1, STATUS
_endasm
// execute a return from interrupt instruction
_asm
RETFIE 0
_endasm
}
/*
*********************************************************************************************************
* TASK LEVEL CONTEXT SWITCH
*
* Description : This function is called when a task makes a higher priority task ready-to-run.
*
* Arguments : none
*
* 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 resume looks as follows:
*
* LOW MEMORY
* - 23 pdata (lower 8 bits)
* - 22 pdata (upper 8 bits)
* - 21 XX (pointed to by FSR1, frame pointer)
* - 20 STATUS register
* - 19 BSR register
* - 18 W register
* - 17 FSR0L register
* - 16 FSR0H register
* - 15 FSR2L register (frame pointer, low)
* - 14 FSR2H register (frame pointer, high)
* - 13 TBLPTRL register
* - 12 TBLPTRH register
* - 11 TBLPTRU register
* - 10 PRODL register
* - 9 PRODH register
* - 8 AARGB3 memory location
* - 7 AARGB2 memory location
* - 6 AARGB1 memory location
* - 5 AARGB0 memory location
*
* (end repeating, based on number of items)
* - 4 TOSL (top of return stack, low)
* - 3 TOSH (top of return stack, high)
* - 2 TOSU (top of return stack, upper)
* (start repeating, based on number of items)
*
* - 1 (number of return stack items)
*
* OSTCBHighRdy->OSTCBStkPtr - 0 ----> (free item)
* HIGH MEMORY
*********************************************************************************************************
*/
//#pragma interrupt OSCtxSw
void OSCtxSw (void)
{
// disable interrupts
INTCON &= (0b00111111 | (RCON & 0b10000000));
// Save processor registers
_asm
MOVFF STATUS, PREINC1
MOVFF BSR, PREINC1
MOVWF PREINC1, 0
MOVFF FSR0L, PREINC1
MOVFF FSR0H, PREINC1
MOVF POSTINC1, 1, 0
MOVFF FSR2L, POSTINC1
MOVFF FSR2H, POSTINC1
MOVFF TBLPTRL,POSTINC1
MOVFF TBLPTRH,POSTINC1
MOVFF TBLPTRU,POSTINC1
MOVFF PRODL, POSTINC1
MOVFF PRODH, POSTINC1
MOVFF AARGB3, POSTINC1
MOVFF AARGB2, POSTINC1
MOVFF AARGB1, POSTINC1
MOVFF AARGB0, POSTINC1
_endasm
// Save the current task's return address hardware stack
FSR0L = 0;
while(STKPTR & 0x1F)
{
_asm
MOVFF TOSL, POSTINC1 // copy the return address pointer
MOVFF TOSH, POSTINC1 // to the end of the software stack.
MOVFF TOSU, POSTINC1
POP // discard the top stack item that we just copied
_endasm
FSR0L++;
}
_asm
MOVFF FSR0L, POSTINC1 // copy the count to the last item in the software stack
_endasm
if(STKPTR)
STKPTR = 0;
// Save the current task's stack pointer into the current task's OS_TCB:
// OSTCBCur->OSTCBStkPtr = Stack Pointer;
_asm
MOVFF OSTCBCur, FSR0L // load the OSTCBCur->OSTCBStkPtr into the free indirect register
MOVFF OSTCBCur+1, FSR0H
MOVFF FSR1L, POSTINC0 // copy the stack pointer into the variable
MOVFF FSR1H, POSTDEC0
_endasm
// Call OSTaskSwHook()
OSTaskSwHook();
// re-arrange the pointers
OSTCBCur = OSTCBHighRdy;
OSPrioCur = OSPrioHighRdy;
// Get the stack pointer of the task to resume.
// Stack Pointer = OSTCBHighRdy->OSTCBStkPtr;
_asm
MOVFF OSTCBHighRdy, FSR0L // load the STCBHighRdy->OSTCBStkPtr into the free indirect register
MOVFF OSTCBHighRdy+1, FSR0H
MOVFF POSTINC0, FSR1L // copy the variable into the stack pointer
MOVFF POSTDEC0, FSR1H
_endasm
// restore the hardware return stack
_asm
MOVF POSTDEC1, 1, 0 // decrement stack pointer one to set it on the first item
MOVF POSTDEC1, 0, 0 // number of function pointers in hardware return stack
MOVWF FSR0L, 0 // user FSR0 as a temperary counter
_endasm
do
{
_asm
PUSH // push current address onto hardware stack
MOVF POSTDEC1, 0, 0 // then change to the function pointer in stack
MOVWF TOSU, 0
MOVF POSTDEC1, 0, 0
MOVWF TOSH, 0
MOVF POSTDEC1, 0, 0
MOVWF TOSL, 0
_endasm
} while(--FSR0L); // decrement counter and loop if not finished
// restore all processor registers from the new task's stack:
_asm
MOVFF POSTDEC1, AARGB0
MOVFF POSTDEC1, AARGB1
MOVFF POSTDEC1, AARGB2
MOVFF POSTDEC1, AARGB3
MOVFF POSTDEC1, PRODH
MOVFF POSTDEC1, PRODL
MOVFF POSTDEC1, TBLPTRU
MOVFF POSTDEC1, TBLPTRH
MOVFF POSTDEC1, TBLPTRL
MOVFF POSTDEC1, FSR2H
MOVFF INDF1, FSR2L
MOVF POSTDEC1, 1, 0
MOVFF POSTDEC1, FSR0H
MOVFF POSTDEC1, FSR0L
MOVF POSTDEC1, 0, 0
MOVFF POSTDEC1, BSR
MOVFF POSTDEC1, STATUS
_endasm
// execute a return from interrupt instruction
_asm
RETFIE 0
_endasm
}
/*
*********************************************************************************************************
* TICK ISR
*
* Notes: 1) Your ISR MUST be added into the CPUInterruptHook()
*
* setup the timer with the following instructions.
* T1CON = 0x0F;
* or
* movlw 0x0F
* movwf T1CON
*********************************************************************************************************
*/
void CPUhighVector(void);
void CPUlowVector(void);
void CPUlowInterrupt(void);
#pragma code highVector=0x008
void CPUhighVector(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -