]> git.sur5r.net Git - freertos/blobdiff - Demo/MSP430X_MSP430F5438_IAR/main.c
Comment the command line interpreter and lwIP sockets based server code.
[freertos] / Demo / MSP430X_MSP430F5438_IAR / main.c
index 600e1f81ff0d5fc3657cd093bfccbb684660fb1c..f48fb861530e15f172e02f153fc6a8c14d8a3f28 100644 (file)
@@ -1,38 +1,38 @@
 /*\r
-    FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
 \r
     ***************************************************************************\r
-    *                                                                         *\r
-    * If you are:                                                             *\r
-    *                                                                         *\r
-    *    + New to FreeRTOS,                                                   *\r
-    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *\r
-    *    + Looking for basic training,                                        *\r
-    *    + Wanting to improve your FreeRTOS skills and productivity           *\r
-    *                                                                         *\r
-    * then take a look at the FreeRTOS books - available as PDF or paperback  *\r
-    *                                                                         *\r
-    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *\r
-    *                  http://www.FreeRTOS.org/Documentation                  *\r
-    *                                                                         *\r
-    * A pdf reference manual is also available.  Both are usually delivered   *\r
-    * to your inbox within 20 minutes to two hours when purchased between 8am *\r
-    * and 8pm GMT (although please allow up to 24 hours in case of            *\r
-    * exceptional circumstances).  Thank you for your support!                *\r
-    *                                                                         *\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\r
     ***************************************************************************\r
 \r
+\r
     This file is part of the FreeRTOS distribution.\r
 \r
     FreeRTOS is free software; you can redistribute it and/or modify it under\r
     the terms of the GNU General Public License (version 2) as published by the\r
     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
-    ***NOTE*** The exception to the GPL is included to allow you to distribute\r
-    a combined work that includes FreeRTOS without being obliged to provide the\r
-    source code for proprietary components outside of the FreeRTOS kernel.\r
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
+    >>>NOTE<<< The modification to the GPL is included to allow you to\r
+    distribute a combined work that includes FreeRTOS without being obliged to\r
+    provide the source code for proprietary components outside of the FreeRTOS\r
+    kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
+    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
     more details. You should have received a copy of the GNU General Public\r
     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
     licensing and training services.\r
 */\r
 \r
+/*\r
+ * The documentation page for this demo available on http://www.FreeRTOS.org\r
+ * documents the hardware configuration required to run this demo.  It also\r
+ * provides more information on the expected demo application behaviour.\r
+ *\r
+ * main() creates all the demo application tasks, then starts the scheduler.\r
+ * A lot of the created tasks are from the pool of "standard demo" tasks.  The\r
+ * web documentation provides more details of the standard demo tasks, which\r
+ * provide no particular functionality but do provide good examples of how to\r
+ * use the FreeRTOS API.\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks, interrupts and\r
+ * tests are defined and/or created within this file:\r
+ *\r
+ * "LCD" task - The LCD task is a 'gatekeeper' task.  It is the only task that\r
+ * is permitted to access the LCD and therefore ensures access to the LCD is\r
+ * always serialised and there are no mutual exclusion issues.  When a task or\r
+ * an interrupt wants to write to the LCD, it does not access the LCD directly\r
+ * but instead sends the message to the LCD task.  The LCD task then performs\r
+ * the actual LCD output.  This mechanism also allows interrupts to, in effect,\r
+ * write to the LCD by sending messages to the LCD task.\r
+ *\r
+ * The LCD task is also a demonstration of a 'controller' task design pattern.\r
+ * Some tasks do not actually send a string to the LCD task directly, but\r
+ * instead send a command that is interpreted by the LCD task.  In a normal\r
+ * application these commands can be control values or set points, in this\r
+ * simple example the commands just result in messages being displayed on the\r
+ * LCD.\r
+ *\r
+ * "Button Poll" task - This task polls the state of the 'up' key on the\r
+ * joystick input device.  It uses the vTaskDelay() API function to control\r
+ * the poll rate to ensure debouncing is not necessary and that the task does\r
+ * not use all the available CPU processing time.\r
+ *\r
+ * Button Interrupt and run time stats display - The select button on the\r
+ * joystick input device is configured to generate an external interrupt.  The\r
+ * handler for this interrupt sends a message to LCD task, which interprets the\r
+ * message to mean, firstly write a message to the LCD, and secondly, generate\r
+ * a table of run time statistics.  The run time statistics are displayed as a\r
+ * table that contains information on how much processing time each task has\r
+ * been allocated since the application started to execute.  This information\r
+ * is provided both as an absolute time, and as a percentage of the total run\r
+ * time.  The information is displayed in the terminal IO window of the IAR\r
+ * embedded workbench.  The online documentation for this demo shows a screen\r
+ * shot demonstrating where the run time stats can be viewed.\r
+ *\r
+ * Idle Hook - The idle hook is a function that is called on each iteration of\r
+ * the idle task.  In this case it is used to place the processor into a low\r
+ * power mode.  Note however that this application is implemented using standard\r
+ * components, and is therefore not optimised for low power operation.  Lower\r
+ * power consumption would be achieved by converting polling tasks into event\r
+ * driven tasks, and slowing the tick interrupt frequency.\r
+ *\r
+ * "Check" function called from the tick hook - The tick hook is called during\r
+ * each tick interrupt.  It is called from an interrupt context so must execute\r
+ * quickly, not attempt to block, and not call any FreeRTOS API functions that\r
+ * do not end in "FromISR".  In this case the tick hook executes a 'check'\r
+ * function.  This only executes every five seconds.  Its main function is to\r
+ * check that all the standard demo tasks are still operational.  Each time it\r
+ * executes it sends a status code to the LCD task.  The LCD task interprets the\r
+ * code and displays an appropriate message - which will be PASS if no tasks\r
+ * have reported any errors, or a message stating which task has reported an\r
+ * error.\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 task (described a above) 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
+ *\r
+ * *NOTE 1* vApplicationSetupTimerInterrupt() is called by the kernel to let\r
+ * the application set up a timer to generate the tick interrupt.  In this\r
+ * example a timer A0 is used for this purpose.\r
+ *\r
+*/\r
+\r
 /* Standard includes. */\r
 #include <stdio.h>\r
 \r
 \r
 /* Standard demo includes. */\r
 #include "ParTest.h"\r
+#include "dynamic.h"\r
 #include "comtest2.h"\r
+#include "GenQTest.h"\r
 \r
 /* Codes sent within messages to the LCD task so the LCD task can interpret\r
 exactly what the message it just received was.  These are sent in the\r
@@ -86,28 +169,61 @@ of the same message and indicate what the status actually is. */
 to send messages from tasks and interrupts the the LCD task. */\r
 #define mainQUEUE_LENGTH                               ( 5 )\r
 \r
+/* Priorities used by the test and demo tasks. */\r
 #define mainLCD_TASK_PRIORITY                  ( tskIDLE_PRIORITY + 1 )\r
 #define mainCOM_TEST_PRIORITY                  ( tskIDLE_PRIORITY + 2 )\r
+#define mainGENERIC_QUEUE_TEST_PRIORITY        ( tskIDLE_PRIORITY )\r
 \r
 /* The LED used by the comtest tasks. See the comtest.c file for more\r
-information.  In this case it is deliberately out of range as there are only\r
-two LEDs, and they are both already in use. */\r
-#define mainCOM_TEST_LED                       ( 3 )\r
+information.  */\r
+#define mainCOM_TEST_LED                               ( 1 )\r
+\r
+/* The baud rate used by the comtest tasks described at the top of this file. */\r
+#define mainCOM_TEST_BAUD_RATE                 ( 38400 )\r
 \r
+/* The maximum number of lines of text that can be displayed on the LCD. */\r
+#define mainMAX_LCD_LINES                              ( 8 )\r
 \r
+/* Just used to ensure parameters are passed into tasks correctly. */\r
+#define mainTASK_PARAMETER_CHECK_VALUE ( ( void * ) 0xDEAD )\r
 /*-----------------------------------------------------------*/\r
 \r
+/*\r
+ * The reg test tasks as described at the top of this file.\r
+ */\r
 extern void vRegTest1Task( void *pvParameters );\r
 extern void vRegTest2Task( void *pvParameters );\r
+\r
+/*\r
+ * Configures clocks, LCD, port pints, etc. necessary to execute this demo.\r
+ */\r
 static void prvSetupHardware( void );\r
-static void prvTerminalIOTask( void *pvParameters );\r
+\r
+/*\r
+ * Definition of the LCD/controller task described in the comments at the top\r
+ * of this file.\r
+ */\r
+static void prvLCDTask( void *pvParameters );\r
+\r
+/*\r
+ * Definition of the button poll task described in the comments at the top of\r
+ * this file.\r
+ */\r
 static void prvButtonPollTask( void *pvParameters );\r
+\r
+/*\r
+ * Converts a status message value into an appropriate string for display on\r
+ * the LCD.  The string is written to pcBuffer.\r
+ */\r
 static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
+/* Variables that are incremented on each iteration of the reg test tasks -\r
+provided the tasks have not reported any errors.  The check task inspects these\r
+variables to ensure they are still incrementing as expected.  If a variable\r
+stops incrementing then it is likely that its associate task has stalled. */\r
 volatile unsigned short usRegTest1Counter = 0, usRegTest2Counter = 0;\r
-volatile unsigned long ulStatsOverflowCount = 0;\r
 \r
 /* The handle of the queue used to send messages from tasks and interrupts to\r
 the LCD task. */\r
@@ -117,19 +233,29 @@ static xQueueHandle xLCDQueue = NULL;
 task. */\r
 typedef struct\r
 {\r
-       char cMessageID;        /* << States what the message is. */\r
-       unsigned long ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID. */\r
+       char cMessageID;                                /* << States what the message is. */\r
+       unsigned long ulMessageValue;   /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID). */\r
 } xQueueMessage;\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
+/* The linker script can be used to test the FreeRTOS ports use of 20bit \r
+addresses by locating all code in high memory.  The following pragma ensures \r
+that main remains in low memory when that is done.  The ISR_CODE segment is used \r
+for convenience as ISR functions are always placed in low memory. */\r
+#pragma location="ISR_CODE"\r
 void main( void )\r
 {\r
+       /* Configure the peripherals used by this demo application.  This includes\r
+       configuring the joystick input select button to generate interrupts. */\r
        prvSetupHardware();\r
 \r
        /* Create the queue used by tasks and interrupts to send strings to the LCD\r
        task. */\r
        xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );\r
 \r
+       /* If the queue could not be created then don't create any tasks that might\r
+       attempt to use the queue. */\r
        if( xLCDQueue != NULL )\r
        {\r
                /* Add the created queue to the queue registry so it can be viewed in\r
@@ -137,22 +263,30 @@ void main( void )
                vQueueAddToRegistry( xLCDQueue, "LCDQueue" );\r
 \r
                /* Create the standard demo tasks. */\r
-               vAltStartComTestTasks( mainCOM_TEST_PRIORITY, 9600, mainCOM_TEST_LED );\r
+               vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );\r
+               vStartDynamicPriorityTasks();\r
+               vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );\r
                \r
-               /* Create the terminal IO and button poll tasks, as described at the top\r
-               of this file. */\r
-               xTaskCreate( prvTerminalIOTask, ( signed char * ) "IO", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );\r
+               /* Create the LCD, button poll and register test tasks, as described at\r
+               the top of this file. */\r
+               xTaskCreate( prvLCDTask, ( signed char * ) "LCD", configMINIMAL_STACK_SIZE * 2, mainTASK_PARAMETER_CHECK_VALUE, mainLCD_TASK_PRIORITY, NULL );\r
                xTaskCreate( prvButtonPollTask, ( signed char * ) "BPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+               xTaskCreate( vRegTest1Task, ( signed char * ) "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
+               xTaskCreate( vRegTest2Task, ( signed char * ) "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
 \r
-               xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
-               xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
+               /* Start the scheduler. */\r
                vTaskStartScheduler();\r
        }\r
+       \r
+       /* If all is well then this line will never be reached.  If it is reached\r
+       then it is likely that there was insufficient (FreeRTOS) heap memory space\r
+       to create the idle task.  This may have been trapped by the malloc() failed\r
+       hook function, if one is configured. */ \r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvTerminalIOTask( void *pvParameters )\r
+static void prvLCDTask( void *pvParameters )\r
 {\r
 xQueueMessage xReceivedMessage;\r
 \r
@@ -161,6 +295,8 @@ LCD.  Note this is a static variable to prevent it being allocated on the task
 stack, which is too small to hold such a variable.  The stack size is configured\r
 when the task is created. */\r
 static char cBuffer[ 512 ];\r
+unsigned char ucLine = 1;\r
+\r
 \r
        /* This function is the only function that uses printf().  If printf() is\r
        used from any other function then some sort of mutual exclusion on stdout\r
@@ -171,6 +307,14 @@ static char cBuffer[ 512 ];
        First print out the number of bytes that remain in the FreeRTOS heap.  This\r
        can be viewed in the terminal IO window within the IAR Embedded Workbench. */\r
        printf( "%d bytes of heap space remain unallocated\n", ( int ) xPortGetFreeHeapSize() );\r
+       \r
+       /* Just as a test of the port, and for no functional reason, check the task\r
+       parameter contains its expected value. */\r
+       if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )\r
+       {\r
+               halLcdPrintLine( "Invalid parameter", ucLine,  OVERWRITE_TEXT );\r
+               ucLine++;               \r
+       }\r
 \r
        for( ;; )\r
        {\r
@@ -181,6 +325,13 @@ static char cBuffer[ 512 ];
                has been received. */\r
                xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );\r
 \r
+               /* Clear the LCD if no room remains for any more text output. */\r
+               if( ucLine > mainMAX_LCD_LINES )\r
+               {\r
+                       halLcdClearScreen();\r
+                       ucLine = 0;\r
+               }\r
+               \r
                /* What is this message?  What does it contain? */\r
                switch( xReceivedMessage.cMessageID )\r
                {\r
@@ -199,9 +350,18 @@ static char cBuffer[ 512 ];
                                                                                                the terminal IO window in the IAR\r
                                                                                                embedded workbench. */\r
                                                                                                printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );\r
-                                                                                               fflush( stdout );\r
                                                                                                vTaskGetRunTimeStats( ( signed char * ) cBuffer );\r
-//                                                                                             printf( cBuffer );\r
+                                                                                               printf( cBuffer );\r
+                                                                                               \r
+                                                                                               /* Also print out a message to\r
+                                                                                               the LCD - in this case the\r
+                                                                                               pointer to the string to print\r
+                                                                                               is sent directly in the\r
+                                                                                               ulMessageValue member of the\r
+                                                                                               message.  This just demonstrates\r
+                                                                                               a different communication\r
+                                                                                               technique. */\r
+                                                                                               sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );\r
                                                                                                break;\r
                                                                                                \r
                        case mainMESSAGE_STATUS                 :       /* The tick interrupt hook\r
@@ -217,9 +377,10 @@ static char cBuffer[ 512 ];
                }\r
                \r
                /* Output the message that was placed into the cBuffer array within the\r
-               switch statement above. */\r
-               printf( "%s : %u\n", cBuffer, ( unsigned int ) xTaskGetTickCount() );\r
-               fflush( stdout );\r
+               switch statement above, then move onto the next line ready for the next\r
+               message to arrive on the queue. */\r
+               halLcdPrintLine( cBuffer, ucLine,  OVERWRITE_TEXT );\r
+               ucLine++;\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -230,11 +391,11 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
        string for output onto the LCD. */\r
        switch( lStatusValue )\r
        {\r
-               case pdPASS                                             :       sprintf( pcBuffer, "Task status = PASS" );\r
+               case pdPASS                                             :       sprintf( pcBuffer, "Status = PASS" );\r
                                                                                        break;\r
-               case mainERROR_DYNAMIC_TASKS    :       sprintf( pcBuffer, "Error: Dynamic tasks" );\r
+               case mainERROR_DYNAMIC_TASKS    :       sprintf( pcBuffer, "Err: Dynamic tsks" );\r
                                                                                        break;\r
-               case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Err: COM test" ); /* Error in COM test - is the Loopback connector connected? */                                                                                                            \r
+               case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Err: COM test" );\r
                                                                                        break;\r
                case mainERROR_GEN_QUEUE_TEST   :       sprintf( pcBuffer, "Error: Gen Q test" );\r
                                                                                        break;\r
@@ -260,6 +421,7 @@ xQueueMessage xMessage;
                \r
                if( ucState != 0 )\r
                {\r
+                       /* The button was pressed. */\r
                        ucState = pdTRUE;\r
                }\r
                \r
@@ -281,62 +443,29 @@ xQueueMessage xMessage;
 \r
 static void prvSetupHardware( void )\r
 {\r
+/* Convert a Hz value to a KHz value, as required by the Init_FLL_Settle()\r
+function. */\r
 unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );\r
 \r
        halBoardInit();\r
-       halButtonsInit( BUTTON_ALL );\r
-       halButtonsInterruptEnable( BUTTON_SELECT );\r
+\r
        LFXT_Start( XT1DRIVE_0 );\r
        Init_FLL_Settle( ( unsigned short ) ulCPU_Clock_KHz, 488 );\r
-}\r
-/*-----------------------------------------------------------*/\r
 \r
-void vApplicationSetupTimerInterrupt( void )\r
-{\r
-const unsigned short usACLK_Frequency_Hz = 32768;\r
-\r
-       /* Ensure the timer is stopped. */\r
-       TA0CTL = 0;\r
-\r
-       /* Run the timer from the ACLK. */\r
-       TA0CTL = TASSEL_1;\r
-\r
-       /* Clear everything to start with. */\r
-       TA0CTL |= TACLR;\r
-\r
-       /* Set the compare match value according to the tick rate we want. */\r
-       TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;\r
-\r
-       /* Enable the interrupts. */\r
-       TA0CCTL0 = CCIE;\r
-\r
-       /* Start up clean. */\r
-       TA0CTL |= TACLR;\r
-\r
-       /* Up mode. */\r
-       TA0CTL |= MC_1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationMallocFailedHook( void )\r
-{\r
-       for( ;; );\r
-}\r
-/*-----------------------------------------------------------*/\r
+       halButtonsInit( BUTTON_ALL );\r
+       halButtonsInterruptEnable( BUTTON_SELECT );\r
 \r
-void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
-{\r
-       ( void ) pxTask;\r
-       ( void ) pcTaskName;\r
+       /* Initialise the LCD, but note that the backlight is not used as the\r
+       library function uses timer A0 to modulate the backlight, and this file\r
+       defines vApplicationSetupTimerInterrupt() to also use timer A0 to generate\r
+       the tick interrupt.  If the backlight is required, then change either the\r
+       halLCD library or vApplicationSetupTimerInterrupt() to use a different\r
+       timer.  Timer A1 is used for the run time stats time base6. */\r
+       halLcdInit();\r
+       halLcdSetContrast( 100 );\r
+       halLcdClearScreen();\r
        \r
-       for( ;; );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationIdleHook( void )\r
-{\r
-       /* Want to leave the SMCLK running so the COMTest tasks don't fail. */\r
-       __bis_SR_register( LPM1_bits + GIE );\r
+       halLcdPrintLine( " www.FreeRTOS.org", 0,  OVERWRITE_TEXT );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -358,44 +487,38 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
        ulCounter++;\r
        if( ulCounter >= ulCheckFrequency )\r
        {\r
-               #ifdef LEFT_OVER_FROM_CUT_AND_PASTE\r
-                       /* See if the standard demo tasks are executing as expected, changing\r
-                       the message that is sent to the LCD task from PASS to an error code if\r
-                       any tasks set reports an error. */\r
-                       if( xAreDynamicPriorityTasksStillRunning() != pdPASS )\r
-                       {\r
-                               xStatusMessage.lMessageValue = mainERROR_DYNAMIC_TASKS;\r
-                       }\r
-                       \r
-                       if( xAreGenericQueueTasksStillRunning() != pdPASS )\r
-                       {\r
-                               xStatusMessage.lMessageValue = mainERROR_GEN_QUEUE_TEST;\r
-                       }\r
-               #else\r
-                       /* See if the standard demo tasks are executing as expected, changing\r
-                       the message that is sent to the LCD task from PASS to an error code if\r
-                       any tasks set reports an error. */\r
-                       if( xAreComTestTasksStillRunning() != pdPASS )\r
-                       {\r
-                               xStatusMessage.ulMessageValue = mainERROR_COM_TEST;\r
-                       }\r
-\r
-\r
-                       /* Check the reg test tasks are still cycling.  They will stop incrementing\r
-                       their loop counters if they encounter an error. */\r
-                       if( usRegTest1Counter == usLastRegTest1Counter )\r
-                       {\r
-                               xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
-                       }\r
-       \r
-                       if( usRegTest2Counter == usLastRegTest2Counter )\r
-                       {\r
-                               xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
-                       }\r
-       \r
-                       usLastRegTest1Counter = usRegTest1Counter;\r
-                       usLastRegTest2Counter = usRegTest2Counter;\r
-               #endif\r
+               /* See if the standard demo tasks are executing as expected, changing\r
+               the message that is sent to the LCD task from PASS to an error code if\r
+               any tasks set reports an error. */\r
+               if( xAreComTestTasksStillRunning() != pdPASS )\r
+               {\r
+                       xStatusMessage.ulMessageValue = mainERROR_COM_TEST;\r
+               }\r
+\r
+               if( xAreDynamicPriorityTasksStillRunning() != pdPASS )\r
+               {\r
+                       xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;\r
+               }\r
+               \r
+               if( xAreGenericQueueTasksStillRunning() != pdPASS )\r
+               {\r
+                       xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;\r
+               }                       \r
+\r
+               /* Check the reg test tasks are still cycling.  They will stop\r
+               incrementing their loop counters if they encounter an error. */\r
+               if( usRegTest1Counter == usLastRegTest1Counter )\r
+               {\r
+                       xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
+               }\r
+\r
+               if( usRegTest2Counter == usLastRegTest2Counter )\r
+               {\r
+                       xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
+               }\r
+\r
+               usLastRegTest1Counter = usRegTest1Counter;\r
+               usLastRegTest2Counter = usRegTest2Counter;\r
                \r
                /* As this is the tick hook the lHigherPriorityTaskWoken parameter is not\r
                needed (a context switch is going to be performed anyway), but it must\r
@@ -404,17 +527,18 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
                ulCounter = 0;\r
        }\r
 \r
+       /* Just periodically toggle an LED to show that the tick interrupt is\r
+       running.  Note that this access LED_PORT_OUT in a non-atomic way, so tasks\r
+       that access the same port must do so from a critical section. */\r
        if( ( ulCounter & 0xff ) == 0 )\r
        {\r
                if( ( LED_PORT_OUT & LED_1 ) == 0 )\r
                {\r
                        LED_PORT_OUT |= LED_1;\r
-                       LED_PORT_OUT &= ~LED_2;\r
                }\r
                else\r
                {\r
                        LED_PORT_OUT &= ~LED_1;\r
-                       LED_PORT_OUT |= LED_2;\r
                }\r
        }\r
 }\r
@@ -424,7 +548,7 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
 __interrupt static void prvSelectButtonInterrupt(void)\r
 {\r
 /* Define the message sent to the LCD task from this interrupt. */\r
-static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };\r
+static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt" };\r
 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
 \r
        /* This is the interrupt handler for the joystick select button input.\r
@@ -442,46 +566,68 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vConfigureTimerForRunTimeStats( void )\r
+/* The MSP430X port uses this callback function to configure its tick interrupt.\r
+This allows the application to choose the tick interrupt source.\r
+configTICK_VECTOR must also be set in FreeRTOSConfig.h to the correct\r
+interrupt vector for the chosen tick interrupt source.  This implementation of\r
+vApplicationSetupTimerInterrupt() generates the tick from timer A0, so in this\r
+case configTICK_VECTOR is set to TIMER0_A0_VECTOR. */\r
+void vApplicationSetupTimerInterrupt( void )\r
 {\r
+const unsigned short usACLK_Frequency_Hz = 32768;\r
+\r
        /* Ensure the timer is stopped. */\r
-       TA1CTL = 0;\r
+       TA0CTL = 0;\r
 \r
-       /* Run the timer from the ACLK/4. */\r
-       TA1CTL = TASSEL_1 | ID__4;\r
+       /* Run the timer from the ACLK. */\r
+       TA0CTL = TASSEL_1;\r
 \r
        /* Clear everything to start with. */\r
-       TA1CTL |= TACLR;\r
+       TA0CTL |= TACLR;\r
+\r
+       /* Set the compare match value according to the tick rate we want. */\r
+       TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;\r
 \r
        /* Enable the interrupts. */\r
-       TA1CCTL0 = CCIE;\r
+       TA0CCTL0 = CCIE;\r
 \r
        /* Start up clean. */\r
-       TA1CTL |= TACLR;\r
+       TA0CTL |= TACLR;\r
 \r
-       /* Continuous mode. */\r
-       TA1CTL |= MC__CONTINOUS;\r
+       /* Up mode. */\r
+       TA0CTL |= MC_1;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-#pragma vector=TIMER1_A0_VECTOR\r
-static __interrupt void prvRunTimeStatsOverflowISR( void )\r
+void vApplicationIdleHook( void )\r
 {\r
-       ulStatsOverflowCount++;\r
+       /* Called on each iteration of the idle task.  In this case the idle task\r
+       just enters a low power mode. */\r
+       __bis_SR_register( LPM3_bits + GIE );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-inline unsigned long ulGetRunTimeStatsTime( void )\r
+void vApplicationMallocFailedHook( void )\r
 {\r
-unsigned long ulReturn;\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 or\r
+       semaphores. */\r
+       taskDISABLE_INTERRUPTS();\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       TA1CTL &= ~MC__CONTINOUS;\r
-       ulReturn = ( ( ulStatsOverflowCount << 16UL ) | ( unsigned long ) TA1R );\r
-       TA1CTL |= MC__CONTINOUS;\r
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
+{\r
+       ( void ) pxTask;\r
+       ( void ) pcTaskName;\r
        \r
-       return ulReturn;\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
+       taskDISABLE_INTERRUPTS();\r
+       for( ;; );\r
 }\r
-\r
-\r
-\r
+/*-----------------------------------------------------------*/\r
 \r