I have an application using FreeRTOS in an MSP430F5438A that is configured with Code Memory large, data memory model restricted,
and data near as globals.
I am seeing two failures in the application:
- The vApplicationStackOverflowHook is called with pcTaskName IDLE. So supposedly the IDLE task is having an overflow
- At times the MSP430 will end up no where, basically no longer executing the FreeRTOS, with the program counter pointing to 0x4 or some other very high location that is basically illegal
A brief description of my application:
I have a total of 8 user created tasks. These tasks basically process UART, I2C and a few other things. The majority of them
are blocking on queues (one or two are using vTaskDelay to wait a certain amount of time). These queues are being filled from ISRs that
trigger on data from UART and I2C if certain conditions are met. The ISRs don’t call any other functions except xQueueSendFromISR so as to keep the ISRs short.
Here is the main stuff from FreeRTOSConfig.h
#define configUSE_PREEMPTION 0 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( 25000000UL ) #define configLFXT_CLOCK_HZ ( 32768L ) #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 10 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 12 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 10 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 1 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 1 #define configGENERATE_RUN_TIME_STATS 0 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 #ifdef __LARGE_DATA_MODEL__ #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 ) #else #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 480 ) #endif /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Software timer definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( 3 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) /* 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
I first thought that I actually had some ISRs triggering and causing a stack overflow in the IDLE task, but I am not sure this is
the actual cause. I say this because when the failure occurs, the pxCurrentTCB shows that the top of the stack is above the pxStack variable, and the pxStack points to an area of memory with more than 25 bytes of the 0x5A filler, so in fact the conditions for stack overflow don’t seem to be present, and yet I still get an overflow.
In any case, I increased the IDLE task’s stack size by increasing configMINIMAL_STACK_SIZE to 480 as you can see above, although my tasks are not deriving their stack size from this variable otherwise I wouldn’t be able to fit everything. My tasks don’t seem to need more stack.
I’ve added uxEnforaHighWaterMark checks in all my tasks and I never see them drop below 200 or so. I realize its not checking it all the time since I check this after the queue is read. In fact, I created a table with pointers to all the tasks when they’re created and looked at their TCBs.I don’t see any stack overflow conditions.
One suspicious occurrence I see is that I sometimes see the Stack Pointer of the CPU to point at a location above the top of the stack of one task,
but below the pxTask of the next task. This is seen at least in failure #2 above, but maybe also in failure #1.
Any help would be appreciated and if there is a detail missing please let me know.