Add additional configASSERTS() to some standard demo tasks.

Use own rand() function in QueueSet.c to prevent library versions being referenced.
This commit is contained in:
Richard Barry 2013-09-01 19:45:06 +00:00
parent 33bd63e287
commit ed399e801e
3 changed files with 132 additions and 52 deletions

View file

@ -109,7 +109,7 @@ in the range of 0xffff to ULONG_MAX. */
/* For test purposes the priority of the sending task is changed after every
queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
#define queuesetPRIORITY_CHANGE_LOOPS 100UL
#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 3 )
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
#define queuesetISR_TX_PERIOD ( 100UL )
@ -161,6 +161,13 @@ static void prvSetupTest( xTaskHandle xQueueSetSendingTask );
*/
static portBASE_TYPE prvCheckReceivedValueWithinExpectedRange( unsigned long ulReceived, unsigned long ulExpectedReceived );
/*
* Local pseudo random number seed and return functions. Used to avoid calls
* to the standard library.
*/
static unsigned long prvRand( void );
static void prvSRand( unsigned long ulSeed );
/*-----------------------------------------------------------*/
/* The queues that are added to the set. */
@ -193,6 +200,9 @@ xAreQueeuSetTasksStillRunning() function can check it is incrementing as
expected. */
static volatile unsigned long ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
/* Used by the pseudo random number generator. */
static unsigned long ulNextRand = 0;
/*-----------------------------------------------------------*/
void vStartQueueSetTasks( void )
@ -264,25 +274,25 @@ portBASE_TYPE xReturn = pdPASS, x;
static void prvQueueSetSendingTask( void *pvParameters )
{
unsigned long ulTaskTxValue = 0;
portBASE_TYPE xQueueToWriteTo;
unsigned long ulTaskTxValue = 0, ulQueueToWriteTo;
xQueueHandle xQueueInUse;
unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
/* Remove compiler warning about the unused parameter. */
( void ) pvParameters;
srand( ( unsigned int ) &ulTaskTxValue );
/* Seed mini pseudo random number generator. */
prvSRand( ( unsigned long ) &ulTaskTxValue );
for( ;; )
{
/* Generate the index for the queue to which a value is to be sent. */
xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;
xQueueInUse = xQueues[ xQueueToWriteTo ];
ulQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET;
xQueueInUse = xQueues[ ulQueueToWriteTo ];
/* Note which index is being written to to ensure all the queues are
used. */
( ulQueueUsedCounter[ xQueueToWriteTo ] )++;
( ulQueueUsedCounter[ ulQueueToWriteTo ] )++;
/* Send to the queue to unblock the task that is waiting for data to
arrive on a queue within the queue set to which this queue belongs. */
@ -637,3 +647,17 @@ unsigned long ulValueToSend = 0;
/* Let the ISR access the queues also. */
xSetupComplete = pdTRUE;
}
/*-----------------------------------------------------------*/
static unsigned long prvRand( void )
{
ulNextRand = ( ulNextRand * 1103515245UL ) + 12345UL;
return (ulNextRand / 65536UL ) % 32768UL;
}
/*-----------------------------------------------------------*/
static void prvSRand( unsigned long ulSeed )
{
ulNextRand = ulSeed;
}

View file

@ -72,12 +72,12 @@
*
* One counter task loops indefinitely, incrementing the shared count variable
* on each iteration. To ensure it has exclusive access to the variable it
* raises it's priority above that of the controller task before each
* increment, lowering it again to it's original priority before starting the
* raises its priority above that of the controller task before each
* increment, lowering it again to its original priority before starting the
* next iteration.
*
* The other counter task increments the shared count variable on each
* iteration of it's loop until the count has reached a limit of 0xff - at
* iteration of its loop until the count has reached a limit of 0xff - at
* which point it suspends itself. It will not start a new loop until the
* controller task has made it "ready" again by calling vTaskResume().
* This second counter task operates at a higher priority than controller
@ -105,7 +105,7 @@
* continuous count task, and moves on to its second section.
*
* At the start of the second section the shared variable is cleared to zero.
* The limited count task is then woken from it's suspension by a call to
* The limited count task is then woken from its suspension by a call to
* vTaskResume (). As this counter task operates at a higher priority than
* the controller task the controller task should not run again until the
* shared variable has been counted up to the limited value causing the counter
@ -153,11 +153,11 @@ static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters );
/* Handles to the two counter tasks. These could be passed in as parameters
to the controller task to prevent them having to be file scope. */
static xTaskHandle xContinousIncrementHandle, xLimitedIncrementHandle;
static xTaskHandle xContinuousIncrementHandle, xLimitedIncrementHandle;
/* The shared counter variable. This is passed in as a parameter to the two
counter variables for demonstration purposes. */
static unsigned long ulCounter;
static volatile unsigned long ulCounter;
/* Variables used to check that the tasks are still operating without error.
Each complete iteration of the controller task increments this variable
@ -192,7 +192,7 @@ void vStartDynamicPriorityTasks( void )
defined to be less than 1. */
vQueueAddToRegistry( xSuspendedTestQueue, ( signed char * ) "Suspended_Test_Queue" );
xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle );
xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle );
xTaskCreate( vLimitedIncrementTask, ( signed char * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
xTaskCreate( vCounterControlTask, ( signed char * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vQueueSendWhenSuspendedTask, ( signed char * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
@ -235,7 +235,7 @@ unsigned long *pulCounter;
*/
static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters )
{
unsigned long *pulCounter;
volatile unsigned long *pulCounter;
unsigned portBASE_TYPE uxOurPriority;
/* Take a pointer to the shared variable from the parameters passed into
@ -248,11 +248,15 @@ unsigned portBASE_TYPE uxOurPriority;
for( ;; )
{
/* Raise our priority above the controller task to ensure a context
switch does not occur while we are accessing this variable. */
/* Raise the priority above the controller task to ensure a context
switch does not occur while the variable is being accessed. */
vTaskPrioritySet( NULL, uxOurPriority + 1 );
{
configASSERT( ( uxTaskPriorityGet( NULL ) == ( uxOurPriority + 1 ) ) );
( *pulCounter )++;
}
vTaskPrioritySet( NULL, uxOurPriority );
configASSERT( ( uxTaskPriorityGet( NULL ) == uxOurPriority ) );
}
}
/*-----------------------------------------------------------*/
@ -280,10 +284,26 @@ short sError = pdFALSE;
for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
{
/* Suspend the continuous count task so we can take a mirror of the
shared variable without risk of corruption. */
vTaskSuspend( xContinousIncrementHandle );
shared variable without risk of corruption. This is not really
needed as the other task raises its priority above this task's
priority. */
vTaskSuspend( xContinuousIncrementHandle );
{
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended );
}
#endif /* INCLUDE_eTaskGetState */
ulLastCounter = ulCounter;
vTaskResume( xContinousIncrementHandle );
}
vTaskResume( xContinuousIncrementHandle );
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady );
}
#endif /* INCLUDE_eTaskGetState */
/* Now delay to ensure the other task has processor time. */
vTaskDelay( priSLEEP_TIME );
@ -303,20 +323,34 @@ short sError = pdFALSE;
xTaskResumeAll();
}
/* Second section: */
/* Suspend the continuous counter task so it stops accessing the shared variable. */
vTaskSuspend( xContinousIncrementHandle );
/* Suspend the continuous counter task so it stops accessing the shared
variable. */
vTaskSuspend( xContinuousIncrementHandle );
/* Reset the variable. */
ulCounter = ( unsigned long ) 0;
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
}
#endif /* INCLUDE_eTaskGetState */
/* Resume the limited count task which has a higher priority than us.
We should therefore not return from this call until the limited count
task has suspended itself with a known value in the counter variable. */
vTaskResume( xLimitedIncrementHandle );
/* This task should not run again until xLimitedIncrementHandle has
suspended itself. */
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
}
#endif /* INCLUDE_eTaskGetState */
/* Does the counter variable have the expected value? */
if( ulCounter != priMAX_COUNT )
{
@ -332,7 +366,7 @@ short sError = pdFALSE;
}
/* Resume the continuous count task and do it all again. */
vTaskResume( xContinousIncrementHandle );
vTaskResume( xContinuousIncrementHandle );
}
}
/*-----------------------------------------------------------*/

View file

@ -117,7 +117,7 @@
/* Misc. */
#define recmuSHORT_DELAY ( 20 / portTICK_RATE_MS )
#define recmuNO_DELAY ( ( portTickType ) 0 )
#define recmuTWO_TICK_DELAY ( ( portTickType ) 2 )
#define recmuTHREE_TICK_DELAY ( ( portTickType ) 3 )
/* The three tasks as described at the top of this file. */
static void prvRecursiveMutexControllingTask( void *pvParameters );
@ -191,7 +191,7 @@ unsigned portBASE_TYPE 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, recmuTWO_TICK_DELAY ) != pdPASS )
if( xSemaphoreTakeRecursive( xMutex, recmuTHREE_TICK_DELAY ) != pdPASS )
{
xErrorOccurred = pdTRUE;
}
@ -251,8 +251,10 @@ static void prvRecursiveMutexBlockingTask( void *pvParameters )
controlling task will block only once it has the mutex - therefore
this call should block until the controlling task has given up the
mutex, and not actually execute past this call until the controlling
task is suspended. */
if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS )
task is suspended. portMAX_DELAY - 1 is used instead of portMAX_DELAY
to ensure the task's state is reported as Blocked and not Suspended in
a later call to configASSERT() (within the polling task). */
if( xSemaphoreTakeRecursive( xMutex, ( portMAX_DELAY - 1 ) ) == pdPASS )
{
if( xControllingIsSuspended != pdTRUE )
{
@ -306,6 +308,13 @@ static void prvRecursiveMutexPollingTask( void *pvParameters )
happen when the controlling task is also suspended. */
if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )
{
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xControllingTaskHandle ) == eSuspended );
configASSERT( eTaskGetState( xBlockingTaskHandle ) == eSuspended );
}
#endif /* INCLUDE_eTaskGetState */
/* Is the blocking task suspended? */
if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) )
{
@ -336,6 +345,19 @@ static void prvRecursiveMutexPollingTask( void *pvParameters )
xErrorOccurred = pdTRUE;
}
#if( INCLUDE_uxTaskPriorityGet == 1 )
{
configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY );
}
#endif /* INCLUDE_uxTaskPriorityGet */
#if( INCLUDE_eTaskGetState == 1 )
{
configASSERT( eTaskGetState( xControllingTaskHandle ) == eBlocked );
configASSERT( eTaskGetState( xBlockingTaskHandle ) == eBlocked );
}
#endif /* INCLUDE_eTaskGetState */
/* Release the mutex, disinheriting the higher priority again. */
if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
{