#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "countsem.h"
Go to the source code of this file.
Data Structures | |
struct | COUNT_SEM_STRUCT |
Defines | |
#define | countDONT_BLOCK ( 0 ) |
#define | countMAX_COUNT_VALUE ( 200 ) |
#define | countNUM_TEST_TASKS ( 2 ) |
#define | countSTART_AT_MAX_COUNT ( 0xaa ) |
#define | countSTART_AT_ZERO ( 0x55 ) |
Typedefs | |
typedef struct COUNT_SEM_STRUCT | xCountSemStruct |
Functions | |
static void | prvCountingSemaphoreTask (void *pvParameters) |
static void | prvDecrementSemaphoreCount (xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter) |
static void | prvIncrementSemaphoreCount (xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter) |
void | vStartCountingSemaphoreTasks (void) |
portBASE_TYPE | xAreCountingSemaphoreTasksStillRunning (void) |
Variables | |
static volatile portBASE_TYPE | xErrorDetected = pdFALSE |
static volatile xCountSemStruct | xParameters [countNUM_TEST_TASKS] |
#define countDONT_BLOCK ( 0 ) |
Definition at line 80 of file countsem.c.
Referenced by prvDecrementSemaphoreCount(), and prvIncrementSemaphoreCount().
#define countMAX_COUNT_VALUE ( 200 ) |
Definition at line 68 of file countsem.c.
Referenced by prvDecrementSemaphoreCount(), prvIncrementSemaphoreCount(), and vStartCountingSemaphoreTasks().
#define countNUM_TEST_TASKS ( 2 ) |
Definition at line 79 of file countsem.c.
#define countSTART_AT_MAX_COUNT ( 0xaa ) |
Definition at line 74 of file countsem.c.
Referenced by prvCountingSemaphoreTask(), and vStartCountingSemaphoreTasks().
#define countSTART_AT_ZERO ( 0x55 ) |
Definition at line 75 of file countsem.c.
typedef struct COUNT_SEM_STRUCT xCountSemStruct |
static void prvCountingSemaphoreTask | ( | void * | pvParameters | ) | [static] |
Definition at line 238 of file countsem.c.
References countSTART_AT_MAX_COUNT, pdPASS, pdTRUE, portCHAR, prvDecrementSemaphoreCount(), prvIncrementSemaphoreCount(), COUNT_SEM_STRUCT::uxExpectedStartCount, COUNT_SEM_STRUCT::uxLoopCounter, vPrintDisplayMessage(), xErrorDetected, COUNT_SEM_STRUCT::xSemaphore, and xSemaphoreTake.
Referenced by vStartCountingSemaphoreTasks().
00239 { 00240 xCountSemStruct *pxParameter; 00241 00242 #ifdef USE_STDIO 00243 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); 00244 00245 const portCHAR * const pcTaskStartMsg = "Counting semaphore demo started.\r\n"; 00246 00247 /* Queue a message for printing to say the task has started. */ 00248 vPrintDisplayMessage( &pcTaskStartMsg ); 00249 #endif 00250 00251 /* The semaphore to be used was passed as the parameter. */ 00252 pxParameter = ( xCountSemStruct * ) pvParameters; 00253 00254 /* Did we expect to find the semaphore already at its max count value, or 00255 at zero? */ 00256 if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT ) 00257 { 00258 prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); 00259 } 00260 00261 /* Now we expect the semaphore count to be 0, so this time there is an 00262 error if we can take the semaphore. */ 00263 if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS ) 00264 { 00265 xErrorDetected = pdTRUE; 00266 } 00267 00268 for( ;; ) 00269 { 00270 prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); 00271 prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); 00272 } 00273 }
static void prvDecrementSemaphoreCount | ( | xSemaphoreHandle | xSemaphore, | |
unsigned portBASE_TYPE * | puxLoopCounter | |||
) | [static] |
Definition at line 166 of file countsem.c.
References countDONT_BLOCK, countMAX_COUNT_VALUE, pdPASS, pdTRUE, portBASE_TYPE, taskYIELD, xErrorDetected, xSemaphoreGive, and xSemaphoreTake.
Referenced by prvCountingSemaphoreTask().
00167 { 00168 unsigned portBASE_TYPE ux; 00169 00170 /* If the semaphore count is at its maximum then we should not be able to 00171 'give' the semaphore. */ 00172 if( xSemaphoreGive( xSemaphore ) == pdPASS ) 00173 { 00174 xErrorDetected = pdTRUE; 00175 } 00176 00177 /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */ 00178 for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) 00179 { 00180 if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS ) 00181 { 00182 /* We expected to be able to take the semaphore. */ 00183 xErrorDetected = pdTRUE; 00184 } 00185 00186 ( *puxLoopCounter )++; 00187 } 00188 00189 #if configUSE_PREEMPTION == 0 00190 taskYIELD(); 00191 #endif 00192 00193 /* If the semaphore count is zero then we should not be able to 'take' 00194 the semaphore. */ 00195 if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) 00196 { 00197 xErrorDetected = pdTRUE; 00198 } 00199 }
static void prvIncrementSemaphoreCount | ( | xSemaphoreHandle | xSemaphore, | |
unsigned portBASE_TYPE * | puxLoopCounter | |||
) | [static] |
Definition at line 202 of file countsem.c.
References countDONT_BLOCK, countMAX_COUNT_VALUE, pdPASS, pdTRUE, portBASE_TYPE, taskYIELD, xErrorDetected, xSemaphoreGive, and xSemaphoreTake.
Referenced by prvCountingSemaphoreTask().
00203 { 00204 unsigned portBASE_TYPE ux; 00205 00206 /* If the semaphore count is zero then we should not be able to 'take' 00207 the semaphore. */ 00208 if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) 00209 { 00210 xErrorDetected = pdTRUE; 00211 } 00212 00213 /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */ 00214 for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) 00215 { 00216 if( xSemaphoreGive( xSemaphore ) != pdPASS ) 00217 { 00218 /* We expected to be able to take the semaphore. */ 00219 xErrorDetected = pdTRUE; 00220 } 00221 00222 ( *puxLoopCounter )++; 00223 } 00224 00225 #if configUSE_PREEMPTION == 0 00226 taskYIELD(); 00227 #endif 00228 00229 /* If the semaphore count is at its maximum then we should not be able to 00230 'give' the semaphore. */ 00231 if( xSemaphoreGive( xSemaphore ) == pdPASS ) 00232 { 00233 xErrorDetected = pdTRUE; 00234 } 00235 }
void vStartCountingSemaphoreTasks | ( | void | ) |
Definition at line 133 of file countsem.c.
References configMINIMAL_STACK_SIZE, countMAX_COUNT_VALUE, countSTART_AT_MAX_COUNT, portCHAR, prvCountingSemaphoreTask(), tskIDLE_PRIORITY, COUNT_SEM_STRUCT::uxExpectedStartCount, COUNT_SEM_STRUCT::uxLoopCounter, vQueueAddToRegistry, COUNT_SEM_STRUCT::xSemaphore, xSemaphoreCreateCounting, and xTaskCreate.
00134 { 00135 /* Create the semaphores that we are going to use for the test/demo. The 00136 first should be created such that it starts at its maximum count value, 00137 the second should be created such that it starts with a count value of zero. */ 00138 xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE ); 00139 xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT; 00140 xParameters[ 0 ].uxLoopCounter = 0; 00141 00142 xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 ); 00143 xParameters[ 1 ].uxExpectedStartCount = 0; 00144 xParameters[ 1 ].uxLoopCounter = 0; 00145 00146 /* vQueueAddToRegistry() adds the semaphore to the registry, if one is 00147 in use. The registry is provided as a means for kernel aware 00148 debuggers to locate semaphores and has no purpose if a kernel aware debugger 00149 is not being used. The call to vQueueAddToRegistry() will be removed 00150 by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 00151 defined to be less than 1. */ 00152 vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 0 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_1" ); 00153 vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 1 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_2" ); 00154 00155 00156 /* Were the semaphores created? */ 00157 if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) ) 00158 { 00159 /* Create the demo tasks, passing in the semaphore to use as the parameter. */ 00160 xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL ); 00161 xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL ); 00162 } 00163 }
portBASE_TYPE xAreCountingSemaphoreTasksStillRunning | ( | void | ) |
Definition at line 276 of file countsem.c.
References pdFAIL, pdFALSE, pdPASS, portBASE_TYPE, COUNT_SEM_STRUCT::uxLoopCounter, and xErrorDetected.
00277 { 00278 static unsigned portBASE_TYPE uxLastCount0 = 0, uxLastCount1 = 0; 00279 portBASE_TYPE xReturn = pdPASS; 00280 00281 /* Return fail if any 'give' or 'take' did not result in the expected 00282 behaviour. */ 00283 if( xErrorDetected != pdFALSE ) 00284 { 00285 xReturn = pdFAIL; 00286 } 00287 00288 /* Return fail if either task is not still incrementing its loop counter. */ 00289 if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter ) 00290 { 00291 xReturn = pdFAIL; 00292 } 00293 else 00294 { 00295 uxLastCount0 = xParameters[ 0 ].uxLoopCounter; 00296 } 00297 00298 if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter ) 00299 { 00300 xReturn = pdFAIL; 00301 } 00302 else 00303 { 00304 uxLastCount1 = xParameters[ 1 ].uxLoopCounter; 00305 } 00306 00307 return xReturn; 00308 }
volatile portBASE_TYPE xErrorDetected = pdFALSE [static] |
Definition at line 86 of file countsem.c.
volatile xCountSemStruct xParameters[countNUM_TEST_TASKS] [static] |
Definition at line 129 of file countsem.c.