From f34b2bbcceee29c29778b30aef82282583271180 Mon Sep 17 00:00:00 2001 From: rtel Date: Sun, 24 Nov 2013 10:11:16 +0000 Subject: [PATCH] Add additional asserts() to ensure certain operations are not performed when the scheduler is suspended. Change the xBlockTime variables in event_groups.c/h to xTicksToWait to match the naming in other core FreeRTOS files. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2116 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Source/event_groups.c | 36 +++++++++++++++++--------- FreeRTOS/Source/include/event_groups.h | 22 ++++++++-------- FreeRTOS/Source/include/task.h | 17 +++++++----- FreeRTOS/Source/queue.c | 13 +++++++++- FreeRTOS/Source/tasks.c | 5 ++++ 5 files changed, 62 insertions(+), 31 deletions(-) diff --git a/FreeRTOS/Source/event_groups.c b/FreeRTOS/Source/event_groups.c index a49d0a1f6..09ddbee54 100644 --- a/FreeRTOS/Source/event_groups.c +++ b/FreeRTOS/Source/event_groups.c @@ -134,12 +134,18 @@ xEVENT_BITS *pxEventBits; } /*-----------------------------------------------------------*/ -xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, portTickType xBlockTime ) +xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, portTickType xTicksToWait ) { xEventBitsType uxOriginalBitValue, uxReturn; xEVENT_BITS *pxEventBits = ( xEVENT_BITS * ) xEventGroup; portBASE_TYPE xYieldedAlready; + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + vTaskSuspendAll(); { uxOriginalBitValue = pxEventBits->uxEventBits; @@ -156,16 +162,16 @@ portBASE_TYPE xYieldedAlready; already unless this is the only task in the rendezvous. */ pxEventBits->uxEventBits &= uxBitsToWaitFor; - xBlockTime = 0; + xTicksToWait = 0; } else { - if( xBlockTime != ( portTickType ) 0 ) + if( xTicksToWait != ( portTickType ) 0 ) { /* Store the bits that the calling task is waiting for in the task's event list item so the kernel knows when a match is found. Then enter the blocked state. */ - vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | taskCLEAR_EVENTS_ON_EXIT_BIT | taskWAIT_FOR_ALL_BITS ), xBlockTime ); + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | taskCLEAR_EVENTS_ON_EXIT_BIT | taskWAIT_FOR_ALL_BITS ), xTicksToWait ); } else { @@ -177,7 +183,7 @@ portBASE_TYPE xYieldedAlready; } xYieldedAlready = xTaskResumeAll(); - if( xBlockTime != ( portTickType ) 0 ) + if( xTicksToWait != ( portTickType ) 0 ) { if( xYieldedAlready == pdFALSE ) { @@ -207,7 +213,7 @@ portBASE_TYPE xYieldedAlready; } /*-----------------------------------------------------------*/ -xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, portTickType xBlockTime ) +xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, portTickType xTicksToWait ) { xEVENT_BITS *pxEventBits = ( xEVENT_BITS * ) xEventGroup; const xEventBitsType uxCurrentEventBits = pxEventBits->uxEventBits; @@ -217,6 +223,11 @@ xEventBitsType uxReturn, uxControlBits = 0; itself, and that at least one bit is being requested. */ configASSERT( ( uxBitsToWaitFor & taskEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif taskENTER_CRITICAL(); { @@ -227,7 +238,7 @@ xEventBitsType uxReturn, uxControlBits = 0; if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( xEventBitsType ) 0 ) { /* At least one of the bits was set. No need to block. */ - xBlockTime = 0; + xTicksToWait = 0; } } else @@ -237,13 +248,13 @@ xEventBitsType uxReturn, uxControlBits = 0; if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) { /* All the bits were set, no need to block. */ - xBlockTime = 0; + xTicksToWait = 0; } } /* The task can return now if either its wait condition is already met or the requested block time is 0. */ - if( xBlockTime == ( portTickType ) 0 ) + if( xTicksToWait == ( portTickType ) 0 ) { /* No need to block, just set the return value. */ uxReturn = uxCurrentEventBits; @@ -274,13 +285,13 @@ xEventBitsType uxReturn, uxControlBits = 0; /* Store the bits that the calling task is waiting for in the task's event list item so the kernel knows when a match is found. Then enter the blocked state. */ - vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xBlockTime ); + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); portYIELD_WITHIN_API(); } } taskEXIT_CRITICAL(); - if( xBlockTime != ( portTickType ) 0 ) + if( xTicksToWait != ( portTickType ) 0 ) { /* The task blocked to wait for its required bits to be set - at this point either the required bits were set or the block time expired. If @@ -345,9 +356,10 @@ portBASE_TYPE xMatchFound = pdFALSE; pxList = &( pxEventBits->xTasksWaitingForBits ); pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ - pxListItem = listGET_HEAD_ENTRY( pxList ); vTaskSuspendAll(); { + pxListItem = listGET_HEAD_ENTRY( pxList ); + /* Set the bits. */ pxEventBits->uxEventBits |= uxBitsToSet; diff --git a/FreeRTOS/Source/include/event_groups.h b/FreeRTOS/Source/include/event_groups.h index 36a4c85b3..3ca5ac3f5 100644 --- a/FreeRTOS/Source/include/event_groups.h +++ b/FreeRTOS/Source/include/event_groups.h @@ -168,7 +168,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, - portTickType xBlockTime ); + portTickType xTicksToWait ); * * [Potentially] block to wait for one or more bits to be set within a @@ -197,7 +197,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set * in uxBitsToWaitFor is set or the specified block time expires. * - * @param xBlockTime The maximum amount of time (specified in 'ticks') to wait + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait * for one/all (depending on the xWaitForAllBits value) of the bits specified by * uxBitsToWaitFor to become set. * @@ -217,7 +217,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; void aFunction( xEventGroupHandle xEventGroup ) { xEventBitsType uxBits; - const portTickType xBlockTime = 100 / portTICK_RATE_MS; + const portTickType xTicksToWait = 100 / portTICK_RATE_MS; // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within // the event group. Clear the bits before exiting. @@ -226,7 +226,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; BIT_0 | BIT_4, // The bits within the event group to wait for. pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. pdFALSE, // Don't wait for both bits, either bit will do. - xBlockTime ); // Wait a maximum of 100ms for either bit to be set. + xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) { @@ -242,7 +242,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; } else { - // xEventGroupWaitBits() returned because xBlockTime ticks passed + // xEventGroupWaitBits() returned because xTicksToWait ticks passed // without either BIT_0 or BIT_4 becoming set. } } @@ -250,7 +250,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION; * \defgroup xEventGroupWaitBits xEventGroupWaitBits * \ingroup EventGroup */ -xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, portTickType xBlockTime ) PRIVILEGED_FUNCTION; +xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; /** * event_groups.h @@ -459,7 +459,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, - portTickType xBlockTime ); + portTickType xTicksToWait ); * * Atomically set bits within an event group, then wait for a combination of @@ -487,7 +487,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set * uxBitsToWaitFor to 0x07. Etc. * - * @param xBlockTime The maximum amount of time (specified in 'ticks') to wait + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait * for all of the bits specified by uxBitsToWaitFor to become set. * * @return The value of the event group at the time either the bits being waited @@ -514,7 +514,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType void vTask0( void *pvParameters ) { xEventBitsType uxReturn; - portTickType xBlockTime = 100 / portTICK_RATE_MS; + portTickType xTicksToWait = 100 / portTICK_RATE_MS; for( ;; ) { @@ -525,7 +525,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType // by ALL_SYNC_BITS. All three tasks have reached the synchronisation // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms // for this to happen. - uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xBlockTime ); + uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) { @@ -577,7 +577,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType * \defgroup xEventGroupSync xEventGroupSync * \ingroup EventGroup */ -xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, portTickType xBlockTime ) PRIVILEGED_FUNCTION; +xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; /** diff --git a/FreeRTOS/Source/include/task.h b/FreeRTOS/Source/include/task.h index d7330a974..d71d5145e 100644 --- a/FreeRTOS/Source/include/task.h +++ b/FreeRTOS/Source/include/task.h @@ -226,10 +226,13 @@ typedef enum */ #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() -/* Definitions returned by xTaskGetSchedulerState(). */ -#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 0 ) -#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 1 ) -#define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 2 ) +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 1 ) +#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 2 ) + /*----------------------------------------------------------- * TASK CREATION API @@ -1378,7 +1381,7 @@ portBASE_TYPE xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; * there be no higher priority tasks waiting on the same event) or * the delay period expires. * - * The 'unordered' version replaces the event list item value with the + * The 'unordered' version replaces the event list item value with the * xItemValue value, and inserts the list item at the end of the list. * * The 'ordered' version uses the existing event list item value (which is the @@ -1423,8 +1426,8 @@ void vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xT * Removes a task from both the specified event list and the list of blocked * tasks, and places it on a ready queue. * - * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called - * if either an event occurs to unblock a task, or the block timeout period + * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period * expires. * * xTaskRemoveFromEventList() is used when the event list is in task priority diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c index a94b03ed8..023aa4124 100644 --- a/FreeRTOS/Source/queue.c +++ b/FreeRTOS/Source/queue.c @@ -570,6 +570,12 @@ xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + /* This function relaxes the coding standard somewhat to allow return statements within the function itself. This is done in the interest @@ -1052,7 +1058,12 @@ xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + /* This function relaxes the coding standard somewhat to allow return statements within the function itself. This is done in the interest of execution time efficiency. */ diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c index f23143271..1c93cf3a8 100644 --- a/FreeRTOS/Source/tasks.c +++ b/FreeRTOS/Source/tasks.c @@ -683,6 +683,7 @@ tskTCB * pxNewTCB; { if( pxTCB == pxCurrentTCB ) { + configASSERT( uxSchedulerSuspended == 0 ); portYIELD_WITHIN_API(); } } @@ -700,6 +701,7 @@ tskTCB * pxNewTCB; configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll(); { @@ -774,9 +776,11 @@ tskTCB * pxNewTCB; portTickType xTimeToWake; signed portBASE_TYPE xAlreadyYielded = pdFALSE; + /* A delay time of zero just forces a reschedule. */ if( xTicksToDelay > ( portTickType ) 0U ) { + configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll(); { traceTASK_DELAY(); @@ -1075,6 +1079,7 @@ tskTCB * pxNewTCB; if( xSchedulerRunning != pdFALSE ) { /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); portYIELD_WITHIN_API(); } else -- 2.39.5