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.
This commit is contained in:
Richard Barry 2013-11-24 10:11:16 +00:00
parent 5037ecdc5c
commit d2c2e3ca68
5 changed files with 62 additions and 31 deletions

View File

@ -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; xEventBitsType uxOriginalBitValue, uxReturn;
xEVENT_BITS *pxEventBits = ( xEVENT_BITS * ) xEventGroup; xEVENT_BITS *pxEventBits = ( xEVENT_BITS * ) xEventGroup;
portBASE_TYPE xYieldedAlready; portBASE_TYPE xYieldedAlready;
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
{
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
}
#endif
vTaskSuspendAll(); vTaskSuspendAll();
{ {
uxOriginalBitValue = pxEventBits->uxEventBits; uxOriginalBitValue = pxEventBits->uxEventBits;
@ -156,16 +162,16 @@ portBASE_TYPE xYieldedAlready;
already unless this is the only task in the rendezvous. */ already unless this is the only task in the rendezvous. */
pxEventBits->uxEventBits &= uxBitsToWaitFor; pxEventBits->uxEventBits &= uxBitsToWaitFor;
xBlockTime = 0; xTicksToWait = 0;
} }
else else
{ {
if( xBlockTime != ( portTickType ) 0 ) if( xTicksToWait != ( portTickType ) 0 )
{ {
/* Store the bits that the calling task is waiting for in the /* 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 task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ 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 else
{ {
@ -177,7 +183,7 @@ portBASE_TYPE xYieldedAlready;
} }
xYieldedAlready = xTaskResumeAll(); xYieldedAlready = xTaskResumeAll();
if( xBlockTime != ( portTickType ) 0 ) if( xTicksToWait != ( portTickType ) 0 )
{ {
if( xYieldedAlready == pdFALSE ) 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; xEVENT_BITS *pxEventBits = ( xEVENT_BITS * ) xEventGroup;
const xEventBitsType uxCurrentEventBits = pxEventBits->uxEventBits; const xEventBitsType uxCurrentEventBits = pxEventBits->uxEventBits;
@ -217,6 +223,11 @@ xEventBitsType uxReturn, uxControlBits = 0;
itself, and that at least one bit is being requested. */ itself, and that at least one bit is being requested. */
configASSERT( ( uxBitsToWaitFor & taskEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToWaitFor & taskEVENT_BITS_CONTROL_BYTES ) == 0 );
configASSERT( uxBitsToWaitFor != 0 ); configASSERT( uxBitsToWaitFor != 0 );
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
{
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
}
#endif
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
@ -227,7 +238,7 @@ xEventBitsType uxReturn, uxControlBits = 0;
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( xEventBitsType ) 0 ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( xEventBitsType ) 0 )
{ {
/* At least one of the bits was set. No need to block. */ /* At least one of the bits was set. No need to block. */
xBlockTime = 0; xTicksToWait = 0;
} }
} }
else else
@ -237,13 +248,13 @@ xEventBitsType uxReturn, uxControlBits = 0;
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
{ {
/* All the bits were set, no need to block. */ /* 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 /* The task can return now if either its wait condition is already met
or the requested block time is 0. */ or the requested block time is 0. */
if( xBlockTime == ( portTickType ) 0 ) if( xTicksToWait == ( portTickType ) 0 )
{ {
/* No need to block, just set the return value. */ /* No need to block, just set the return value. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
@ -274,13 +285,13 @@ xEventBitsType uxReturn, uxControlBits = 0;
/* Store the bits that the calling task is waiting for in the /* 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 task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ found. Then enter the blocked state. */
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xBlockTime ); vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
if( xBlockTime != ( portTickType ) 0 ) if( xTicksToWait != ( portTickType ) 0 )
{ {
/* The task blocked to wait for its required bits to be set - at this /* 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 point either the required bits were set or the block time expired. If
@ -345,9 +356,10 @@ portBASE_TYPE xMatchFound = pdFALSE;
pxList = &( pxEventBits->xTasksWaitingForBits ); 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. */ 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(); vTaskSuspendAll();
{ {
pxListItem = listGET_HEAD_ENTRY( pxList );
/* Set the bits. */ /* Set the bits. */
pxEventBits->uxEventBits |= uxBitsToSet; pxEventBits->uxEventBits |= uxBitsToSet;

View File

@ -168,7 +168,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
xEventBitsType uxBitsToWaitFor, xEventBitsType uxBitsToWaitFor,
portBASE_TYPE xClearOnExit, portBASE_TYPE xClearOnExit,
portBASE_TYPE xWaitForAllBits, portBASE_TYPE xWaitForAllBits,
portTickType xBlockTime ); portTickType xTicksToWait );
</pre> </pre>
* *
* [Potentially] block to wait for one or more bits to be set within a * [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 * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
* in uxBitsToWaitFor is set or the specified block time expires. * 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 * for one/all (depending on the xWaitForAllBits value) of the bits specified by
* uxBitsToWaitFor to become set. * uxBitsToWaitFor to become set.
* *
@ -217,7 +217,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
void aFunction( xEventGroupHandle xEventGroup ) void aFunction( xEventGroupHandle xEventGroup )
{ {
xEventBitsType uxBits; 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 // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
// the event group. Clear the bits before exiting. // 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. BIT_0 | BIT_4, // The bits within the event group to wait for.
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
pdFALSE, // Don't wait for both bits, either bit will do. 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 ) ) if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ {
@ -242,7 +242,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
} }
else else
{ {
// xEventGroupWaitBits() returned because xBlockTime ticks passed // xEventGroupWaitBits() returned because xTicksToWait ticks passed
// without either BIT_0 or BIT_4 becoming set. // without either BIT_0 or BIT_4 becoming set.
} }
} }
@ -250,7 +250,7 @@ xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
* \defgroup xEventGroupWaitBits xEventGroupWaitBits * \defgroup xEventGroupWaitBits xEventGroupWaitBits
* \ingroup EventGroup * \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 * event_groups.h
@ -459,7 +459,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType
xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup,
xEventBitsType uxBitsToSet, xEventBitsType uxBitsToSet,
xEventBitsType uxBitsToWaitFor, xEventBitsType uxBitsToWaitFor,
portTickType xBlockTime ); portTickType xTicksToWait );
</pre> </pre>
* *
* Atomically set bits within an event group, then wait for a combination of * 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 0x05. To wait for bits 0 and bit 1 and bit 2 set
* uxBitsToWaitFor to 0x07. Etc. * 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. * 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 * @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 ) void vTask0( void *pvParameters )
{ {
xEventBitsType uxReturn; xEventBitsType uxReturn;
portTickType xBlockTime = 100 / portTICK_RATE_MS; portTickType xTicksToWait = 100 / portTICK_RATE_MS;
for( ;; ) for( ;; )
{ {
@ -525,7 +525,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation // 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 // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
// for this to happen. // 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 ) if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
{ {
@ -577,7 +577,7 @@ xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType
* \defgroup xEventGroupSync xEventGroupSync * \defgroup xEventGroupSync xEventGroupSync
* \ingroup EventGroup * \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;
/** /**

View File

@ -226,10 +226,13 @@ typedef enum
*/ */
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
/* Definitions returned by xTaskGetSchedulerState(). */ /* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is
#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 0 ) 0 to generate more optimal code when configASSERT() is defined as the constant
#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 1 ) is used in assert() statements. */
#define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 2 ) #define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 0 )
#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 1 )
#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 2 )
/*----------------------------------------------------------- /*-----------------------------------------------------------
* TASK CREATION API * TASK CREATION API

View File

@ -570,6 +570,12 @@ xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); 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 /* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest statements within the function itself. This is done in the interest
@ -1052,6 +1058,11 @@ xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); 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 /* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest statements within the function itself. This is done in the interest

View File

@ -683,6 +683,7 @@ tskTCB * pxNewTCB;
{ {
if( pxTCB == pxCurrentTCB ) if( pxTCB == pxCurrentTCB )
{ {
configASSERT( uxSchedulerSuspended == 0 );
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
} }
@ -700,6 +701,7 @@ tskTCB * pxNewTCB;
configASSERT( pxPreviousWakeTime ); configASSERT( pxPreviousWakeTime );
configASSERT( ( xTimeIncrement > 0U ) ); configASSERT( ( xTimeIncrement > 0U ) );
configASSERT( uxSchedulerSuspended == 0 );
vTaskSuspendAll(); vTaskSuspendAll();
{ {
@ -774,9 +776,11 @@ tskTCB * pxNewTCB;
portTickType xTimeToWake; portTickType xTimeToWake;
signed portBASE_TYPE xAlreadyYielded = pdFALSE; signed portBASE_TYPE xAlreadyYielded = pdFALSE;
/* A delay time of zero just forces a reschedule. */ /* A delay time of zero just forces a reschedule. */
if( xTicksToDelay > ( portTickType ) 0U ) if( xTicksToDelay > ( portTickType ) 0U )
{ {
configASSERT( uxSchedulerSuspended == 0 );
vTaskSuspendAll(); vTaskSuspendAll();
{ {
traceTASK_DELAY(); traceTASK_DELAY();
@ -1075,6 +1079,7 @@ tskTCB * pxNewTCB;
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
/* The current task has just been suspended. */ /* The current task has just been suspended. */
configASSERT( uxSchedulerSuspended == 0 );
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
else else