Creates all the demo application tasks, then starts the scheduler. The WEB documentation provides more details of the demo application tasks.
Main. c also creates a task called "Check". This only executes every three seconds but has the highest priority so is guaranteed to get processor time. Its main function is to check that all the other tasks are still operational. Each task that does not flash an LED maintains a unique count that is incremented each time the task successfully completes its function. Should any error occur within such a task the count is permanently halted. The check task inspects the count of each task to ensure it has changed since the last time the check task executed. If all the count variables have changed all the tasks are still executing error free, and the check task toggles an LED. Should any task contain an error at any time the LED toggle will stop.
The LED flash and communications test tasks do not maintain a count.
Definition in file main.c.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "power_clocks_lib.h"
#include "FreeRTOS.h"
#include "task.h"
#include "partest.h"
#include "serial.h"
#include "integer.h"
#include "comtest.h"
#include "flash.h"
#include "PollQ.h"
#include "semtest.h"
#include "dynamic.h"
#include "BlockQ.h"
#include "death.h"
#include "flop.h"
Go to the source code of this file.
Defines | |
#define | mainCHECK_PERIOD ( ( portTickType ) 3000 / portTICK_RATE_MS ) |
The period between executions of the check task. | |
#define | mainCHECK_TASK_LED ( 6 ) |
LED that is toggled by the check task. | |
#define | mainCOM_TEST_BAUD_RATE ( ( unsigned portLONG ) 57600 ) |
Baud rate used by the serial port tasks. | |
#define | mainCOM_TEST_LED ( 3 ) |
LED used by the serial port tasks. | |
#define | mainERROR_FLASH_RATE ( (portTickType) 500 / portTICK_RATE_MS ) |
If an error is detected in a task, the vErrorChecks task will enter in an infinite loop flashing the LED at this rate. | |
#define | mainERROR_LED ( 7 ) |
LED that is set upon error. | |
Priority definitions for most of the tasks in the demo application. | |
Some tasks just use the idle priority. | |
#define | mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 ) |
#define | mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) |
#define | mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) |
#define | mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) |
#define | mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) |
#define | mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) |
#define | mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) |
Constants used by the vMemCheckTask() task. | |
#define | mainCOUNT_INITIAL_VALUE ( ( unsigned portLONG ) 0 ) |
#define | mainNO_TASK ( 0 ) |
The size of the memory blocks allocated by the vMemCheckTask() task. | |
#define | mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 ) |
#define | mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 ) |
#define | mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 ) |
Functions | |
int | main (void) |
static portBASE_TYPE | prvCheckOtherTasksAreStillRunning (void) |
Checks that all the demo application tasks are still executing without error. | |
static void | prvIndicateError (void) |
static void | vErrorChecks (void *pvParameters) |
The task function for the "Check" task. | |
static void | vMemCheckTask (void *pvParameters) |
Dynamically created and deleted during each cycle of the vErrorChecks() task. This is done to check the operation of the memory allocator. See the top of vErrorChecks for more details. |
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 ) |
#define mainCHECK_PERIOD ( ( portTickType ) 3000 / portTICK_RATE_MS ) |
The period between executions of the check task.
Definition at line 139 of file main.c.
Referenced by vErrorChecks().
#define mainCHECK_TASK_LED ( 6 ) |
LED that is toggled by the check task.
The check task periodically checks that all the other tasks are operating without error. If no errors are found the LED is toggled. If an error is found at any time the LED toggles faster.
Definition at line 133 of file main.c.
Referenced by prvIndicateError(), and vErrorChecks().
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) |
#define mainCOM_TEST_BAUD_RATE ( ( unsigned portLONG ) 57600 ) |
#define mainCOM_TEST_LED ( 3 ) |
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) |
#define mainCOUNT_INITIAL_VALUE ( ( unsigned portLONG ) 0 ) |
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) |
#define mainERROR_FLASH_RATE ( (portTickType) 500 / portTICK_RATE_MS ) |
If an error is detected in a task, the vErrorChecks task will enter in an infinite loop flashing the LED at this rate.
Definition at line 143 of file main.c.
Referenced by prvIndicateError().
#define mainERROR_LED ( 7 ) |
LED that is set upon error.
Definition at line 136 of file main.c.
Referenced by prvIndicateError().
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) |
#define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 ) |
#define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 ) |
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 ) |
#define mainNO_TASK ( 0 ) |
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) |
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) |
int main | ( | void | ) |
Definition at line 189 of file main.c.
References configMINIMAL_STACK_SIZE, mainBLOCK_Q_PRIORITY, mainCHECK_TASK_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED, mainCOM_TEST_PRIORITY, mainLED_TASK_PRIORITY, mainQUEUE_POLL_PRIORITY, mainSEM_TEST_PRIORITY, portCHAR, portDBG_TRACE, tskIDLE_PRIORITY, vAltStartComTestTasks(), vErrorChecks(), vParTestInitialise(), vStartBlockingQueueTasks(), vStartDynamicPriorityTasks(), vStartIntegerMathTasks(), vStartLEDFlashTasks(), vStartMathTasks(), vStartPolledQueueTasks(), vStartSemaphoreTasks(), vTaskStartScheduler(), and xTaskCreate.
00190 { 00191 // Configure Osc0 in crystal mode (i.e. use of an external crystal source, with 00192 // frequency FOSC0) with an appropriate startup time then switch the main clock 00193 // source to Osc0. 00194 pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); 00195 00196 portDBG_TRACE("Starting the FreeRTOS AVR32 UC3 Demo..."); 00197 00198 /* Setup the LED's for output. */ 00199 vParTestInitialise(); 00200 00201 /* Start the standard demo tasks. See the WEB documentation for more 00202 information. */ 00203 vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); 00204 vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); 00205 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); 00206 vStartIntegerMathTasks( tskIDLE_PRIORITY ); 00207 vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); 00208 vStartDynamicPriorityTasks(); 00209 #if BOARD != EVK1101 00210 vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); 00211 vStartMathTasks( tskIDLE_PRIORITY ); 00212 #endif 00213 00214 /* Start the demo tasks defined within this file, specifically the check 00215 task as described at the top of this file. */ 00216 xTaskCreate( 00217 vErrorChecks 00218 , (const signed portCHAR *)"ErrCheck" 00219 , configMINIMAL_STACK_SIZE 00220 , NULL 00221 , mainCHECK_TASK_PRIORITY 00222 , NULL ); 00223 00224 /* Start the scheduler. */ 00225 vTaskStartScheduler(); 00226 00227 /* Will only get here if there was insufficient memory to create the idle 00228 task. */ 00229 00230 return 0; 00231 }
static portBASE_TYPE prvCheckOtherTasksAreStillRunning | ( | void | ) | [static] |
Checks that all the demo application tasks are still executing without error.
Definition at line 331 of file main.c.
References pdFALSE, pdTRUE, portBASE_TYPE, xAreBlockingQueuesStillRunning(), xAreComTestTasksStillRunning(), xAreDynamicPriorityTasksStillRunning(), xAreIntegerMathsTaskStillRunning(), xAreMathsTaskStillRunning(), xArePollingQueuesStillRunning(), xAreSemaphoreTasksStillRunning(), and xIsCreateTaskStillRunning().
Referenced by vErrorChecks().
00332 { 00333 static portBASE_TYPE xErrorHasOccurred = pdFALSE; 00334 00335 if( xAreComTestTasksStillRunning() != pdTRUE ) 00336 { 00337 xErrorHasOccurred = pdTRUE; 00338 } 00339 00340 if( xArePollingQueuesStillRunning() != pdTRUE ) 00341 { 00342 xErrorHasOccurred = pdTRUE; 00343 } 00344 00345 if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) 00346 { 00347 xErrorHasOccurred = pdTRUE; 00348 } 00349 00350 if( xAreSemaphoreTasksStillRunning() != pdTRUE ) 00351 { 00352 xErrorHasOccurred = pdTRUE; 00353 } 00354 00355 #if BOARD != EVK1101 00356 if( xAreBlockingQueuesStillRunning() != pdTRUE ) 00357 { 00358 xErrorHasOccurred = pdTRUE; 00359 } 00360 #endif 00361 00362 if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) 00363 { 00364 xErrorHasOccurred = pdTRUE; 00365 } 00366 00367 #if BOARD != EVK1101 00368 if( xAreMathsTaskStillRunning() != pdTRUE ) 00369 { 00370 xErrorHasOccurred = pdTRUE; 00371 } 00372 #endif 00373 00374 if( xIsCreateTaskStillRunning() != pdTRUE ) 00375 { 00376 xErrorHasOccurred = pdTRUE; 00377 } 00378 00379 return ( xErrorHasOccurred ); 00380 }
static void prvIndicateError | ( | void | ) | [static] |
Definition at line 481 of file main.c.
References mainCHECK_TASK_LED, mainERROR_FLASH_RATE, mainERROR_LED, pdTRUE, vParTestSetLED(), vParTestToggleLED(), and vTaskDelay().
Referenced by vErrorChecks().
00481 { 00482 /* The check task has found an error in one of the other tasks. 00483 Set the LEDs to a state that indicates this. */ 00484 vParTestSetLED(mainERROR_LED,pdTRUE); 00485 00486 #if BOARD == EVK1101 || BOARD == EVK1104 || BOARD == EVK1105 00487 /* Set all LEDs to the same initial state before toggling them. */ 00488 vParTestSetLED( 0, pdTRUE ); 00489 vParTestSetLED( 1, pdTRUE ); 00490 vParTestSetLED( 2, pdTRUE ); 00491 vParTestSetLED( 3, pdTRUE ); 00492 #endif 00493 00494 for(;;) 00495 { 00496 #if BOARD == EVK1100 00497 vParTestToggleLED( mainCHECK_TASK_LED ); 00498 vTaskDelay( mainERROR_FLASH_RATE ); 00499 #elif BOARD == EVK1101 || BOARD == EVK1104 || BOARD == EVK1105 || BOARD == UC3C_EK 00500 vParTestToggleLED( 0 ); 00501 vParTestToggleLED( 1 ); 00502 vParTestToggleLED( 2 ); 00503 vParTestToggleLED( 3 ); 00504 vTaskDelay( mainERROR_FLASH_RATE ); 00505 #else 00506 #error You should define here the way of indicating an error on your board 00507 #endif 00508 } 00509 } 00510 }
static void vErrorChecks | ( | void * | pvParameters | ) | [static] |
The task function for the "Check" task.
Definition at line 237 of file main.c.
References configMINIMAL_STACK_SIZE, mainCHECK_PERIOD, mainCHECK_TASK_LED, mainCOUNT_INITIAL_VALUE, mainCREATOR_TASK_PRIORITY, mainNO_TASK, pdFALSE, pdPASS, portBASE_TYPE, portCHAR, portLONG, prvCheckOtherTasksAreStillRunning(), prvIndicateError(), tskIDLE_PRIORITY, vCreateSuicidalTasks(), vMemCheckTask(), vParTestToggleLED(), vTaskDelay(), vTaskDelete(), xCreatedTask, and xTaskCreate.
Referenced by main().
00238 { 00239 static volatile unsigned portLONG ulDummyVariable = 3UL; 00240 unsigned portLONG ulMemCheckTaskRunningCount; 00241 xTaskHandle xCreatedTask; 00242 portBASE_TYPE bSuicidalTask = 0; 00243 00244 /* The parameters are not used. Prevent compiler warnings. */ 00245 ( void ) pvParameters; 00246 00247 /* Cycle for ever, delaying then checking all the other tasks are still 00248 operating without error. 00249 00250 In addition to the standard tests the memory allocator is tested through 00251 the dynamic creation and deletion of a task each cycle. Each time the 00252 task is created memory must be allocated for its stack. When the task is 00253 deleted this memory is returned to the heap. If the task cannot be created 00254 then it is likely that the memory allocation failed. */ 00255 00256 for( ;; ) 00257 { 00258 /* Do this only once. */ 00259 if( bSuicidalTask == 0 ) 00260 { 00261 bSuicidalTask++; 00262 00263 /* This task has to be created last as it keeps account of the number of 00264 tasks it expects to see running. However its implementation expects 00265 to be called before vTaskStartScheduler(). We're in the case here where 00266 vTaskStartScheduler() has already been called (thus the hidden IDLE task 00267 has already been spawned). Since vCreateSuicidalTask() supposes that the 00268 IDLE task isn't included in the response from uxTaskGetNumberOfTasks(), 00269 let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks() 00270 is not called as the last task. */ 00271 vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); 00272 } 00273 00274 /* Reset xCreatedTask. This is modified by the task about to be 00275 created so we can tell if it is executing correctly or not. */ 00276 xCreatedTask = mainNO_TASK; 00277 00278 /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a 00279 parameter. */ 00280 ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; 00281 00282 if( xTaskCreate( vMemCheckTask, 00283 ( signed portCHAR * ) "MEM_CHECK", 00284 configMINIMAL_STACK_SIZE, 00285 ( void * ) &ulMemCheckTaskRunningCount, 00286 tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS ) 00287 { 00288 /* Could not create the task - we have probably run out of heap. 00289 Don't go any further and flash the LED faster to provide visual 00290 feedback of the error. */ 00291 prvIndicateError(); 00292 } 00293 00294 /* Delay until it is time to execute again. */ 00295 vTaskDelay( mainCHECK_PERIOD ); 00296 00297 /* Delete the dynamically created task. */ 00298 if( xCreatedTask != mainNO_TASK ) 00299 { 00300 vTaskDelete( xCreatedTask ); 00301 } 00302 00303 /* Perform a bit of 32bit maths to ensure the registers used by the 00304 integer tasks get some exercise. The result here is not important - 00305 see the demo application documentation for more info. */ 00306 ulDummyVariable *= 3; 00307 00308 /* Check all other tasks are still operating without error. 00309 Check that vMemCheckTask did increment the counter. */ 00310 if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) 00311 || ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) ) 00312 { 00313 /* An error has occurred in one of the tasks. 00314 Don't go any further and flash the LED faster to give visual 00315 feedback of the error. */ 00316 prvIndicateError(); 00317 } 00318 else 00319 { 00320 /* Toggle the LED if everything is okay. */ 00321 vParTestToggleLED( mainCHECK_TASK_LED ); 00322 } 00323 } 00324 }
static void vMemCheckTask | ( | void * | pvParameters | ) | [static] |
Dynamically created and deleted during each cycle of the vErrorChecks() task. This is done to check the operation of the memory allocator. See the top of vErrorChecks for more details.
*pvParameters | Parameters for the task (can be of any kind) |
Definition at line 391 of file main.c.
References mainCOUNT_INITIAL_VALUE, mainMEM_CHECK_SIZE_1, mainMEM_CHECK_SIZE_2, mainMEM_CHECK_SIZE_3, pdFALSE, pdTRUE, portLONG, pvPortMalloc(), vPortFree(), vTaskSuspendAll(), and xTaskResumeAll().
Referenced by vErrorChecks().
00392 { 00393 unsigned portLONG *pulMemCheckTaskRunningCounter; 00394 void *pvMem1, *pvMem2, *pvMem3; 00395 static portLONG lErrorOccurred = pdFALSE; 00396 00397 /* This task is dynamically created then deleted during each cycle of the 00398 vErrorChecks task to check the operation of the memory allocator. Each time 00399 the task is created memory is allocated for the stack and TCB. Each time 00400 the task is deleted this memory is returned to the heap. This task itself 00401 exercises the allocator by allocating and freeing blocks. 00402 00403 The task executes at the idle priority so does not require a delay. 00404 00405 pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the 00406 vErrorChecks() task that this task is still executing without error. */ 00407 00408 pulMemCheckTaskRunningCounter = ( unsigned portLONG * ) pvParameters; 00409 00410 for( ;; ) 00411 { 00412 if( lErrorOccurred == pdFALSE ) 00413 { 00414 /* We have never seen an error so increment the counter. */ 00415 ( *pulMemCheckTaskRunningCounter )++; 00416 } 00417 else 00418 { 00419 /* There has been an error so reset the counter so the check task 00420 can tell that an error occurred. */ 00421 *pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE; 00422 } 00423 00424 /* Allocate some memory - just to give the allocator some extra 00425 exercise. This has to be in a critical section to ensure the 00426 task does not get deleted while it has memory allocated. */ 00427 00428 vTaskSuspendAll(); 00429 { 00430 pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 ); 00431 00432 if( pvMem1 == NULL ) 00433 { 00434 lErrorOccurred = pdTRUE; 00435 } 00436 else 00437 { 00438 memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 ); 00439 vPortFree( pvMem1 ); 00440 } 00441 } 00442 xTaskResumeAll(); 00443 00444 /* Again - with a different size block. */ 00445 vTaskSuspendAll(); 00446 { 00447 pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); 00448 00449 if( pvMem2 == NULL ) 00450 { 00451 lErrorOccurred = pdTRUE; 00452 } 00453 else 00454 { 00455 memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 ); 00456 vPortFree( pvMem2 ); 00457 } 00458 } 00459 xTaskResumeAll(); 00460 00461 /* Again - with a different size block. */ 00462 vTaskSuspendAll(); 00463 { 00464 pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); 00465 if( pvMem3 == NULL ) 00466 { 00467 lErrorOccurred = pdTRUE; 00468 } 00469 else 00470 { 00471 memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 ); 00472 vPortFree( pvMem3 ); 00473 } 00474 } 00475 xTaskResumeAll(); 00476 } 00477 } 00478 /*-----------------------------------------------------------*/