I have been somewhat randomly receiving an exception while in vListRemove. Here is my stack list:
vUART2InterruptHandler (this is the ISR)
UartHandler (collectively handles each port)
xQueueGenericSendFromISR (called when I am moving a byte from the uart to the character queue)
The reason for the failure is in vListRemove the following line:
pxList = ( xList * ) pxItemToRemove->pvContainer;
Which is followed by:
if(pxList-pxIndex == pxItemToRemove)…
which throws the actual exception. The reason it throws the exception is that pxItemToRemove->pvContainer equals 0xA5A5A5A5 wwhich indicates crap memory, so when pxList is assigned to this crap memory, it is now crap and the if statement explodes.
Since most of this code is stock, i will only copy over my own ccode to show what I am doing (the UartHandler is modified from the demo)
__declspec(interrupt:0) void vUART2InterruptHandler( void )
UartHandler( serCOM3 );
void UartHandler( eCOMPort ePort)
unsigned portCHAR ucChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, xDoneSomething = pdTRUE;
while( xDoneSomething != pdFALSE )
xDoneSomething = pdFALSE;
/* Does the tx buffer contain space? */
if( ( MCF_UART_USR(ePort) & MCF_UART_USR_TXRDY ) != 0x00 )
/* Are there any characters queued to be sent? */
if( xQueueReceiveFromISR( xCharsForTx[ePort], &ucChar, &xHigherPriorityTaskWoken ) == pdTRUE )
/* Send the next char. */
MCF_UART_UTB(ePort) = ucChar;
xDoneSomething = pdTRUE;
/* Turn off the Tx interrupt until such time as another character
is being transmitted. */
MCF_UART_UIMR(ePort) = serRX_INT;
xTxHasEnded[ePort] = pdTRUE;
if( MCF_UART_USR(ePort) & MCF_UART_USR_RXRDY )
ucChar = MCF_UART_URB(ePort);
xQueueSendFromISR( xRxedChars[ePort], &ucChar, &xHigherPriorityTaskWoken );
xDoneSomething = pdTRUE;
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
This code can be run successfully hundreds of times, but if i sneeze it will fail. That is to say, it could fail if i am streaming messages too quickly, or if i enable or disable a breakpoint in some unrelated code.
What’s going on? I am sure i’m leaving much to be desired in my explanation, so please, ask for any additional info.
oh yeah, it is throwing the following exception:
VECTORDISPLAY("Error on operand readn");
sorry for the messy post, i thought that [code] tags would clean it up…
0xa5a5a5a5 is the value the stack is filled with when the task is created, so this indicates stack pointer corruption.
Does the way your interrupt is coded match the example given in the demo for your port?
Which port are you using? If it supports interrupt nesting, have you got the interrupt priorities set correctly. If you context switch from a priority higher than configMAX_SYSCALL_INTERRUPT_PRIORITY then you will get intermittent failures of this type. configMAX_SYSCALL_INTERRUPT_PRIORITY is not defined for all ports.
Could just be a simple stack problem. Check if any of your tasks are running out of stack.
Thank you for your response. This sounds like it could be very helpful.
The interrupt is set up like this:
MCF_INTC_ICR(MCF_UART_BASE_ICR + ePort) = ( ( configMAX_SYSCALL_INTERRUPT_PRIORITY – 1 ) << 3 );
MCF_INTC_IMRL &= ~( MCF_INTC_IMRL_INT_MASK_UART(ePort)
| MCF_INTC_IMRL_MASKALL );
/* The Tx interrupt is not enabled until there is data to send. */
MCF_UART_UIMR(ePort) = serRX_INT;
Where configMAX_SYSCALL_INTERRUPT_PRIORITY is equal to (4).
That code was modified from the demo xSerialPortInitMinimal and my UartHandler function is modified from the same demo.
I am using (I believe) a MCF5282 port modified to MCF5213. I am not sure what you mean by "is the way that you interrupt is coded match the example given…". Have a look at my first post; i copied the ISR into it near the bottom.
Is there a simple way to see if my tasks are running out of stack?
Thanks a bunch,
See http://www.freertos.org/a00110.html for the setting configCHECK_FOR_STACK_OVERFLOW, and http://www.freertos.org/Stacks-and-stack-overflow-checking.html and http://www.freertos.org/uxTaskGetStackHighWaterMark.html.
Ack – i tried to reply with details by sourceforge forum crapped out on me. I’ll try again…
Dave, Thanks a lot for the suggestions. Here is what I’ve found:
My project was already set up with configCHECK_FOR_STACK_OVERFLOW = 1 so i put a breakpoint in the stack overflow hook. It never triggered. Next, i set the setting to 2 and again it never triggered.
After that I added checking the highwater function to:
1 – my uart handler (this is an interrupt, nto a task, so it threw an exception… oops)
2 – my message handler
3 – my control system
I ran the program and stopped it before there was any com – I was already sitting in the aoverflow hook and all three variables were 0 – this must be the initial value because i had not yet even started the motor control task.
Next, I started it up and it did NOT hit the hook, so instead it crashed when i sent a message because the uart handler is not a task.
Next, i removed the uart handler high water check and found that the program would throw an exception every time that it receieved a message – BUT the msg handler routine is always running and it filled in a 1 in its highwater mark… so i’m guessing that’s a bad thing and the stack needs to be larger.
How can one systematically decide on a stack size for a task?
Okay, i got some valid data on stack sizes. My control system is staying well away from its stack limit, highwater mark is 123 and the stack size is 190. My message handler on the other hand… i increased its size to 290 from 190 and it has a high water mark of 46. Odds are this is what was causing my crashes.
Now… i have been testing it for 10 minutes like this and it has been flawless, but the failures were very random, so i’m not holding my breath that it is fixed.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.