Hard Fault within vPortYield

pcalton wrote on Friday, June 21, 2013:

I am attempting to build a FreeRTOS project on an LPC4357 (M4 core) that includes a task running emWin.

The emWin code runs fine in a standalone environment, but when I place it within a task it will run for a few minutes and then hard fault.

emWin is configured to be called from only one task and the only difference between the two emWin ports is that FreeRTOS provides the timing (i.e. GUI_X_Delay calls vTaskDelay instead of using the system timer to increment a counter and looping on that counter to reach a timeout value as in the standalone version).

The emWin task is the only task running.

I am using Atollic TrueSTUDIO which includes a tool to take you directly to the source of a hard fault. This always takes me to the call to DSB within vPortYield when the fault occurs.

void vPortYield( void )
/* Set a PendSV to request a context switch. */

/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__asm volatile( “dsb” );
__asm volatile( “isb” );

Any ideas what might be the cause?

edwards3 wrote on Friday, June 21, 2013:

I don’t know emwin at all, but the first place to look is always stack overflow. I expect graphics takes a lot of stack. Do you have stack overflow checking switched on? The auto stack checking will only check the task stack, so also manually check the interrupt stack (which is the stack configured in the linker and used by main()).

A long shot, but I think portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT will fault if it is called from unprivileged code. Could it be that your application or emwin is switching out of privileged mode?

pcalton wrote on Friday, June 21, 2013:

I had some task stack issues when I first started the migration into FreeRTOS, but the task is now provided with ample stack (1024 words) and I am monitoring how much of that is used. The lowest Ive seen it get still left it with 1400+ words available.

Following your suggestions, I tried making the interrupt stack larger and monitoring how much of that is used. Again, the stack high water mark is well within its bounds.

Finally, the processor remains in privileged mode, so the portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT line should be ok.

The fact that the code runs fine for a while (5 minutes at times) without issue makes me think that it faults when the vPortYield coincides with something else.

There is only one task, so I would have thought the only asynchronous code would be the SystemTick interrupt for the scheduler, a UART interrupt for my debug printf and the LCD interrupt.

Once the system is running, the only printf used is in the hardfault handler.
The LCD interrupt changes the frame buffer base address to show the most recently rendered screen

void LCD_IRQHandler(void)
unsigned long Addr, BufferSize;
//Check of base update interrupt
if ((LPC_LCD ->INTSTAT) & (1 << 2))
if (_PendingBuffer >= 0)
// Calculate address of the given buffer
Addr = VRAM_ADDR + BufferSize * _PendingBuffer;
// Make the given buffer visible
// Send a confirmation that the buffer is visible now
_PendingBuffer = -1;
LPC_LCD ->INTCLR |= 1 << 2;

pcalton wrote on Friday, June 21, 2013:

Some more information. The hard fault type is “Invalid EXC_RETURN value (INVPC)”. The value in the link register is 0xFFFFFFFD.

pcalton wrote on Tuesday, June 25, 2013:

Is anyone able to help me understand what might be happening here? I have found that disabling the LCD interrupt stops the faults from occurring, so I imagine that it is some interaction between the LCD interrupt and the SVC calls, but I dont understand what might be the source

rtel wrote on Tuesday, June 25, 2013:

Your ISR code is not using any FreeRTOS functions, so it should be possible to run it at any priority.

Do you know what GUI_MULTIBUF_Confirm() is doing internally?


pcalton wrote on Tuesday, June 25, 2013:

Hi Richard,

The function is part of a pre-compiled library to which we do not have the source. The application uses triple buffering. A front buffer that the LCD driver is currently using. A pending buffer which has been rendered and is ready to become the front buffer and a third buffer that is used for rendering the next update.

I imagine that this function is letting the library know that the pending buffer is now the front buffer and the previous front buffer is now free, but all I know for certain is what the documentation tells me:

This function needs to be called immediately after a new buffer has become visible.
void GUI_MULTIBUF_Confirm(int Index);
Additional information
The function is typically called by the ISR which switches to the new front buffer or
by the display driver callback function.