main.c File Reference


Detailed Description

FreeRTOS Real Time Kernel example.

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.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

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 Documentation

#define mainBLOCK_Q_PRIORITY   ( tskIDLE_PRIORITY + 3 )

Definition at line 118 of file main.c.

Referenced by main().

#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 )

Definition at line 119 of file main.c.

Referenced by main().

#define mainCOM_TEST_BAUD_RATE   ( ( unsigned portLONG ) 57600 )

Baud rate used by the serial port tasks.

Definition at line 124 of file main.c.

Referenced by main().

#define mainCOM_TEST_LED   ( 3 )

LED used by the serial port tasks.

This is toggled on each character Tx, and mainCOM_TEST_LED + 1 is toggled on each character Rx.

Definition at line 128 of file main.c.

Referenced by main().

#define mainCOM_TEST_PRIORITY   ( tskIDLE_PRIORITY + 2 )

Definition at line 115 of file main.c.

Referenced by main().

#define mainCOUNT_INITIAL_VALUE   ( ( unsigned portLONG ) 0 )

Definition at line 148 of file main.c.

Referenced by vErrorChecks(), and vMemCheckTask().

#define mainCREATOR_TASK_PRIORITY   ( tskIDLE_PRIORITY + 3 )

Definition at line 120 of file main.c.

Referenced by vErrorChecks().

#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 )

Definition at line 114 of file main.c.

Referenced by main().

#define mainMEM_CHECK_SIZE_1   ( ( size_t ) 51 )

Definition at line 155 of file main.c.

Referenced by vMemCheckTask().

#define mainMEM_CHECK_SIZE_2   ( ( size_t ) 52 )

Definition at line 156 of file main.c.

Referenced by vMemCheckTask().

#define mainMEM_CHECK_SIZE_3   ( ( size_t ) 15 )

Definition at line 157 of file main.c.

Referenced by vMemCheckTask().

#define mainNO_TASK   ( 0 )

Definition at line 149 of file main.c.

Referenced by vErrorChecks().

#define mainQUEUE_POLL_PRIORITY   ( tskIDLE_PRIORITY + 2 )

Definition at line 116 of file main.c.

Referenced by main().

#define mainSEM_TEST_PRIORITY   ( tskIDLE_PRIORITY + 1 )

Definition at line 117 of file main.c.

Referenced by main().


Function Documentation

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.

Parameters:
*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 /*-----------------------------------------------------------*/


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