📄 os_cpu_c.c
字号:
{
_asm
BTFSC RCON, 7, 0
goto CPUhighInterruptHook
goto CPUlowInterrupt
_endasm
}
#pragma code lowVector=0x018
void CPUlowVector(void)
{
_asm goto CPUlowInterrupt _endasm
}
#pragma code
void CPUlowInterrupt(void)
{
// 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
// Notify kernel about interrupt by incrementing OSIntNesting or by calling OSIntEnter()
OSIntNesting++;
//OSIntEnter();
// Call the user defined interrupt hook.
CPUlowInterruptHook();
// Call OSIntExit() to determine what task to switch to.
OSIntExit();
_asm
MOVF POSTDEC1, 1, 0 // decrement stack pointer one to set it on the first item
_endasm
// 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
}
/*
*********************************************************************************************************
* PERFORM A CONTEXT SWITCH (From an ISR)
*
* Description : This function is called when an ISR 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 suspend looks as follows.
*
* LOW MEMORY
* - 19 pdata (lower 8 bits)
* - 18 pdata (upper 8 bits)
* - 17 XX (pointed to by FSR1, frame pointer)
* - 16 STATUS register
* - 15 BSR register
* - 14 W register
* - 13 FSR0L register
* - 12 FSR0H register
* - 11 FSR2L register (frame pointer, low)
* - 10 FSR2H register (frame pointer, high)
* - 9 TBLPTRL register
* - 8 TBLPTRH register
* - 7 TBLPTRU register
* - 6 PRODL register
* - 5 PRODH register
* - 4 AARGB3 memory location
* - 3 AARGB2 memory location
* - 2 AARGB1 memory location
* - 1 AARGB0 memory location
*
* OSTCBCur->OSTCBStkPtr - 0 ----> (free item
*
* 3) The following itms need to be placed on to the stack.
* The function return stack holds two extra items that need
* to be removed before saving, OSIntExit() and OSIntCtxSw().
*
* (end repeating, based on number of items)
* + 0 TOSL (top of return stack, low)
* + 1 TOSH (top of return stack, high)
* + 2 TOSU (top of return stack, upper)
* (start repeating, based on number of items)
*
* + 3 (number of return stack items)
*
* OSTCBCur->OSTCBStkPtr + 4 ----> (free item)
* HIGH MEMORY
*
* 3) 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
*********************************************************************************************************
*/
void OSIntCtxSw (void)
{
// Remove the two extra return items, OSIntExit() and OSIntCtxSw().
_asm
POP
POP
_endasm
#if OS_CRITICAL_METHOD == 3 /* De-Allocate storage for CPU status register */
_asm
MOVF POSTDEC1, 1, 0
MOVF POSTDEC1, 1, 0
MOVF POSTDEC1, 1, 0
_endasm
#endif
// 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
// 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 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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -