Merge branch 'feature/freertos_untested_feature_assert' into 'master'

Assert on untested FreeRTOS features

When I SMP-enabled, I went through all the functions and made the necessary modifiucations. I however only managed to test the most used functions thoroughly. While we should test all FreeRTOS functions eventually, this MR will mark the ones we have not tested yet with a macro call that will, if enabled in MenuConfig (default enabled) assert() when the untested function is called.

Also removes some superfluous mux initializion code in EventGroups code.

See merge request !120
This commit is contained in:
Jeroen Domburg 2016-09-29 09:55:06 +08:00
commit 60a6467663
6 changed files with 44 additions and 17 deletions

View file

@ -44,6 +44,14 @@ config FREERTOS_HZ
help
Select the tick rate at which FreeRTOS does pre-emptive context switching.
config FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
bool "Halt when an SMP-untested function is called"
default y
help
Some functions in FreeRTOS have not been thoroughly tested yet when moving to
the SMP implementation of FreeRTOS. When this option is enabled, these fuctions
will throw an assert().
choice FREERTOS_CHECK_STACKOVERFLOW
prompt "Check for stack overflow"
default FREERTOS_CHECK_STACKOVERFLOW_QUICK

View file

@ -143,6 +143,7 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
BaseType_t xReturn;
CRCB_t *pxCoRoutine;
UNTESTED_FUNCTION(); //Actually, coroutines are entirely unsupported
/* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
if( pxCoRoutine )

View file

@ -124,7 +124,6 @@ typedef struct xEventGroupDefinition
/* Again: one mux for all events. Maybe this can be made more granular. ToDo: look into that. -JD */
static portMUX_TYPE xEventGroupMux = portMUX_INITIALIZER_UNLOCKED;
static BaseType_t xMuxInitialized = pdFALSE;
/*-----------------------------------------------------------*/
@ -145,12 +144,6 @@ EventGroupHandle_t xEventGroupCreate( void )
{
EventGroup_t *pxEventBits;
//Initialize mux, if needed
if ( xMuxInitialized == pdFALSE ) {
vPortCPUInitializeMutex( & xEventGroupMux );
xMuxInitialized = pdTRUE;
}
pxEventBits = pvPortMalloc( sizeof( EventGroup_t ) );
if( pxEventBits != NULL )
{

View file

@ -124,6 +124,16 @@
abort(); \
}
#endif
#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
#include <stdlib.h>
#include "rom/ets_sys.h"
#define UNTESTED_FUNCTION() { ets_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
#else
#define UNTESTED_FUNCTION()
#endif
#endif /* def __ASSEMBLER__ */
@ -263,5 +273,7 @@
#define configXT_SIMULATOR 0
#endif /* FREERTOS_CONFIG_H */

View file

@ -888,7 +888,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
ets_printf("Not Supported: %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
for( ;; )
{
taskENTER_CRITICAL();
@ -1903,6 +1903,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
BaseType_t xReturn;
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
UNTESTED_FUNCTION();
/* If the queue is already full we may have to block. A critical section
is required to prevent an interrupt removing something from the queue
between the check to see if the queue is full and blocking on the queue. */
@ -2176,7 +2177,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
UBaseType_t ux;
UNTESTED_FUNCTION();
/* See if there is an empty space in the registry. A NULL name denotes
a free slot. */
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )

View file

@ -129,6 +129,9 @@ functions but without including stdio.h here. */
} while(0)
#endif
/* Value that can be assigned to the eNotifyState member of the TCB. */
typedef enum
{
@ -584,7 +587,6 @@ BaseType_t xReturn;
TCB_t * pxNewTCB;
StackType_t *pxTopOfStack;
BaseType_t i;
configASSERT( pxTaskCode );
configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) );
configASSERT( (xCoreID>=0 && xCoreID<portNUM_PROCESSORS) || (xCoreID==tskNO_AFFINITY) );
@ -859,7 +861,7 @@ BaseType_t i;
TickType_t xTimeToWake;
BaseType_t xAlreadyYielded=pdFALSE, xShouldDelay = pdFALSE;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
configASSERT( pxPreviousWakeTime );
configASSERT( ( xTimeIncrement > 0U ) );
configASSERT( uxSchedulerSuspended[ xPortGetCoreID() ] == 0 );
@ -1029,7 +1031,7 @@ BaseType_t i;
List_t *pxStateList;
const TCB_t * const pxTCB = ( TCB_t * ) xTask;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
configASSERT( pxTCB );
if( pxTCB == pxCurrentTCB[ xPortGetCoreID() ] )
@ -1099,7 +1101,7 @@ BaseType_t i;
TCB_t *pxTCB;
UBaseType_t uxReturn;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
taskENTER_CRITICAL(&xTaskQueueMutex);
{
/* If null is passed in here then we are changing the
@ -1307,7 +1309,7 @@ BaseType_t i;
{
TCB_t *pxTCB;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
taskENTER_CRITICAL(&xTaskQueueMutex);
{
/* If null is passed in here then it is the running task that is
@ -1448,7 +1450,7 @@ BaseType_t i;
{
TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
/* It does not make sense to resume the calling task. */
configASSERT( xTaskToResume );
@ -1850,7 +1852,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void )
{
UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
vTaskSuspendAll(); //WARNING: This only suspends one CPU. ToDo: suspend others as well. Mux using taskQueueMutex maybe?
{
/* Is there a space in the array for each task in the system? */
@ -3136,7 +3138,7 @@ UBaseType_t x;
{
TCB_t *pxTCB;
ets_printf("ToDo %s\n", __FUNCTION__);
UNTESTED_FUNCTION();
/* If null is passed in here then we are deleting ourselves. */
pxTCB = prvGetTCBFromHandle( xTaskToModify );
@ -3344,6 +3346,7 @@ TCB_t *pxNewTCB;
volatile TCB_t *pxNextTCB, *pxFirstTCB;
UBaseType_t uxTask = 0;
UNTESTED_FUNCTION();
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
{
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
@ -3450,6 +3453,7 @@ TCB_t *pxNewTCB;
uint8_t *pucEndOfStack;
UBaseType_t uxReturn;
UNTESTED_FUNCTION();
pxTCB = prvGetTCBFromHandle( xTask );
#if portSTACK_GROWTH < 0
@ -3881,6 +3885,7 @@ scheduler will re-enable the interrupts instead. */
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
char cStatus;
UNTESTED_FUNCTION();
/*
* PLEASE NOTE:
@ -3974,6 +3979,7 @@ scheduler will re-enable the interrupts instead. */
volatile UBaseType_t uxArraySize, x;
uint32_t ulTotalTime, ulStatsAsPercentage;
UNTESTED_FUNCTION();
#if( configUSE_TRACE_FACILITY != 1 )
{
#error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
@ -4131,6 +4137,7 @@ TickType_t uxReturn;
TickType_t xTimeToWake;
uint32_t ulReturn;
UNTESTED_FUNCTION();
taskENTER_CRITICAL(&xTaskQueueMutex);
{
/* Only block if the notification count is not already non-zero. */
@ -4241,6 +4248,7 @@ TickType_t uxReturn;
TickType_t xTimeToWake;
BaseType_t xReturn;
UNTESTED_FUNCTION();
taskENTER_CRITICAL(&xTaskQueueMutex);
{
/* Only block if a notification is not already pending. */
@ -4363,6 +4371,7 @@ TickType_t uxReturn;
eNotifyValue eOriginalNotifyState;
BaseType_t xReturn = pdPASS;
UNTESTED_FUNCTION();
configASSERT( xTaskToNotify );
pxTCB = ( TCB_t * ) xTaskToNotify;
@ -4447,6 +4456,7 @@ TickType_t uxReturn;
eNotifyValue eOriginalNotifyState;
BaseType_t xReturn = pdPASS;
UNTESTED_FUNCTION();
configASSERT( xTaskToNotify );
pxTCB = ( TCB_t * ) xTaskToNotify;
@ -4540,6 +4550,7 @@ TickType_t uxReturn;
TCB_t * pxTCB;
eNotifyValue eOriginalNotifyState;
UNTESTED_FUNCTION();
configASSERT( xTaskToNotify );