BUGS: FreeRTOS v9.0.0 StaticTask_t size too small with INCLUDE_xTaskAbortDelay or portUSING_MPU_WRAPPERS

Posted by danhepler on September 13, 2016

There are a total of three bugs.

Two bugs are found in StaticTaskt 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 xSTATICTCB { void *pxDummy1; #if ( portUSINGMPUWRAPPERS == 1 ) xMPUSETTINGS xDummy2; #endif StaticListItemt xDummy3[ 2 ]; UBaseTypet uxDummy5; void *pxDummy6; uint8t ucDummy7[ configMAXTASKNAMELEN ]; #if ( portSTACKGROWTH > 0 ) void *pxDummy8; #endif #if ( portCRITICALNESTINGINTCB == 1 ) UBaseTypet uxDummy9; #endif #if ( configUSETRACEFACILITY == 1 ) UBaseTypet uxDummy10[ 2 ]; #endif #if ( configUSEMUTEXES == 1 ) UBaseTypet uxDummy12[ 2 ]; #endif #if ( configUSEAPPLICATIONTASKTAG == 1 ) void *pxDummy14; #endif #if( configNUMTHREADLOCALSTORAGEPOINTERS > 0 ) void *pvDummy15[ configNUMTHREADLOCALSTORAGEPOINTERS ]; #endif #if ( configGENERATERUNTIMESTATS == 1 ) uint32t ulDummy16; #endif #if ( configUSENEWLIBREENTRANT == 1 ) struct _reent xDummy17; #endif #if ( configUSETASKNOTIFICATIONS == 1 ) uint32t ulDummy18; uint8t ucDummy19; #endif #if( ( configSUPPORTSTATICALLOCATION == 1 ) && ( configSUPPORTDYNAMICALLOCATION == 1 ) ) uint8t uxDummy20; #endif

} StaticTask_t; ~~~

  1. StaticTaskt should have the last uxDummy20 conditional compile flag changed to the following to include the ports with portUSINGMPU_WRAPPERS enabled:

~~~ #if( ( ( configSUPPORTSTATICALLOCATION == 1 ) && ( configSUPPORTDYNAMICALLOCATION == 1 ) ) || ( portUSINGMPUWRAPPERS == 1 ) ) uint8_t uxDummy20; #endif ~~~

  1. StaticTaskt should add a missing ucDummy21 to account for ucDelayAborted if INCLUDExTaskAbortDelay is enabled:

~~~ #if( INCLUDExTaskAbortDelay == 1 ) uint8t ucDummy21; #endif ~~~

  1. Additionally, there is a very misleading comment in xTaskCreateStatic() in tasks.c:

~~~ TaskHandlet xTaskCreateStatic( TaskFunctiont pxTaskCode, const char * const pcName, const uint32t ulStackDepth, void * const pvParameters, UBaseTypet uxPriority, StackTypet * const puxStackBuffer, StaticTaskt * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { TCBt *pxNewTCB; TaskHandlet 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(StaticTaskt) == sizeof(TCBt), "StaticTaskt must be same size as TCBt" ); ~~~

Or at least a run-time assert would be OK:

~~~ configASSERT( sizeof(StaticTaskt) == sizeof(TCBt) ); ~~~

Hope this helps someone and can make it into the next rev of FreeRTOS.


BUGS: FreeRTOS v9.0.0 StaticTask_t size too small with INCLUDE_xTaskAbortDelay or portUSING_MPU_WRAPPERS

Posted by rtel on September 14, 2016

Thanks for taking the time to point this out. I have updated the StaticTask_t structure accordingly and will post a 'known issue'.

I will have to check the assert() - there definitely used to be one but the issue was getting it through all the compilers we use without warnings being generated a "condition is always false" warning.


BUGS: FreeRTOS v9.0.0 StaticTask_t size too small with INCLUDE_xTaskAbortDelay or portUSING_MPU_WRAPPERS

Posted by rtel on September 14, 2016

Added in:

~~~

if( configASSERT_DEFINED == 1 )

{ /* Sanity check that the size of the structure used to declare a variable of type StaticTaskt equals the size of the real task structure. */ volatile sizet xSize = sizeof( StaticTask_t ); configASSERT( xSize == sizeof( tskTCB ) ); }

endif /* configASSERT_DEFINED */

~~~

Which is how it was done with the static queue structure.


BUGS: FreeRTOS v9.0.0 StaticTask_t size too small with INCLUDE_xTaskAbortDelay or portUSING_MPU_WRAPPERS

Posted by danhepler on September 14, 2016

No problem, keep up the great work!