C18 - portRESTORE_CONTEXT - stack underflow

shannon-mc wrote on Wednesday, April 03, 2013:

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	
.......

rtel wrote on Wednesday, April 03, 2013:

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.

shannon-mc wrote on Saturday, April 06, 2013:

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.