]> git.sur5r.net Git - freertos/commitdiff
Complete first pass commenting of the new MicroBlaze demo main-blinky.c and main...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jun 2011 09:30:14 +0000 (09:30 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jun 2011 09:30:14 +0000 (09:30 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1476 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-blinky.c
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c

index efc633dfe4babd997299e913cda35c92f2031d63..5a62d0cf78cf28b9a73dfd687b0bd6ae255365d7 100644 (file)
@@ -389,11 +389,16 @@ const unsigned char ucSetToOutput = 0U;
 \r
 void vApplicationMallocFailedHook( void )\r
 {\r
-       /* Called if a call to pvPortMalloc() fails because there is insufficient\r
-       free memory available in the FreeRTOS heap.  pvPortMalloc() is called\r
-       internally by FreeRTOS API functions that create tasks, queues, software\r
-       timers, and semaphores.  The size of the FreeRTOS heap is set by the\r
-       configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */\r
+       /* vApplicationMallocFailedHook() will only be called if\r
+       configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
+       function that will get called if a call to pvPortMalloc() fails. \r
+       pvPortMalloc() is called internally by the kernel whenever a task, queue or\r
+       semaphore is created.  It is also called by various parts of the demo\r
+       application.  If heap_1.c or heap_2.c are used, then the size of the heap\r
+       available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in\r
+       FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used\r
+       to query the size of free heap space that remains (although it does not\r
+       provide information on how the remaining heap might be fragmented). */\r
        taskDISABLE_INTERRUPTS();\r
        for( ;; );\r
 }\r
@@ -404,9 +409,13 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName
        ( void ) pcTaskName;\r
        ( void ) pxTask;\r
 \r
-       /* Run time stack overflow checking is performed if\r
-       configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook\r
-       function is called if a stack overflow is detected. */\r
+       /* vApplicationStackOverflowHook() will only be called if\r
+       configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2.  The handle and name\r
+       of the offending task will be passed into the hook function via its \r
+       parameters.  However, when a stack has overflowed, it is possible that the\r
+       parameters will have been corrupted, in which case the pxCurrentTCB variable\r
+       can be inspected directly. */\r
+       taskDISABLE_INTERRUPTS();\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -415,9 +424,18 @@ void vApplicationIdleHook( void )
 {\r
 volatile size_t xFreeHeapSpace;\r
 \r
-       /* This function is called on each cycle of the idle task.  In this case it\r
-       does nothing useful, other than report the amout of FreeRTOS heap that\r
-       remains unallocated. */\r
+       /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set \r
+       to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle \r
+       task.  It is essential that code added to this hook function never attempts \r
+       to block in any way (for example, call xQueueReceive() with a block time \r
+       specified, or call vTaskDelay()).  If the application makes use of the \r
+       vTaskDelete() API function (as this demo application does) then it is also \r
+       important that vApplicationIdleHook() is permitted to return to its calling \r
+       function, because it is the responsibility of the idle task to clean up \r
+       memory allocated by the kernel to any task that has since been deleted. */\r
+\r
+       /* This implementation of vApplicationIdleHook() simply demonstrates how\r
+       the xPortGetFreeHeapSize() function can be used. */\r
        xFreeHeapSpace = xPortGetFreeHeapSize();\r
 \r
        if( xFreeHeapSpace > 100 )\r
@@ -432,7 +450,11 @@ volatile size_t xFreeHeapSpace;
 \r
 void vApplicationTickHook( void )\r
 {\r
-       /* This simple blinky demo does not use the tick hook, but a tick hook is\r
+       /* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set\r
+       to 1 in FreeRTOSConfig.h.  It executes from an interrupt context so must\r
+       not use any FreeRTOS API functions that do not end in ...FromISR().\r
+\r
+       This simple blinky demo does not use the tick hook, but a tick hook is\r
        required to be defined as the blinky and full demos share a\r
        FreeRTOSConfig.h header file. */
 }\r
@@ -444,7 +466,7 @@ will run on lots of different MicroBlaze and FPGA configurations - not all of
 which will have the same timer peripherals defined or available.  This example\r
 uses the AXI Timer 0.  If that is available on your hardware platform then this\r
 example callback implementation should not require modification.   The name of\r
-the interrupt handler that should be installed in vTickISR(), which the function\r
+the interrupt handler that should be installed is vTickISR(), which the function\r
 below declares as an extern. */\r
 void vApplicationSetupTimerInterrupt( void )\r
 {\r
index 39bbd08404b00eb5dea03c3bce1e5aa015acdb4f..80328ebee3ec9386b2d8d145207cdae17211ef72 100644 (file)
 */\r
 \r
 /* ****************************************************************************\r
- * This project includes a lot of demo and test tasks,  and is therefore complex.\r
- * If you would prefer a much simpler project to get started with, then select\r
- * the 'Blinky' build configuration within the SDK Eclipse IDE.\r
+ * main-blinky.c is included when the "Blinky" build configuration is used.\r
+ * main-full.c is included when the "Full" build configuration is used.\r
+ *\r
+ * main-full.c creates a lot of demo and test tasks and timers,  and is \r
+ * therefore very comprehensive but also complex.  If you would prefer a much \r
+ * simpler project to get started with, then select the 'Blinky' build \r
+ * configuration within the SDK Eclipse IDE.  See the documentation page for\r
+ * this demo on the http://www.FreeRTOS.org web site for more information.\r
  * ****************************************************************************\r
  *\r
- * main() creates all the demo application tasks, then starts the scheduler.  \r
- * The web documentation provides more details of the standard demo application \r
- * tasks, which provide no particular functionality, but do provide a good \r
- * example of how to use the FreeRTOS API.  \r
+ * main() creates all the demo application tasks and timers, then starts the \r
+ * scheduler.  The web documentation provides more details of the standard demo \r
+ * application tasks, which provide no particular functionality, but do provide \r
+ * a good example of how to use the FreeRTOS API.  \r
  *\r
  * In addition to the standard demo tasks, the following tasks and tests are\r
  * defined and/or created within this file:\r
  *\r
- * Webserver ("lwIP") task - TBD _RB_\r
+ * TCP/IP ("lwIP") task - TBD _RB_\r
  *\r
- * "Reg test" tasks - These fill the registers with known values, then check\r
- * that each register still contains its expected value.  Each task uses\r
- * different values.  The tasks run with very low priority so get preempted\r
- * very frequently.  A check variable is incremented on each iteration of the\r
- * test loop.  A register containing an unexpected value is indicative of an\r
- * error in the context switching mechanism and will result in a branch to a\r
- * null loop - which in turn will prevent the check variable from incrementing\r
- * any further and allow the check timer (described below) to determine that an\r
- * error has occurred.  The nature of the reg test tasks necessitates that they\r
- * are written in assembly code.\r
+ * "Reg test" tasks - These test the task context switch mechanism by first \r
+ * filling the MicroBlaze registers with known values, before checking that each\r
+ * register maintains the value that was written to it as the tasks are switched\r
+ * in and out.  The two register test tasks do not use the same values, and\r
+ * execute at a very low priority to ensure they are pre-empted regularly.\r
  *\r
  * "Check" timer - The check timer period is initially set to five seconds.  \r
- * The check timer callback function checks that all the standard demo tasks are \r
- * functioning as expected, without error.  If an error is discovered in any \r
- * standard demo task, then the check timer period is shortened to 200ms.  The\r
- * check timer callback function also toggles an LED each time it is called. \r
- * Therefore, if the LED toggles every five seconds, all the tasks are\r
- * functioning as expected, without any error conditions being detected.  If the\r
- * LED toggles every 200ms then an error has been discovered in at least one\r
- * task. \r
+ * The check timer callback function checks that all the standard demo tasks,\r
+ * and the register check tasks, are not only still execution, but are executing\r
+ * without reporting any errors.  If the check timer discovers that a task has\r
+ * either stalled or reported an error, then it changes its own period from\r
+ * the inital five seconds, to just 200ms.  The check timer callback function \r
+ * also toggles an LED each time it is called.  This provides a visual\r
+ * indication of the system status:  If the LED toggles every five seconds then\r
+ * no issues have been discovered.  If the LED toggles every 200ms then an issue\r
+ * has been discovered with at least one task.  The last reported issue is\r
+ * latched into the pcStatusMessage variable.\r
  *\r
  * This file also includes example implementations of the vApplicationTickHook(),\r
  * vApplicationIdleHook(), vApplicationStackOverflowHook(),\r
 #include "comtest_strings.h"\r
 #include "TimerDemo.h"\r
 \r
-/* Priorities at which the tasks are created. */\r
+/* Priorities at which the various tasks are created. */\r
 #define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
 #define mainSEM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
 #define mainBLOCK_Q_PRIORITY           ( tskIDLE_PRIORITY + 2 )\r
 #define mainGEN_QUEUE_TASK_PRIORITY    ( tskIDLE_PRIORITY )\r
 #define mainFLOP_TASK_PRIORITY         ( tskIDLE_PRIORITY )\r
 \r
-/* The WEB server uses string handling functions, which in turn use a bit more\r
-stack than most of the other tasks. */\r
-#define mainuIP_STACK_SIZE                     ( configMINIMAL_STACK_SIZE * 3 )\r
-\r
 /* The LED toggled by the check task. */\r
 #define mainCHECK_LED                          ( 3 )\r
 \r
 /* The rate at which mainCHECK_LED will toggle when all the tasks are running\r
-without error.  Controlled by the check task as described at the top of this\r
-file. */\r
+without error.  See the description of the check timer in the comments at the\r
+top of this file. */\r
 #define mainNO_ERROR_CHECK_TIMER_PERIOD                ( 5000 / portTICK_RATE_MS )\r
 \r
 /* The rate at which mainCHECK_LED will toggle when an error has been reported\r
-by at least one task.  Controlled by the check task as described at the top of\r
-this file. */\r
+by at least one task.  See the description of the check timer in the comments at \r
+the top of this file. */\r
 #define mainERROR_CHECK_TIMER_PERIOD           ( 200 / portTICK_RATE_MS )\r
 \r
-/* A block time of zero means "don't block". */
+/* A block time of zero simply means "don't block". */
 #define mainDONT_BLOCK                                         ( ( portTickType ) 0 )\r
 \r
-/* The LED used by the comtest tasks. See the comtest.c file for more\r
+/* The LED used by the comtest tasks. See the comtest_strings.c file for more\r
 information.  In this case an invalid LED number is provided as all four\r
-available LEDs are already in use. */\r
+available LEDs (LEDs 0 to 3) are already in use. */\r
 #define mainCOM_TEST_LED                       ( 4 )\r
 \r
-/* Baud rate used by the comtest tasks.  This is actually fixed in the hardware\r
-when the hardware was built, but the standard serial init function required a\r
-baud rate parameter. */\r
+/* Baud rate used by the comtest tasks.  The baud rate used is actually fixed in \r
+UARTLite IP when the hardware was built, but the standard serial init function \r
+required a baud rate parameter to be provided - in this case it is just \r
+ignored. */\r
 #define mainCOM_TEST_BAUD_RATE                         ( XPAR_RS232_UART_1_BAUDRATE )\r
 \r
+/* The timer test task generates a lot of timers that all use a different \r
+period that is a multiple of the mainTIMER_TEST_PERIOD definition. */\r
 #define mainTIMER_TEST_PERIOD                  ( 20 )\r
 \r
-/*\r
- * vApplicationMallocFailedHook() will only be called if\r
- * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
- * function that will execute if a call to pvPortMalloc() fails.\r
- * pvPortMalloc() is called internally by the kernel whenever a task, queue or\r
- * semaphore is created.  It is also called by various parts of the demo\r
- * application.\r
- */\r
-void vApplicationMallocFailedHook( void );\r
-\r
-/*\r
- * vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set to 1\r
- * in FreeRTOSConfig.h.  It is a hook function that is called on each iteration\r
- * of the idle task.  It is essential that code added to this hook function\r
- * never attempts to block in any way (for example, call xQueueReceive() with\r
- * a block time specified).  If the application makes use of the vTaskDelete()\r
- * API function (as this demo application does) then it is also important that\r
- * vApplicationIdleHook() is permitted to return to its calling function because\r
- * it is the responsibility of the idle task to clean up memory allocated by the\r
- * kernel to any task that has since been deleted.\r
- */\r
-void vApplicationIdleHook( void );\r
-\r
-/*\r
- * vApplicationStackOverflowHook() will only be called if\r
- * configCHECK_FOR_STACK_OVERFLOW is set to a non-zero value.  The handle and\r
- * name of the offending task should be passed in the function parameters, but\r
- * it is possible that the stack overflow will have corrupted these - in which\r
- * case pxCurrentTCB can be inspected to find the same information.\r
- */\r
-void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
- * The reg test tasks as described at the top of this file.\r
+ * The register test tasks as described in the comments at the top of this file.\r
+ * The nature of the register test tasks means they have to be implemented in\r
+ * assembler.\r
  */\r
 extern void vRegisterTest1( void *pvParameters );\r
 extern void vRegisterTest2( void *pvParameters );\r
 \r
 /*\r
- * Defines the 'check' functionality as described at the top of this file.  This\r
- * function is the callback function for the 'check' timer.\r
+ * Defines the 'check' timer functionality as described at the top of this file.  \r
+ * This function is the callback function associated with the 'check' timer.\r
  */\r
 static void vCheckTimerCallback( xTimerHandle xTimer );\r
 \r
-\r
+/* \r
+ * Configure the interrupt controller, LED outputs and button inputs. \r
+ */\r
 static void prvSetupHardware( void );\r
 \r
-\r
 /*-----------------------------------------------------------*/\r
 \r
-/* The status message that is displayed at the bottom of the "task stats" web\r
-page, which is served by the uIP task.  This will report any errors picked up\r
-by the reg test task. */\r
+/* The check timer callback function sets pcStatusMessage to a string that\r
+indicates the last reported error that it discovered. */\r
 static const char *pcStatusMessage = NULL;\r
 \r
+/* Structures that hold the state of the various peripherals used by this demo.\r
+These are used by the Xilinx peripheral driver API functions.  In this case,\r
+only the timer/counter is used directly within this file. */\r
 static XTmrCtr xTimer0Instance;\r
 \r
 /* The 'check' timer, as described at the top of this file. */\r
@@ -230,16 +206,18 @@ static xTimerHandle xCheckTimer = NULL;
 \r
 int main( void )\r
 {\r
-       /* *************************************************************************\r
-       This project includes a lot of demo and test tasks,  and is therefore complex.\r
-       If you would prefer a much simpler project to get started with, then select\r
-       the 'Blinky' build configuration within the SDK Eclipse IDE.\r
+       /***************************************************************************\r
+       This project includes a lot of demo and test tasks and timers,  and is \r
+       therefore comprehensive, but complex.  If you would prefer a much simpler \r
+       project to get started with, then select the 'Blinky' build configuration \r
+       within the SDK Eclipse IDE.\r
        ***************************************************************************/\r
 \r
        /* Configure the interrupt controller, LED outputs and button inputs. */\r
        prvSetupHardware();\r
 \r
-       /* Start the reg test tasks which test the context switching mechanism. */\r
+       /* Start the reg test tasks, as described in the comments at the top of this\r
+       file. */\r
        xTaskCreate( vRegisterTest1, ( const signed char * const ) "RegTst1", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL );\r
        xTaskCreate( vRegisterTest2, ( const signed char * const ) "RegTst2", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL );\r
 \r
@@ -258,31 +236,34 @@ int main( void )
 \r
        /* Note - the set of standard demo tasks contains two versions of\r
        vStartMathTasks.c.  One is defined in flop.c, and uses double precision\r
-       floating point numbers and variables.  The other is defined in sp_flop.c\r
+       floating point numbers and variables.  The other is defined in sp_flop.c,\r
        and uses single precision floating point numbers and variables.  The\r
        MicroBlaze floating point unit only handles single precision floating.\r
-       Therefore, to test the floating point unit, sp_flop.c should be included\r
+       Therefore, to test the floating point hardware, sp_flop.c should be included\r
        in this project. */\r
        vStartMathTasks( mainFLOP_TASK_PRIORITY );\r
 \r
        /* The suicide tasks must be created last as they need to know how many\r
-       tasks were running prior to their creation in order to ascertain whether\r
-       or not the correct/expected number of tasks are running at any given time. */\r
+       tasks were running prior to their creation.  This then allows them to \r
+       ascertain whether or not the correct/expected number of tasks are running at \r
+       any given time. */\r
        vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );\r
 \r
        /* Create the 'check' timer - the timer that periodically calls the\r
-       check function as described at the top of this file.  Note that, for\r
-       the reasons stated in the comments above the call to\r
-       vStartTimerDemoTask(), that the check timer is not actually started\r
-       until after the scheduler has been started. */\r
+       check function as described in the comments at the top of this file.  Note \r
+       that, for reasons stated in the comments within vApplicationIdleHook()\r
+       (defined in this file), the check timer is not actually started until after \r
+       the scheduler has been started. */\r
        xCheckTimer = xTimerCreate( ( const signed char * ) "Check timer", mainNO_ERROR_CHECK_TIMER_PERIOD, pdTRUE, ( void * ) 0, vCheckTimerCallback );\r
 \r
-       /* Start the tasks running. */\r
+       /* Start the scheduler running.  From this point on, only tasks and \r
+       interrupts will be executing. */\r
        vTaskStartScheduler();\r
 \r
-       /* If all is well we will never reach here as the scheduler will now be\r
-       running.  If we do reach here then it is likely that there was insufficient\r
-       heap available for the idle task to be created. */\r
+       /* If all is well then the following line will never be reached.  If\r
+       execution does reach here, then it is highly probably that the heap size\r
+       is too small for the idle and/or timer tasks to be created within \r
+       vTaskStartScheduler(). */\r
        taskDISABLE_INTERRUPTS();\r
        for( ;; );\r
 }\r
@@ -296,14 +277,11 @@ static long lErrorAlreadyLatched = pdFALSE;
 portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;\r
 \r
        /* This is the callback function used by the 'check' timer, as described\r
-       at the top of this file. */\r
+       in the comments at the top of this file. */\r
 \r
        /* Check the standard demo tasks are running without error. */\r
        if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
        {\r
-               /* Increase the rate at which this task cycles, which will increase the\r
-               rate at which mainCHECK_LED flashes to give visual feedback that an error\r
-               has occurred. */\r
                pcStatusMessage = "Error: GenQueue";\r
        }\r
        else if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
@@ -361,6 +339,9 @@ portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;
                pcStatusMessage = "Error: RegTest2\r\n";\r
        }\r
 \r
+       /* Store a local copy of the current reg test loop counters.  If these have\r
+       not incremented the next time this callback function is executed then the\r
+       reg test tasks have either stalled or discovered an error. */\r
        ulLastRegTest1CycleCount = ulRegTest1CycleCount;\r
        ulLastRegTest2CycleCount = ulRegTest2CycleCount;\r
 \r
@@ -373,23 +354,39 @@ portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;
        {\r
                if( lErrorAlreadyLatched == pdFALSE )\r
                {\r
-                       /* Ensure the LED toggles at a faster rate if an error has occurred.\r
-                       This is called from a timer callback so must not attempt to block. */
-                       xTimerChangePeriod( xTimer, mainERROR_CHECK_TIMER_PERIOD, mainDONT_BLOCK );\r
-\r
-                       /* Update the xExecutionRate variable as the rate at which this\r
+                       /* An error has occurred, so change the period of the timer that\r
+                       calls this callback function.  This results in the LED toggling at\r
+                       a faster rate - giving the user visual feedback that something is not\r
+                       as it should be.  This function is called from the context of the\r
+                       timer service task so must ***not*** attempt to block while calling\r
+                       this function. */
+                       if( xTimerChangePeriod( xTimer, mainERROR_CHECK_TIMER_PERIOD, mainDONT_BLOCK ) == pdPASS )\r
+                       {\r
+                               /* If the command to change the timer period was sent to the\r
+                               timer command queue successfully, then latch the fact that the\r
+                               timer period has already been changed.  This is just done to\r
+                               prevent xTimerChangePeriod() being called on every execution of\r
+                               this function once an error has been discovered.  */\r
+                               lErrorAlreadyLatched = pdTRUE;\r
+                       }\r
+\r
+                       /* Update the xExecutionRate variable too as the rate at which this\r
                        callback is executed has to be passed into the\r
                        xAreTimerDemoTasksStillRunning() function. */\r
                        xExecutionRate = mainERROR_CHECK_TIMER_PERIOD;\r
-\r
-                       /* Just to ensure the timer period is not changed on each execution\r
-                       of the callback. */
-                       lErrorAlreadyLatched = pdTRUE;\r
                }\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* This is an application defined callback function used to install the tick\r
+interrupt handler.  It is provided as an application callback because the kernel\r
+will run on lots of different MicroBlaze and FPGA configurations - not all of\r
+which will have the same timer peripherals defined or available.  This example\r
+uses the AXI Timer 0.  If that is available on your hardware platform then this\r
+example callback implementation should not require modification.   The name of\r
+the interrupt handler that should be installed is vTickISR(), which the function\r
+below declares as an extern. */\r
 void vApplicationSetupTimerInterrupt( void )\r
 {\r
 portBASE_TYPE xStatus;\r
@@ -402,12 +399,17 @@ extern void vTickISR( void *pvUnused );
 \r
        if( xStatus == XST_SUCCESS )\r
        {\r
-               /* Install the tick interrupt handler as the timer ISR. */\r
+               /* Install the tick interrupt handler as the timer ISR. \r
+               *NOTE* The xPortInstallInterruptHandler() API function must be used for\r
+               this purpose. */\r
                xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_TMRCTR_0_VEC_ID, vTickISR, NULL );\r
        }\r
 \r
        if( xStatus == pdPASS )\r
        {\r
+               /* Enable the timer interrupt in the interrupt controller.\r
+               *NOTE* The vPortEnableInterrupt() API function must be used for this\r
+               purpose. */\r
                vPortEnableInterrupt( XPAR_INTC_0_TMRCTR_0_VEC_ID );\r
 \r
                /* Configure the timer interrupt handler. */\r
@@ -426,10 +428,20 @@ extern void vTickISR( void *pvUnused );
                XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber );\r
        }\r
 \r
+       /* Sanity check that the function executed as expected. */\r
        configASSERT( ( xStatus == pdPASS ) );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* This is an application defined callback function used to clear whichever\r
+interrupt was installed by the the vApplicationSetupTimerInterrupt() callback\r
+function - in this case the interrupt generated by the AXI timer.  It is \r
+provided as an application callback because the kernel will run on lots of \r
+different MicroBlaze and FPGA configurations - not all of which will have the \r
+same timer peripherals defined or available.  This example uses the AXI Timer 0.  \r
+If that is available on your hardware platform then this example callback \r
+implementation should not require modification provided the example definition\r
+of vApplicationSetupTimerInterrupt() is also not modified. */\r
 void vApplicationClearTimerInterrupt( void )\r
 {\r
 unsigned long ulCSR;\r
@@ -440,33 +452,60 @@ unsigned long ulCSR;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-/* This function is explained by the comments above its prototype at the top\r
-of this file. */\r
 void vApplicationMallocFailedHook( void )\r
 {\r
+       /* vApplicationMallocFailedHook() will only be called if\r
+       configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
+       function that will get called if a call to pvPortMalloc() fails. \r
+       pvPortMalloc() is called internally by the kernel whenever a task, queue or\r
+       semaphore is created.  It is also called by various parts of the demo\r
+       application.  If heap_1.c or heap_2.c are used, then the size of the heap\r
+       available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in\r
+       FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used\r
+       to query the size of free heap space that remains (although it does not\r
+       provide information on how the remaining heap might be fragmented). */\r
        taskDISABLE_INTERRUPTS();\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-/* This function is explained by the comments above its prototype at the top\r
-of this file. */\r
 void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
 {\r
+       /* vApplicationStackOverflowHook() will only be called if\r
+       configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2.  The handle and name\r
+       of the offending task will be passed into the hook function via its \r
+       parameters.  However, when a stack has overflowed, it is possible that the\r
+       parameters will have been corrupted, in which case the pxCurrentTCB variable\r
+       can be inspected directly. */\r
        taskDISABLE_INTERRUPTS();\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-/* This function is explained by the comments above its prototype at the top\r
-of this file. */\r
 void vApplicationIdleHook( void )\r
 {\r
 static long lCheckTimerStarted = pdFALSE;\r
 \r
+       /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set \r
+       to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle \r
+       task.  It is essential that code added to this hook function never attempts \r
+       to block in any way (for example, call xQueueReceive() with a block time \r
+       specified, or call vTaskDelay()).  If the application makes use of the \r
+       vTaskDelete() API function (as this demo application does) then it is also \r
+       important that vApplicationIdleHook() is permitted to return to its calling \r
+       function, because it is the responsibility of the idle task to clean up \r
+       memory allocated by the kernel to any task that has since been deleted. */\r
+\r
+       /* If the check timer has not already been started, then start it now.\r
+       Normally, the xTimerStart() API function can be called immediately after the\r
+       timer is created - how this demo application includes the timer demo tasks.\r
+       The timer demo tasks, as part of their test function, deliberately fill up\r
+       the timer command queue - meaning the check timer cannot be started until\r
+       after the scheduler has been started - at which point the timer command\r
+       queue will have been drained. */\r
        if( lCheckTimerStarted == pdFALSE )\r
        {\r
-               xTimerStart( xCheckTimer, mainDONT_BLOCK ); //_RB_ comment why this is done here.\r
+               xTimerStart( xCheckTimer, mainDONT_BLOCK ); \r
                lCheckTimerStarted = pdTRUE;\r
        }\r
 }\r
@@ -474,24 +513,35 @@ static long lCheckTimerStarted = pdFALSE;
 \r
 void vApplicationTickHook( void )\r
 {\r
+       /* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set\r
+       to 1 in FreeRTOSConfig.h.  It executes from an interrupt context so must\r
+       not use any FreeRTOS API functions that do not end in ...FromISR(). */\r
+\r
        /* Call the periodic timer test, which tests the timer API functions that\r
        can be called from an ISR. */\r
        vTimerPeriodicISRTests();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-char *pcGetTaskStatusMessage( void )\r
+void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )\r
 {\r
-       /* Not bothered about a critical section here although technically because of\r
-       the task priorities the pointer could change it will be atomic if not near\r
-       atomic and its not critical. */\r
-       if( pcStatusMessage == NULL )\r
-       {\r
-               return "All tasks running without error";\r
-       }\r
-       else\r
+       /* If configINSTALL_EXCEPTION_HANDLERS is set to 1 in FreeRTOSConfig.h, then \r
+       the kernel will automatically install its own exception handlers before the \r
+       kernel is started, if the application writer has not already caused them to \r
+       be installed by calling either of the vPortExceptionsInstallHandlers() \r
+       or xPortInstallInterruptHandler() API functions before that time.  The \r
+       kernels exception handler populates an xPortRegisterDump structure with\r
+       the processor state at the point that the exception was triggered - and also\r
+       includes a strings that say what the exception cause was and which task was\r
+       running at the time.  The exception handler then passes the populated\r
+       xPortRegisterDump structure into vApplicationExceptionRegisterDump() to\r
+       allow the application writer to perform any debugging that may be necessary.\r
+       However, defining vApplicationExceptionRegisterDump() within the application\r
+       itself is optional.  The kernel will use a default implementation if the\r
+       application writer chooses not to provide their own. */\r
+       for( ;; )\r
        {\r
-               return ( char * ) pcStatusMessage;\r
+               portNOP();\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -499,8 +549,12 @@ char *pcGetTaskStatusMessage( void )
 static void prvSetupHardware( void )\r
 {\r
        taskDISABLE_INTERRUPTS();\r
+       \r
+       /* Configure the LED outputs. */\r
        vParTestInitialise();\r
 \r
+       /* Tasks inherit the exception and cache configuration of the MicroBlaze\r
+       at the point that they are created. */\r
        #if MICROBLAZE_EXCEPTIONS_ENABLED == 1\r
                microblaze_enable_exceptions();\r
        #endif\r
@@ -518,11 +572,3 @@ static void prvSetupHardware( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )\r
-{\r
-       for( ;; )\r
-       {\r
-               portNOP();\r
-       }\r
-}\r
-\r