📄 os_cpu_c.c
字号:
{
INTCON3bits.INT1IF = 0;
}
else if(INTCON3bits.INT2IF)
{
INTCON3bits.INT2IF = 0;
}
else
{
_asm
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 + -