C18 – portRESTORE_CONTEXT – stack underflow

MPLab IDE v8.88
mpasmwin.exe v5.42
mplink.exe v4.40
mcc18.exe v3.40
mplib.exe v4.40 MPLAB SIM:
PIC18F4553 When running some fairly simple code to implement a low frequency PWM I’m seeing a stack underflow error on the second execution of a DelayTaskUntil function. Using the MPLab simulator I’ve been able to trace it as far as is described below.  I’m stuck trying to understanding why the program counter is jumping in the middle of executing the  function portRESTORE_CONTEXT?  I can’t imagine its possible to change the program counter within a MOVFF instruction? I would appreciate if anyone could help understand what could cause the jump and how I might go about finding the exact problem.
vTaskDelayUntil calls portYIELD_WITHIN_API calls portRESTORE_CONTEXT
On attempting to restore the eight byte of the ".tmpdata and MATH_DATA memory " with the instruction in Program memory as:
6041    2F30    CFE5            MOVFF POSTDEC1, POSTDEC0
6042    2F32    FFED            NOP
An error occurs:
>>>  CORE-W0015: Out of bounds Memory Access (at address 0x089966 on 0x000002 bytes)
The program counter then jumps to program address: 196C and the instructions is:
3255    196C    C010            MOVFF __tmp_0, PRODL
3256    196E    FFF3            NOP
the program then conintues on (presumably processing rubish) until it reaches the next return call and fails at address 198A.
3270    198A    0012            RETURN 0
>>>  CORE-E0002: Stack under flow error occurred from instruction at 0x00198a





#define portRESTORE_CONTEXT()                                               {                                                           
    _asm                                                        
        /* Set FSR0 to point to pxCurrentTCB->pxTopOfStack. */
        MOVFF   pxCurrentTCB, FSR0L
        MOVFF   pxCurrentTCB + 1, FSR0H 
        /* De-reference FSR0 to set the address it holds into FSR1.
        (i.e. *( pxCurrentTCB->pxTopOfStack ) ). */
        MOVFF   POSTINC0, FSR1L
        MOVFF   POSTINC0, FSR1H
        /* How many return addresses are there on the hardware stack?  Discard
        the first byte as we are pointing to the next free space. */
        MOVFF   POSTDEC1, FSR0L 
        MOVFF   POSTDEC1, FSR0L                                         
    _endasm                                                     
    /* Fill the hardware stack from our software stack. */  
    STKPTR = 0;                                                 
    while( STKPTR < FSR0L ) 
    {       
        _asm
            PUSH
            MOVF    POSTDEC1, 0, 0
            MOVWF   TOSU, 0 
            MOVF    POSTDEC1, 0, 0
            MOVWF   TOSH, 0 
            MOVF    POSTDEC1, 0, 0
            MOVWF   TOSL, 0 
        _endasm 
    }
    _asm
        /* Restore the .tmpdata and MATH_DATA memory. */
        MOVFF   POSTDEC1, FSR0H
        MOVFF   POSTDEC1, FSR0L
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0  <<<< Here the error starts
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, POSTDEC0
        MOVFF   POSTDEC1, INDF0 
        /* Restore the other registers forming the tasks context. */
        MOVFF   POSTDEC1, PCLATH
        MOVFF   POSTDEC1, PCLATU
        MOVFF   POSTDEC1, PRODL 
        MOVFF   POSTDEC1, PRODH 
        MOVFF   POSTDEC1, TBLPTRL
        MOVFF   POSTDEC1, TBLPTRH
        MOVFF   POSTDEC1, TBLPTRU
        MOVFF   POSTDEC1, TABLAT
        MOVFF   POSTDEC1, FSR0H 
        MOVFF   POSTDEC1, FSR0L 
        MOVFF   POSTDEC1, FSR2H 
        MOVFF   POSTDEC1, FSR2L 
        MOVFF   POSTDEC1, BSR   
        /* The next byte is the INTCON register.  Read this into WREG as some
        manipulation is required. */
        MOVFF   POSTDEC1, WREG
    _endasm 
.......

C18 – portRESTORE_CONTEXT – stack underflow

As mentioned on the website, the PIC18 is not an ideal target to run an RTOS, and the C18 compiler is not itself reentrant, so the support I can give is limited.  There are a few things to note however: - Have you set portCOMPILER_MANAGED_MEMORY_SIZE as described in the “memory areas used by the compiler” section of the following page: http://www.freertos.org/a00097.html ? - Have you set up the linker script as described in the “linker scripts” section of the same page? Regards.

C18 – portRESTORE_CONTEXT – stack underflow

Thanks for the tips, I’d already made some changes for the memory area but hadn’t looked too closely at linker scripts.   After implementing John’s suggestions I’ve been able to fix the stack underflow error. Thanks again.