dynamic.c File Reference

#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "dynamic.h"

Go to the source code of this file.

Defines

#define priLOOPS   ( 5 )
#define priMAX_COUNT   ( ( unsigned long ) 0xff )
#define priNO_BLOCK   ( ( portTickType ) 0 )
#define priSLEEP_TIME   ( ( portTickType ) 128 / portTICK_RATE_MS )
#define priSTACK_SIZE   ( configMINIMAL_STACK_SIZE )
#define priSUSPENDED_QUEUE_LENGTH   ( 1 )

Functions

static portTASK_FUNCTION (vQueueReceiveWhenSuspendedTask, pvParameters)
static portTASK_FUNCTION (vQueueSendWhenSuspendedTask, pvParameters)
static portTASK_FUNCTION (vCounterControlTask, pvParameters)
static portTASK_FUNCTION (vContinuousIncrementTask, pvParameters)
static portTASK_FUNCTION (vLimitedIncrementTask, pvParameters)
static portTASK_FUNCTION_PROTO (vQueueSendWhenSuspendedTask, pvParameters)
static portTASK_FUNCTION_PROTO (vQueueReceiveWhenSuspendedTask, pvParameters)
static portTASK_FUNCTION_PROTO (vCounterControlTask, pvParameters)
static portTASK_FUNCTION_PROTO (vContinuousIncrementTask, pvParameters)
static portTASK_FUNCTION_PROTO (vLimitedIncrementTask, pvParameters)
void vStartDynamicPriorityTasks (void)
portBASE_TYPE xAreDynamicPriorityTasksStillRunning (void)

Variables

static unsigned long ulCounter
static volatile unsigned short usCheckVariable = ( unsigned short ) 0
static xTaskHandle xContinousIncrementHandle
static xTaskHandle xLimitedIncrementHandle
static volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE
static volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE
xQueueHandle xSuspendedTestQueue


Define Documentation

#define priLOOPS   ( 5 )

Definition at line 136 of file dynamic.c.

Referenced by portTASK_FUNCTION().

#define priMAX_COUNT   ( ( unsigned long ) 0xff )

Definition at line 137 of file dynamic.c.

Referenced by portTASK_FUNCTION().

#define priNO_BLOCK   ( ( portTickType ) 0 )

Definition at line 138 of file dynamic.c.

Referenced by portTASK_FUNCTION().

#define priSLEEP_TIME   ( ( portTickType ) 128 / portTICK_RATE_MS )

Definition at line 135 of file dynamic.c.

Referenced by portTASK_FUNCTION().

#define priSTACK_SIZE   ( configMINIMAL_STACK_SIZE )

Definition at line 134 of file dynamic.c.

Referenced by vStartDynamicPriorityTasks().

#define priSUSPENDED_QUEUE_LENGTH   ( 1 )

Definition at line 139 of file dynamic.c.

Referenced by vStartDynamicPriorityTasks().


Function Documentation

static portTASK_FUNCTION ( vQueueReceiveWhenSuspendedTask  ,
pvParameters   
) [static]

Definition at line 350 of file dynamic.c.

References pdFALSE, pdTRUE, portBASE_TYPE, priNO_BLOCK, taskYIELD, vTaskSuspendAll(), xQueueReceive, xSuspendedQueueReceiveError, xSuspendedTestQueue, and xTaskResumeAll().

00351 {
00352 static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue;
00353 portBASE_TYPE xGotValue;
00354 
00355     /* Just to stop warning messages. */
00356     ( void ) pvParameters;
00357 
00358     for( ;; )
00359     {
00360         do
00361         {
00362             /* Suspending the scheduler here is fairly pointless and 
00363             undesirable for a normal application.  It is done here purely
00364             to test the scheduler.  The inner xTaskResumeAll() should
00365             never return pdTRUE as the scheduler is still locked by the
00366             outer call. */
00367             vTaskSuspendAll();
00368             {
00369                 vTaskSuspendAll();
00370                 {
00371                     xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );
00372                 }
00373                 if( xTaskResumeAll() )
00374                 {
00375                     xSuspendedQueueReceiveError = pdTRUE;
00376                 }
00377             }
00378             xTaskResumeAll();
00379 
00380             #if configUSE_PREEMPTION == 0
00381             {
00382                 taskYIELD();
00383             }
00384             #endif
00385 
00386         } while( xGotValue == pdFALSE );
00387 
00388         if( ulReceivedValue != ulExpectedValue )
00389         {
00390             xSuspendedQueueReceiveError = pdTRUE;
00391         }
00392 
00393         ++ulExpectedValue;
00394     }
00395 }

static portTASK_FUNCTION ( vQueueSendWhenSuspendedTask  ,
pvParameters   
) [static]

Definition at line 324 of file dynamic.c.

References pdTRUE, priNO_BLOCK, priSLEEP_TIME, vTaskDelay(), vTaskSuspendAll(), xQueueSend, xSuspendedQueueSendError, xSuspendedTestQueue, and xTaskResumeAll().

00325 {
00326 static unsigned long ulValueToSend = ( unsigned long ) 0;
00327 
00328     /* Just to stop warning messages. */
00329     ( void ) pvParameters;
00330 
00331     for( ;; )
00332     {
00333         vTaskSuspendAll();
00334         {
00335             /* We must not block while the scheduler is suspended! */
00336             if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )
00337             {
00338                 xSuspendedQueueSendError = pdTRUE;
00339             }
00340         }
00341         xTaskResumeAll();
00342 
00343         vTaskDelay( priSLEEP_TIME );
00344 
00345         ++ulValueToSend;
00346     }
00347 }

static portTASK_FUNCTION ( vCounterControlTask  ,
pvParameters   
) [static]

Definition at line 247 of file dynamic.c.

References pdFALSE, pdTRUE, portENTER_CRITICAL, portEXIT_CRITICAL, priLOOPS, priMAX_COUNT, priSLEEP_TIME, ulCounter, usCheckVariable, vTaskDelay(), vTaskResume(), vTaskSuspend(), vTaskSuspendAll(), xContinousIncrementHandle, xLimitedIncrementHandle, and xTaskResumeAll().

00248 {
00249 unsigned long ulLastCounter;
00250 short sLoops;
00251 short sError = pdFALSE;
00252 
00253     /* Just to stop warning messages. */
00254     ( void ) pvParameters;
00255 
00256     for( ;; )
00257     {
00258         /* Start with the counter at zero. */
00259         ulCounter = ( unsigned long ) 0;
00260 
00261         /* First section : */
00262 
00263         /* Check the continuous count task is running. */
00264         for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
00265         {
00266             /* Suspend the continuous count task so we can take a mirror of the
00267             shared variable without risk of corruption. */
00268             vTaskSuspend( xContinousIncrementHandle );
00269                 ulLastCounter = ulCounter;
00270             vTaskResume( xContinousIncrementHandle );
00271             
00272             /* Now delay to ensure the other task has processor time. */
00273             vTaskDelay( priSLEEP_TIME );
00274 
00275             /* Check the shared variable again.  This time to ensure mutual 
00276             exclusion the whole scheduler will be locked.  This is just for
00277             demo purposes! */
00278             vTaskSuspendAll();
00279             {
00280                 if( ulLastCounter == ulCounter )
00281                 {
00282                     /* The shared variable has not changed.  There is a problem
00283                     with the continuous count task so flag an error. */
00284                     sError = pdTRUE;
00285                 }
00286             }
00287             xTaskResumeAll();
00288         }
00289 
00290 
00291         /* Second section: */
00292 
00293         /* Suspend the continuous counter task so it stops accessing the shared variable. */
00294         vTaskSuspend( xContinousIncrementHandle );
00295 
00296         /* Reset the variable. */
00297         ulCounter = ( unsigned long ) 0;
00298 
00299         /* Resume the limited count task which has a higher priority than us.
00300         We should therefore not return from this call until the limited count
00301         task has suspended itself with a known value in the counter variable. */
00302         vTaskResume( xLimitedIncrementHandle );
00303 
00304         /* Does the counter variable have the expected value? */
00305         if( ulCounter != priMAX_COUNT )
00306         {
00307             sError = pdTRUE;
00308         }
00309 
00310         if( sError == pdFALSE )
00311         {
00312             /* If no errors have occurred then increment the check variable. */
00313             portENTER_CRITICAL();
00314                 usCheckVariable++;
00315             portEXIT_CRITICAL();
00316         }
00317 
00318         /* Resume the continuous count task and do it all again. */
00319         vTaskResume( xContinousIncrementHandle );
00320     }
00321 }

static portTASK_FUNCTION ( vContinuousIncrementTask  ,
pvParameters   
) [static]

Definition at line 220 of file dynamic.c.

References portBASE_TYPE, uxTaskPriorityGet(), and vTaskPrioritySet().

00221 {
00222 unsigned long *pulCounter;
00223 unsigned portBASE_TYPE uxOurPriority;
00224 
00225     /* Take a pointer to the shared variable from the parameters passed into
00226     the task. */
00227     pulCounter = ( unsigned long * ) pvParameters;
00228 
00229     /* Query our priority so we can raise it when exclusive access to the 
00230     shared variable is required. */
00231     uxOurPriority = uxTaskPriorityGet( NULL );
00232 
00233     for( ;; )
00234     {
00235         /* Raise our priority above the controller task to ensure a context
00236         switch does not occur while we are accessing this variable. */
00237         vTaskPrioritySet( NULL, uxOurPriority + 1 );
00238             ( *pulCounter )++;      
00239         vTaskPrioritySet( NULL, uxOurPriority );
00240     }
00241 }

static portTASK_FUNCTION ( vLimitedIncrementTask  ,
pvParameters   
) [static]

Definition at line 191 of file dynamic.c.

References priMAX_COUNT, and vTaskSuspend().

00192 {
00193 unsigned long *pulCounter;
00194 
00195     /* Take a pointer to the shared variable from the parameters passed into
00196     the task. */
00197     pulCounter = ( unsigned long * ) pvParameters;
00198 
00199     /* This will run before the control task, so the first thing it does is
00200     suspend - the control task will resume it when ready. */
00201     vTaskSuspend( NULL );
00202 
00203     for( ;; )
00204     {
00205         /* Just count up to a value then suspend. */
00206         ( *pulCounter )++;  
00207         
00208         if( *pulCounter >= priMAX_COUNT )
00209         {
00210             vTaskSuspend( NULL );
00211         }   
00212     }
00213 }

static portTASK_FUNCTION_PROTO ( vQueueSendWhenSuspendedTask  ,
pvParameters   
) [static]

static portTASK_FUNCTION_PROTO ( vQueueReceiveWhenSuspendedTask  ,
pvParameters   
) [static]

static portTASK_FUNCTION_PROTO ( vCounterControlTask  ,
pvParameters   
) [static]

static portTASK_FUNCTION_PROTO ( vContinuousIncrementTask  ,
pvParameters   
) [static]

static portTASK_FUNCTION_PROTO ( vLimitedIncrementTask  ,
pvParameters   
) [static]

void vStartDynamicPriorityTasks ( void   ) 

Definition at line 167 of file dynamic.c.

References priSTACK_SIZE, priSUSPENDED_QUEUE_LENGTH, tskIDLE_PRIORITY, ulCounter, vQueueAddToRegistry, xContinousIncrementHandle, xLimitedIncrementHandle, xQueueCreate(), xSuspendedTestQueue, and xTaskCreate.

Referenced by main().

00168 {
00169     xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) );
00170 
00171     /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
00172     in use.  The queue registry is provided as a means for kernel aware 
00173     debuggers to locate queues and has no purpose if a kernel aware debugger
00174     is not being used.  The call to vQueueAddToRegistry() will be removed
00175     by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
00176     defined to be less than 1. */
00177     vQueueAddToRegistry( xSuspendedTestQueue, ( signed char * ) "Suspended_Test_Queue" );
00178 
00179     xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle );
00180     xTaskCreate( vLimitedIncrementTask, ( signed char * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
00181     xTaskCreate( vCounterControlTask, ( signed char * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
00182     xTaskCreate( vQueueSendWhenSuspendedTask, ( signed char * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
00183     xTaskCreate( vQueueReceiveWhenSuspendedTask, ( signed char * ) "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
00184 }

portBASE_TYPE xAreDynamicPriorityTasksStillRunning ( void   ) 

Definition at line 399 of file dynamic.c.

References pdFALSE, pdTRUE, portBASE_TYPE, usCheckVariable, xSuspendedQueueReceiveError, and xSuspendedQueueSendError.

Referenced by prvCheckOtherTasksAreStillRunning().

00400 {
00401 /* Keep a history of the check variables so we know if it has been incremented 
00402 since the last call. */
00403 static unsigned short usLastTaskCheck = ( unsigned short ) 0;
00404 portBASE_TYPE xReturn = pdTRUE;
00405 
00406     /* Check the tasks are still running by ensuring the check variable
00407     is still incrementing. */
00408 
00409     if( usCheckVariable == usLastTaskCheck )
00410     {
00411         /* The check has not incremented so an error exists. */
00412         xReturn = pdFALSE;
00413     }
00414 
00415     if( xSuspendedQueueSendError == pdTRUE )
00416     {
00417         xReturn = pdFALSE;
00418     }
00419 
00420     if( xSuspendedQueueReceiveError == pdTRUE )
00421     {
00422         xReturn = pdFALSE;
00423     }
00424 
00425     usLastTaskCheck = usCheckVariable;
00426     return xReturn;
00427 }


Variable Documentation

unsigned long ulCounter [static]

Definition at line 149 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and vStartDynamicPriorityTasks().

volatile unsigned short usCheckVariable = ( unsigned short ) 0 [static]

Definition at line 155 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and xAreDynamicPriorityTasksStillRunning().

Definition at line 145 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and vStartDynamicPriorityTasks().

Definition at line 145 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and vStartDynamicPriorityTasks().

volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE [static]

Definition at line 157 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and xAreDynamicPriorityTasksStillRunning().

volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE [static]

Definition at line 156 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and xAreDynamicPriorityTasksStillRunning().

Definition at line 160 of file dynamic.c.

Referenced by portTASK_FUNCTION(), and vStartDynamicPriorityTasks().


Generated on Thu Dec 17 20:02:00 2009 for AVR32 UC3 - FreeRTOS Real Time Kernel by  doxygen 1.5.5