There are a total of three bugs.
Two bugs are found in StaticTask
t which are evident comparing the definition of StaticTaskt in FreeRTOS.h and TCB_t in task.c. This causes a false stack overflow failure because the stack overflow check fails on the first byte (ucDelayAborted is written as pdFALSE or pdTRUE). These may also cause weird behaviour with xTaskAbortDelayalthough I have not verified this.
~~~
typedef struct xSTATIC
TCB
{
void *pxDummy1;
#if ( portUSINGMPU
WRAPPERS == 1 )
xMPUSETTINGS xDummy2;
#endif
StaticListItem
t xDummy3[ 2 ];
UBaseTypet uxDummy5;
void *pxDummy6;
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
#if ( portSTACK_GROWTH > 0 )
void *pxDummy8;
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxDummy9;
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxDummy10[ 2 ];
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxDummy12[ 2 ];
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
void *pxDummy14;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulDummy16;
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xDummy17;
#endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t ulDummy18;
uint8_t ucDummy19;
#endif
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
uint8_t uxDummy20;
#endif
} StaticTask_t;
~~~
- StaticTaskt should have the last uxDummy20 conditional compile flag changed to the following to include the ports with portUSINGMPU_WRAPPERS enabled:
~~~
#if( ( ( configSUPPORT
STATICALLOCATION == 1 ) && ( configSUPPORT
DYNAMICALLOCATION == 1 ) ) || ( portUSING
MPUWRAPPERS == 1 ) )
uint8_t uxDummy20;
#endif
~~~
- StaticTaskt should add a missing ucDummy21 to account for ucDelayAborted if INCLUDExTaskAbortDelay is enabled:
~~~
#if( INCLUDE
xTaskAbortDelay == 1 )
uint8t ucDummy21;
#endif
~~~
- Additionally, there is a very misleading comment in xTaskCreateStatic() in tasks.c:
~~~
TaskHandle
t xTaskCreateStatic( TaskFunctiont pxTaskCode,
const char * const pcName,
const uint32
t ulStackDepth,
void * const pvParameters,
UBaseTypet uxPriority,
StackType
t * const puxStackBuffer,
StaticTaskt * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
TCB_t *pxNewTCB;
TaskHandle_t xReturn;
configASSERT( puxStackBuffer != NULL );
configASSERT( pxTaskBuffer != NULL );
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
{
/* The memory used for the task's TCB and stack are passed into this
function - use them. */
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
~~~
The size most certainly is NOT checked by an assert. A compile-time assert is preferable:
~~~
Staticassert( sizeof(StaticTask
t) == sizeof(TCBt), “StaticTask
t must be same size as TCBt” );
~~~
Or at least a run-time assert would be OK:
~~~
configASSERT( sizeof(StaticTask
t) == sizeof(TCBt) );
~~~
Hope this helps someone and can make it into the next rev of FreeRTOS.