Application Overwriting wrong location

anonymous wrote on Thursday, April 19, 2012:

I am using the freeRTOS port on a LPC1763 M3 chip.  Everything was working great until yesterday when I added a new global variable for tracking errors.  I was finding that the errorflags were getting overwritten (with what looks to me to be a memory address).  So I set a breakpoint to fire whenever that location got written to or read from and I found that the line that does it is line 98 in list.c:

      pxIndex = pxList->pxIndex;

I haven’t confirmed this, but it appears to always happen after sending a sempahore from my serial ISR:
xSemaphoreGiveFromISR( pUartCtl_s->xRxDataAvailSema, &xTaskWoken );

This line has been there for months though, and never had a problem until I introduced the new global error flag.  So Im unsure as to how this line could be wrong.  I tried increasing my stacksize, but that didnt seem to help the problem at all.

I know this is not a lot of information, but im confused enough to not know what information would be helpful in this case.  Here are some of my current freertosconfig defines if that helps.

#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 )
#define configUSE_TICK_HOOK 0                   // WAS 1 dks

// FULL_SPEED can be set in Rowley CrossStudio Common Private property “Preprocessor Definitions” under Project Properties.
#define configCPU_CLOCK_HZ          ( ( unsigned long ) 100000000 )
#define configCPU_CLOCK_HZ          ( ( unsigned long ) 72000000 )

#define configTICK_RATE_HZ          ( ( portTickType ) 1000 )

// This next #define sets the default task stack size in 32-bit words
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 )

#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES           1

#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

#define configUSE_COUNTING_SEMAPHORES     0

Thanks for your help!
#define configUSE_ALTERNATIVE_API         0
#define configCHECK_FOR_STACK_OVERFLOW    2
#define configUSE_RECURSIVE_MUTEXES       1
#define configQUEUE_REGISTRY_SIZE         10
#define configGENERATE_RUN_TIME_STATS     0

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet            1
#define INCLUDE_uxTaskPriorityGet           1
#define INCLUDE_vTaskDelete                 1
#define INCLUDE_vTaskCleanUpResources       0
#define INCLUDE_vTaskSuspend                1
#define INCLUDE_vTaskDelayUntil             1
#define INCLUDE_vTaskDelay                  1
#define INCLUDE_uxTaskGetStackHighWaterMark 1

/* Use the system definition, if there is one */
#define configPRIO_BITS       __NVIC_PRIO_BITS
#define configPRIO_BITS       5        /* 32 priority levels */

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) )
/* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) )

/* Priorities passed to NVIC_SetPriority() do not require shifting as the
function does the shifting itself.  Note these priorities need to be equal to
or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric
value needs to be equal to or greater than 5 (on the Cortex-M3 the lower the
numeric value the higher the interrupt priority). */

#define MX_UART_INT_PRIORITY                6
#define TIMER2_INT_PRIORITY                 7
#define TIMER3_INT_PRIORITY                 7

edwards3 wrote on Thursday, April 19, 2012:

The normal first reply is to check for stack overflows (set configCHECK_FOR_STACK_OVERFLOW to 2 and define a stack overflow hook), but you sound experiences so I suspect you have done that already.

As this is a cortex-m chip then the next most likely cause is an incorrect priority in one of your interrupts. Are you 100% sure that all interrupts that call FreeRTOS API functions have a priority that is equal to or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY, and that lower priority means a higher number value? Often people think this is set correctly but because of the nonsense way Cortex defines priorities mistakes can still happen.

Which heap allocation are you using? If it is heap_3 and you are using GCC or a linker script that has the stack and heap grow together, also check your interrupts stack and heap have not clashed.

anonymous wrote on Monday, April 23, 2012:

Thanks for the response.  Ok, so it turned out to be stack overflow.  However, it wasnt in a freertos task stack, rather, it was in my main stack defined by my compiler settings (256 bytes in this case).  Is there a builtin freertos function to monitor this stack along with the task stacks, or is it on the enduser to know the stacks useage?  Thanks.

rtel wrote on Monday, April 23, 2012:

There is no easy way for FreeRTOS to monitor the interrupt stack as the stack used by main() is reused as the interrupt stack, and the size and location of the stack used by main() is not easy to ascertain.  You can normally get the details from linker constants, but not in a portable way.  As you know the linker and linker script you are using you could set something up yourself, but the method used would not then work if somebody were, for example, using a different tool distribution.