#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 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 ) |
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 }
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().
xTaskHandle xContinousIncrementHandle [static] |
Definition at line 145 of file dynamic.c.
Referenced by portTASK_FUNCTION(), and vStartDynamicPriorityTasks().
xTaskHandle xLimitedIncrementHandle [static] |
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().