Common demo tasks:

- Add additional tests to GenQTest.c to test the updated priority inheritance mechanism.
- Slightly increase some delays in recmutex.c to prevent it reporting false errors in high load test cases.

SAMA5D3 Xplained IAR demo:
- Remove space being allocated for stacks that are not used.
- Remove explicit enabling of interrupts in ISR handers as this is now done from the central ISR callback before the individual handers are invoked.
- Reduce both the allocated heap size and the stack allocated to each task.
- Enable I cache.
This commit is contained in:
Richard Barry 2014-08-04 07:53:20 +00:00
parent 47f895cb34
commit 60538c7480
21 changed files with 214 additions and 597 deletions

View file

@ -413,7 +413,7 @@ QueueHandle_t xQueue;
static void prvLowPriorityMutexTask( void *pvParameters )
{
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
@ -424,6 +424,10 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
vPrintDisplayMessage( &pcTaskStartMsg );
#endif
/* The local mutex is used to check the 'mutexs held' count. */
xLocalMutex = xSemaphoreCreateMutex();
configASSERT( xLocalMutex );
for( ;; )
{
/* Take the mutex. It should be available now. */
@ -432,10 +436,10 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
xErrorDetected = pdTRUE;
}
/* Set our guarded variable to a known start value. */
/* Set the guarded variable to a known start value. */
ulGuardedVariable = 0;
/* Our priority should be as per that assigned when the task was
/* This task's priority should be as per that assigned when the task was
created. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
{
@ -450,7 +454,7 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
taskYIELD();
#endif
/* Ensure the task is reporting it priority as blocked and not
/* Ensure the task is reporting its priority as blocked and not
suspended (as it would have done in versions up to V7.5.3). */
#if( INCLUDE_eTaskGetState == 1 )
{
@ -458,37 +462,46 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
}
#endif /* INCLUDE_eTaskGetState */
/* We should now have inherited the prioritoy of the high priority task,
/* The priority of the high priority task should now have been inherited
as by now it will have attempted to get the mutex. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* We can attempt to set our priority to the test priority - between the
idle priority and the medium/high test priorities, but our actual
prioroity should remain at the high priority. */
/* Attempt to set the priority of this task to the test priority -
between the idle priority and the medium/high test priorities, but the
actual priority should remain at the high priority. */
vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Now unsuspend the medium priority task. This should not run as our
inherited priority is above that of the medium priority task. */
/* Now unsuspend the medium priority task. This should not run as the
inherited priority of this task is above that of the medium priority
task. */
vTaskResume( xMediumPriorityMutexTask );
/* If the did run then it will have incremented our guarded variable. */
/* If the medium priority task did run then it will have incremented the
guarded variable. */
if( ulGuardedVariable != 0 )
{
xErrorDetected = pdTRUE;
}
/* When we give back the semaphore our priority should be disinherited
back to the priority to which we attempted to set ourselves. This means
that when the high priority task next blocks, the medium priority task
should execute and increment the guarded variable. When we next run
both the high and medium priority tasks will have been suspended again. */
/* Take the local mutex too, so two mutexes are now held. */
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* When the semaphore is given back the priority of this task should not
yet be disinherited because the local mutex is still held. This is a
simplification to allow FreeRTOS to be integrated with middleware that
attempts to hold multiple mutexes without bloating the code with complex
algorithms. It is possible that the high priority mutex task will
execute as it shares a priority with this task. */
if( xSemaphoreGive( xMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;
@ -498,24 +511,52 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
taskYIELD();
#endif
/* Check that the guarded variable did indeed increment... */
/* The guarded variable is only incremented by the medium priority task,
which still should not have executed as this task should remain at the
higher priority, ensure this is the case. */
if( ulGuardedVariable != 0 )
{
xErrorDetected = pdTRUE;
}
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Now also give back the local mutex, taking the held count back to 0.
This time the priority of this task should be disinherited back to the
priority to which it was set while the mutex was held. This means
the medium priority task should execute and increment the guarded
variable. When this task next runs both the high and medium priority
tasks will have been suspended again. */
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
#if configUSE_PREEMPTION == 0
taskYIELD();
#endif
/* Check the guarded variable did indeed increment... */
if( ulGuardedVariable != 1 )
{
xErrorDetected = pdTRUE;
}
/* ... and that our priority has been disinherited to
/* ... and that the priority of this task has been disinherited to
genqMUTEX_TEST_PRIORITY. */
if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
{
xErrorDetected = pdTRUE;
}
/* Set our priority back to our original priority ready for the next
loop around this test. */
/* Set the priority of this task back to its original value, ready for
the next loop around this test. */
vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
/* Just to show we are still running. */
/* Just to show this task is still running. */
ulLoopCounter2++;
#if configUSE_PREEMPTION == 0
@ -561,8 +602,8 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
xErrorDetected = pdTRUE;
}
/* When we eventually obtain the mutex we just give it back then
return to suspend ready for the next test. */
/* When the mutex is eventually obtained it is just given back before
returning to suspend ready for the next cycle. */
if( xSemaphoreGive( xMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -135,7 +135,7 @@ from within the interrupts. */
#define timerNORMALLY_EMPTY_TX() \
if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \
{ \
UBaseType_t uxSavedInterruptStatus; \
UBaseType_t uxSavedInterruptStatus; \
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
{ \
uxValueForNormallyEmptyQueue++; \
@ -149,7 +149,7 @@ from within the interrupts. */
#define timerNORMALLY_FULL_TX() \
if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \
{ \
UBaseType_t uxSavedInterruptStatus; \
UBaseType_t uxSavedInterruptStatus; \
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
{ \
uxValueForNormallyFullQueue++; \

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -210,7 +210,7 @@ static void prvTimerTestTask( void *pvParameters )
/* Check the auto reload timers can be stopped correctly, and correctly
report their state. */
prvTest4_CheckAutoReloadTimersCanBeStopped();
/* Check the one shot timer only calls its callback once after it has been
started, and that it reports its state correctly. */
prvTest5_CheckBasicOneShotTimerBehaviour();
@ -238,7 +238,7 @@ static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCy
elsewhere. Start counting Iterations again. */
xIterationsWithoutCounterIncrement = ( TickType_t ) 0;
xLastCycleFrequency = xCycleFrequency;
}
}
/* Calculate the maximum number of times that it is permissible for this
function to be called without ulLoopCounter being incremented. This is
@ -336,7 +336,7 @@ UBaseType_t xTimer;
configASSERT( xTestStatus );
}
}
/* Create the timers that are used from the tick interrupt to test the timer
API functions that can be called from an ISR. */
xISRAutoReloadTimer = xTimerCreate( "ISR AR", /* The text name given to the timer. */
@ -350,7 +350,7 @@ UBaseType_t xTimer;
pdFALSE, /* This is a one shot timer. */
( void * ) NULL, /* The identifier is not required. */
prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */
if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) )
{
xTestStatus = pdFAIL;
@ -394,13 +394,13 @@ TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber;
/* Check the auto reload timers expire at the expected rates. */
/* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow
all the auto reload timers to expire at least once. */
xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;
vTaskDelay( xBlockPeriod );
/* Check that all the auto reload timers have called their callback
/* Check that all the auto reload timers have called their callback
function the expected number of times. */
for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
{
@ -408,7 +408,7 @@ TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber;
by the timer period. */
xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod );
xExpectedNumber = xBlockPeriod / xTimerPeriod;
ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber ) ;
ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */
@ -431,7 +431,7 @@ TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber;
/*-----------------------------------------------------------*/
static void prvTest4_CheckAutoReloadTimersCanBeStopped( void )
{
{
uint8_t ucTimer;
/* Check the auto reload timers can be stopped correctly, and correctly
@ -749,7 +749,7 @@ static TickType_t uxTick = ( TickType_t ) -1;
if( uxTick == 0 )
{
/* The timers will have been created, but not started. Start them now
/* The timers will have been created, but not started. Start them now
by setting their period. */
ucISRAutoReloadTimerCounter = 0;
ucISROneShotTimerCounter = 0;
@ -765,7 +765,7 @@ static TickType_t uxTick = ( TickType_t ) -1;
/* First timer was started, try starting the second timer. */
if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS )
{
/* Both timers were started, so set the uxTick back to its
/* Both timers were started, so set the uxTick back to its
proper value. */
uxTick = 0;
}
@ -805,7 +805,7 @@ static TickType_t uxTick = ( TickType_t ) -1;
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
}
}
else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) )
{
@ -817,7 +817,7 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 1 )
{
xTestStatus = pdFAIL;
@ -834,13 +834,13 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 1 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
}
}
else if( uxTick == ( 3 * xBasePeriod ) )
{
/* Start the one shot timer again. */
@ -856,17 +856,17 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 1 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
/* Now stop the auto reload timer. The one shot timer was started
a few ticks ago. */
xTimerStopFromISR( xISRAutoReloadTimer, NULL );
}
}
else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) )
{
/* The auto reload timer is now stopped, and the one shot timer is
@ -877,13 +877,13 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 1 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
}
}
else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) )
{
/* The auto reload timer is now stopped, and the one shot timer is
@ -894,13 +894,13 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 2 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
}
}
else if( uxTick == ( 8 * xBasePeriod ) )
{
/* The auto reload timer is now stopped, and the one shot timer has
@ -911,16 +911,16 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 2 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
/* Now reset the one shot timer. */
xTimerResetFromISR( xISROneShotTimer, NULL );
}
}
else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) )
{
/* Only the one shot timer should be running, but it should not have
@ -931,15 +931,15 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 2 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
xTimerResetFromISR( xISROneShotTimer, NULL );
}
}
else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) )
{
/* Only the one shot timer should be running, but it should not have
@ -950,13 +950,13 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 2 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
xTimerResetFromISR( xISROneShotTimer, NULL );
}
else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) )
@ -969,15 +969,15 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 2 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
xTimerResetFromISR( xISROneShotTimer, NULL );
}
}
else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) )
{
/* Only the one shot timer should have been running and this time it
@ -990,7 +990,7 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 3 )
{
xTestStatus = pdFAIL;
@ -1007,15 +1007,15 @@ static TickType_t uxTick = ( TickType_t ) -1;
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
if( ucISROneShotTimerCounter != 3 )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}
uxTick = ( TickType_t ) -1;
}
}
}
/*-----------------------------------------------------------*/

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -64,15 +64,15 @@
*/
/*
* Creates eight tasks, each of which loops continuously performing a floating
* Creates eight tasks, each of which loops continuously performing a floating
* point calculation.
*
* All the tasks run at the idle priority and never block or yield. This causes
* all eight tasks to time slice with the idle task. Running at the idle
* priority means that these tasks will get pre-empted any time another task is
* ready to run or a time slice occurs. More often than not the pre-emption
* will occur mid calculation, creating a good test of the schedulers context
* switch mechanism - a calculation producing an unexpected result could be a
* all eight tasks to time slice with the idle task. Running at the idle
* priority means that these tasks will get pre-empted any time another task is
* ready to run or a time slice occurs. More often than not the pre-emption
* will occur mid calculation, creating a good test of the schedulers context
* switch mechanism - a calculation producing an unexpected result could be a
* symptom of a corruption in the context of a task.
*/
@ -375,7 +375,7 @@ BaseType_t xReturn = pdPASS, xTask;
usTaskCheck[ xTask ] = pdFALSE;
}
}
return xReturn;
}

View file

@ -121,7 +121,7 @@ be overridden by a definition in FreeRTOSConfig.h. */
/* Misc. */
#define recmuSHORT_DELAY ( 20 / portTICK_PERIOD_MS )
#define recmuNO_DELAY ( ( TickType_t ) 0 )
#define recmuFIVE_TICK_DELAY ( ( TickType_t ) 5 )
#define recmuEIGHT_TICK_DELAY ( ( TickType_t ) 8 )
/* The three tasks as described at the top of this file. */
static void prvRecursiveMutexControllingTask( void *pvParameters );
@ -195,7 +195,7 @@ UBaseType_t ux;
long enough to ensure the polling task will execute again before the
block time expires. If the block time does expire then the error
flag will be set here. */
if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS )
if( xSemaphoreTakeRecursive( xMutex, recmuEIGHT_TICK_DELAY ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}