mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
Move the event groups single tasks test out of the common demo file (they are now part of the module tests).
This commit is contained in:
parent
c861e3883d
commit
a3c2f45116
7 changed files with 117 additions and 229 deletions
|
@ -135,13 +135,6 @@ static void prvWaitBitsTask( void *pvParameters );
|
|||
*/
|
||||
static void prvSyncTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Contains a set of behavioural tests that can be performed from a single task.
|
||||
* This function is called by prvSetBitsTask() before prvSetBitsTasks() starts
|
||||
* the tests that make use of the prvWaitBitsTask().
|
||||
*/
|
||||
static portBASE_TYPE prvSingleTaskTests( void );
|
||||
|
||||
/*
|
||||
* Functions used in a test that blocks two tasks on various different bits
|
||||
* within an event group - then sets each bit in turn and checks that the
|
||||
|
@ -184,196 +177,6 @@ xTaskHandle xWaitBitsTaskHandle;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvSingleTaskTests( void )
|
||||
{
|
||||
xEventBitsType uxReturned;
|
||||
portBASE_TYPE xError = pdFALSE, xHigherPriorityTaskWoken;
|
||||
portTickType xTimeOnEntering, xTimeOnExiting;
|
||||
|
||||
/* Check no bits are currently set. */
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebBIT_1, /* The bit being tested. */
|
||||
pdFALSE, /* Don't clear the bit on exit. */
|
||||
pdFALSE, /* Wait for a single bit, not all the bits. */
|
||||
ebDONT_BLOCK ); /* Block time. */
|
||||
|
||||
if( uxReturned != 0x00 )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* Set selected bits. */
|
||||
xEventGroupSetBits( xEventBits, ebCOMBINED_BITS );
|
||||
|
||||
/* Wait on all the selected bits. This should return immediately even
|
||||
though a block time is specified. */
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, ebCOMBINED_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
|
||||
|
||||
if( uxReturned != ebCOMBINED_BITS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now try waiting on all the selected bits plus a bit that is not set.
|
||||
This should time out. */
|
||||
xTimeOnEntering = xTaskGetTickCount();
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebCOMBINED_BITS | ebBIT_0, /* The bits being tested. */
|
||||
pdFALSE, /* Don't clear the bits on exit. */
|
||||
pdTRUE, /* Wait for all the bits to be set, not just a single bit. */
|
||||
ebSHORT_DELAY ); /* Block time. */
|
||||
xTimeOnExiting = xTaskGetTickCount();
|
||||
|
||||
if( ( xTimeOnExiting - xTimeOnEntering ) < ebSHORT_DELAY )
|
||||
{
|
||||
/* Did not block as expected. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxReturned != ebCOMBINED_BITS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
/* This time pass in the same bit combination, but wait for only a single
|
||||
bit. This time it should not block even though one of the bits in the
|
||||
combination is not set. */
|
||||
xTimeOnEntering = xTaskGetTickCount();
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebCOMBINED_BITS | ebBIT_0, /* The bits being tested. */
|
||||
pdFALSE, /* Don't clear the bits on exit. */
|
||||
pdFALSE, /* Don't wait for all the bits to be set, a single bit is all that is required. */
|
||||
ebSHORT_DELAY ); /* Block time. */
|
||||
xTimeOnExiting = xTaskGetTickCount();
|
||||
|
||||
if( ( xTimeOnExiting - xTimeOnEntering ) >= ebSHORT_DELAY )
|
||||
{
|
||||
/* Blocked, but didn't expect to. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxReturned != ebCOMBINED_BITS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Now set all the bits. */
|
||||
xEventGroupSetBits( xEventBits, ebALL_BITS );
|
||||
|
||||
/* Read the bits back to ensure they are all set. Read back with a timeout
|
||||
to ensure the task does not block (all the bits are already set), and leave
|
||||
the bits set on exit. */
|
||||
xTimeOnEntering = xTaskGetTickCount();
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebALL_BITS, /* The bits being tested. */
|
||||
pdFALSE, /* Don't clear the bits on exit. */
|
||||
pdTRUE, /* Wait for all the bits to be set. */
|
||||
ebSHORT_DELAY );/* Block time. */
|
||||
xTimeOnExiting = xTaskGetTickCount();
|
||||
|
||||
if( ( xTimeOnExiting - xTimeOnEntering ) >= ebSHORT_DELAY )
|
||||
{
|
||||
/* Blocked, but didn't expect to. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxReturned != ebALL_BITS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Now wait for some bits to be set (which are all set), and clear the bits
|
||||
on exit. Again this should not block. */
|
||||
xTimeOnEntering = xTaskGetTickCount();
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebCOMBINED_BITS, /* The bits being tested, which are a subset of the bits now set. */
|
||||
pdTRUE, /* Clear the bits on exit. */
|
||||
pdTRUE, /* Wait for all the bits to be set (which they already are. */
|
||||
ebSHORT_DELAY ); /* Block time. */
|
||||
xTimeOnExiting = xTaskGetTickCount();
|
||||
|
||||
if( ( xTimeOnExiting - xTimeOnEntering ) >= ebSHORT_DELAY )
|
||||
{
|
||||
/* Blocked, but didn't expect to. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxReturned != ebALL_BITS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now the bits set by the ebCOMBINED_BITS constant should be clear, but
|
||||
all the other bits should be set. Call xEventGroupWaitBits() again, this time
|
||||
waiting for any bit within ebALL_BITS, and clearing all bits on exit to
|
||||
leave the event bits all clear again. */
|
||||
xTimeOnEntering = xTaskGetTickCount();
|
||||
uxReturned = xEventGroupWaitBits( xEventBits, /* The event flags being tested. */
|
||||
ebALL_BITS, /* The bits being tested, which are a subset of the bits now set. */
|
||||
pdTRUE, /* Clear the bits on exit. */
|
||||
pdFALSE, /* Wait for any bit to be set. */
|
||||
ebSHORT_DELAY ); /* Block time. */
|
||||
xTimeOnExiting = xTaskGetTickCount();
|
||||
|
||||
if( ( xTimeOnExiting - xTimeOnEntering ) >= ebSHORT_DELAY )
|
||||
{
|
||||
/* Blocked, but didn't expect to. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* The bits defined in ebCOMBINED_BITS were already cleared, so this time
|
||||
only the remaining bits should have been set. */
|
||||
if( uxReturned != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* All the bits should be clear again as the last call to xEventGroupWaitBits()
|
||||
had the "clear on exit" parameter set to pdTRUE. */
|
||||
uxReturned = xEventGroupGetBits( xEventBits );
|
||||
|
||||
if( uxReturned != 0x00 )
|
||||
{
|
||||
/* Expected all bits to be clear. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* Try the 'set from ISR' function, which will pend the set to the timer
|
||||
daemon task. */
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
if( xEventGroupSetBitsFromISR( xEventBits, ebBIT_3, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||
{
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
if( xHigherPriorityTaskWoken == pdTRUE )
|
||||
{
|
||||
/* If the daemon task has a higher priority then a yield should be
|
||||
performed to ensure it runs before the bits are tested. */
|
||||
taskYIELD();
|
||||
}
|
||||
|
||||
/* Is the bit set? */
|
||||
uxReturned = xEventGroupGetBits( xEventBits );
|
||||
|
||||
if( uxReturned != ebBIT_3 )
|
||||
{
|
||||
/* Expected all bits to be clear. */
|
||||
xError = pdTRUE;
|
||||
}
|
||||
|
||||
/* Clear all bits again ready for infinite loop tests. */
|
||||
xEventGroupClearBits( xEventBits, ebALL_BITS );
|
||||
|
||||
return xError;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSyncTask( void *pvParameters )
|
||||
{
|
||||
xEventBitsType uxSynchronisationBit, uxReturned;
|
||||
|
@ -556,16 +359,10 @@ xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;
|
|||
xEventBits = xEventGroupCreate();
|
||||
configASSERT( xEventBits );
|
||||
|
||||
/* Perform the tests that only require a single task. */
|
||||
xError = prvSingleTaskTests();
|
||||
|
||||
if( xError == pdFALSE )
|
||||
{
|
||||
/* Perform the tests that block two tasks on different combinations of
|
||||
bits, then set each bit in turn and check the correct tasks unblock at
|
||||
the correct times. */
|
||||
xError = prvTestSelectiveBits();
|
||||
}
|
||||
/* Perform the tests that block two tasks on different combinations of bits,
|
||||
then set each bit in turn and check the correct tasks unblock at the correct
|
||||
times. */
|
||||
xError = prvTestSelectiveBits();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
|
|
|
@ -721,28 +721,25 @@ static portTickType uxTick = ( portTickType ) -1;
|
|||
function is called from the tick hook anyway. However the API required it
|
||||
to be present. */
|
||||
signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
portTickType xMargin;
|
||||
|
||||
if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) )
|
||||
{
|
||||
/* The timer service task is not the highest priority task, so it cannot
|
||||
be assumed that timings will be exact. Timers should never call their
|
||||
callback before their expiry time, but a margin is permissible for calling
|
||||
their callback after their expiry time. If exact timing is required then
|
||||
configTIMER_TASK_PRIORITY must be set to ensure the timer service task
|
||||
is the highest priority task in the system. */
|
||||
xMargin = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
xMargin = 1;
|
||||
}
|
||||
#if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) )
|
||||
/* The timer service task is not the highest priority task, so it cannot
|
||||
be assumed that timings will be exact. Timers should never call their
|
||||
callback before their expiry time, but a margin is permissible for calling
|
||||
their callback after their expiry time. If exact timing is required then
|
||||
configTIMER_TASK_PRIORITY must be set to ensure the timer service task
|
||||
is the highest priority task in the system. */
|
||||
const portTickType xMargin = 5;
|
||||
#else
|
||||
|
||||
const portTickType xMargin = 1;
|
||||
#endif
|
||||
|
||||
/* This test is called from the tick ISR even when the scheduler is suspended.
|
||||
Therefore, it is possible for the xTickCount to be temporarily less than the
|
||||
uxTicks count maintained in this function. That can result in calculated
|
||||
unblock times being too short, as this function is not called as missed ticks
|
||||
(ticks that occur while the scheduler is suspended) are unwound to re-instate
|
||||
(ticks that occur while the scheduler is suspended) are unwound to reinstate
|
||||
the real tick value. Therefore, if this happens, just abandon the test
|
||||
and start again. */
|
||||
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
|
||||
|
@ -754,14 +751,28 @@ portTickType xMargin;
|
|||
uxTick++;
|
||||
}
|
||||
|
||||
if( uxTick == 0 )
|
||||
if( uxTick == ( xBasePeriod >> 1 ) )
|
||||
{
|
||||
/* The timers will have been created, but not started. Start them
|
||||
now by setting their period. */
|
||||
ucISRAutoReloadTimerCounter = 0;
|
||||
ucISROneShotTimerCounter = 0;
|
||||
xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, &xHigherPriorityTaskWoken );
|
||||
xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, &xHigherPriorityTaskWoken );
|
||||
|
||||
/* It is possible that the timer task has not yet made room in the
|
||||
timer queue. If the timers cannot be started then reset uxTick so
|
||||
another attempt is made later. */
|
||||
uxTick = ( portTickType ) -1;
|
||||
if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, &xHigherPriorityTaskWoken ) == pdPASS )
|
||||
{
|
||||
if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, &xHigherPriorityTaskWoken ) == pdPASS )
|
||||
{
|
||||
uxTick = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xTimerStopFromISR( xISRAutoReloadTimer, &xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( uxTick == xBasePeriod )
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue