📄 os_cpu_c.c
字号:
* (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);
void CPUhighInterrupt(void);
#pragma code highVector=0x008
void CPUhighVector(void)
{
_asm goto CPUhighInterrupt _endasm
}
#pragma code
void CPUhighInterrupt(void)
{
_asm
BTFSC RCON, 7, 0
goto CPUhighInterruptHook
//goto CPUlowInterrupt
_endasm
if(INTCON3bits.INT1IF) //脉冲接收中断比较频繁
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -