⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_c.c

📁 ucos-ii在PIC18F4520上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
{
_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 + -