Please see my note book http://mbed.org/users/kenjiArai/notebook/freertos-on-mbed-board-with-mbed-cloud-ide--never-/

This is too old.
Below is another FreeRTOS on mbed.
http://developer.mbed.org/users/rgrover1/code/FreeRTOS/
I don't know it works well or not.
I have not evaluated it.

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Sat Jan 01 11:17:45 2011 +0000
Commit message:

Changed in this revision

FreeRTOS/Common/Minimal/BlockQ.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/GenQTest.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/PollQ.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/QPeek.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/blocktim.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/flash.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/integer.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/recmutex.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/Minimal/semtest.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/BlockQ.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/GenQTest.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/PollQ.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/QPeek.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/blocktim.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/flash.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/integer.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/partest.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/recmutex.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Common/include/semtest.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/FreeRTOS.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/StackMacros.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/croutine.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/list.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/mpu_wrappers.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/portable.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/projdefs.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/queue.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/semphr.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/include/task.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/list.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/portable/GCC/ARM_CM3/port.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/portable/GCC/ARM_CM3/port_asm_mbed.s Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/portable/MemMang/heap_1.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/queue.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOS/Source/tasks.c Show annotated file Show diff for this revision Revisions of this file
FreeRTOSConfig.h Show annotated file Show diff for this revision Revisions of this file
LPC17xx.h Show annotated file Show diff for this revision Revisions of this file
ParTest.c Show annotated file Show diff for this revision Revisions of this file
core_cm3.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
syscalls.c Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/BlockQ.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/BlockQ.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,308 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * Creates six tasks that operate on three queues as follows:
+ *
+ * The first two tasks send and receive an incrementing number to/from a queue.
+ * One task acts as a producer and the other as the consumer.  The consumer is a
+ * higher priority than the producer and is set to block on queue reads.  The queue
+ * only has space for one item - as soon as the producer posts a message on the
+ * queue the consumer will unblock, pre-empt the producer, and remove the item.
+ *
+ * The second two tasks work the other way around.  Again the queue used only has
+ * enough space for one item.  This time the consumer has a lower priority than the
+ * producer.  The producer will try to post on the queue blocking when the queue is
+ * full.  When the consumer wakes it will remove the item from the queue, causing
+ * the producer to unblock, pre-empt the consumer, and immediately re-fill the
+ * queue.
+ *
+ * The last two tasks use the same queue producer and consumer functions.  This time the queue has
+ * enough space for lots of items and the tasks operate at the same priority.  The
+ * producer will execute, placing items into the queue.  The consumer will start
+ * executing when either the queue becomes full (causing the producer to block) or
+ * a context switch occurs (tasks of the same priority will time slice).
+ *
+ */
+
+/*
+
+Changes from V4.1.1
+
+    + The second set of tasks were created the wrong way around.  This has been
+      corrected.
+*/
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo program include files. */
+#include "BlockQ.h"
+
+#define blckqSTACK_SIZE        configMINIMAL_STACK_SIZE
+#define blckqNUM_TASK_SETS    ( 3 )
+
+/* Structure used to pass parameters to the blocking queue tasks. */
+typedef struct BLOCKING_QUEUE_PARAMETERS
+{
+    xQueueHandle xQueue;                    /*< The queue to be used by the task. */
+    portTickType xBlockTime;                /*< The block time to use on queue reads/writes. */
+    volatile short *psCheckVariable;    /*< Incremented on each successful cycle to check the task is still running. */
+} xBlockingQueueParameters;
+
+/* Task function that creates an incrementing number and posts it on a queue. */
+static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters );
+
+/* Task function that removes the incrementing number from a queue and checks that
+it is the expected number. */
+static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters );
+
+/* Variables which are incremented each time an item is removed from a queue, and
+found to be the expected value.
+These are used to check that the tasks are still running. */
+static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };
+
+/* Variable which are incremented each time an item is posted on a queue.   These
+are used to check that the tasks are still running. */
+static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };
+
+/*-----------------------------------------------------------*/
+
+void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority )
+{
+xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
+xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
+xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
+const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5;
+const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS;
+const portTickType xDontBlock = ( portTickType ) 0;
+
+    /* Create the first two tasks as described at the top of the file. */
+    
+    /* First create the structure used to pass parameters to the consumer tasks. */
+    pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+
+    /* Create the queue used by the first two tasks to pass the incrementing number.
+    Pass a pointer to the queue in the parameter structure. */
+    pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
+
+    /* The consumer is created first so gets a block time as described above. */
+    pxQueueParameters1->xBlockTime = xBlockTime;
+
+    /* Pass in the variable that this task is going to increment so we can check it
+    is still running. */
+    pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] );
+        
+    /* Create the structure used to pass parameters to the producer task. */
+    pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+
+    /* Pass the queue to this task also, using the parameter structure. */
+    pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;
+
+    /* The producer is not going to block - as soon as it posts the consumer will
+    wake and remove the item so the producer should always have room to post. */
+    pxQueueParameters2->xBlockTime = xDontBlock;
+
+    /* Pass in the variable that this task is going to increment so we can check
+    it is still running. */
+    pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] );
+
+
+    /* Note the producer has a lower priority than the consumer when the tasks are
+    spawned. */
+    xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );
+    xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL );
+
+    
+
+    /* Create the second two tasks as described at the top of the file.   This uses
+    the same mechanism but reverses the task priorities. */
+
+    pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+    pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
+    pxQueueParameters3->xBlockTime = xDontBlock;
+    pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] );
+
+    pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+    pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;
+    pxQueueParameters4->xBlockTime = xBlockTime;
+    pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] );
+
+    xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );
+    xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL );
+
+
+
+    /* Create the last two tasks as described above.  The mechanism is again just
+    the same.  This time both parameter structures are given a block time. */
+    pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+    pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
+    pxQueueParameters5->xBlockTime = xBlockTime;
+    pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] );
+
+    pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
+    pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;
+    pxQueueParameters6->xBlockTime = xBlockTime;
+    pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] );    
+
+    xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );
+    xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
+{
+unsigned short usValue = 0;
+xBlockingQueueParameters *pxQueueParameters;
+short sErrorEverOccurred = pdFALSE;
+
+    pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
+
+    for( ;; )
+    {        
+        if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
+        {
+            sErrorEverOccurred = pdTRUE;
+        }
+        else
+        {
+            /* We have successfully posted a message, so increment the variable
+            used to check we are still running. */
+            if( sErrorEverOccurred == pdFALSE )
+            {
+                ( *pxQueueParameters->psCheckVariable )++;
+            }
+
+            /* Increment the variable we are going to post next time round.  The
+            consumer will expect the numbers to    follow in numerical order. */
+            ++usValue;
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )
+{
+unsigned short usData, usExpectedValue = 0;
+xBlockingQueueParameters *pxQueueParameters;
+short sErrorEverOccurred = pdFALSE;
+
+    pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
+
+    for( ;; )
+    {    
+        if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
+        {
+            if( usData != usExpectedValue )
+            {
+                /* Catch-up. */
+                usExpectedValue = usData;
+
+                sErrorEverOccurred = pdTRUE;
+            }
+            else
+            {
+                /* We have successfully received a message, so increment the
+                variable used to check we are still running. */    
+                if( sErrorEverOccurred == pdFALSE )
+                {
+                    ( *pxQueueParameters->psCheckVariable )++;
+                }
+                            
+                /* Increment the value we expect to remove from the queue next time
+                round. */
+                ++usExpectedValue;
+            }            
+        }        
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreBlockingQueuesStillRunning( void )
+{
+static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };
+static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };
+portBASE_TYPE xReturn = pdPASS, xTasks;
+
+    /* Not too worried about mutual exclusion on these variables as they are 16
+    bits and we are only reading them. We also only care to see if they have
+    changed or not.
+    
+    Loop through each check variable to and return pdFALSE if any are found not
+    to have changed since the last call. */
+
+    for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ )
+    {
+        if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ]  )
+        {
+            xReturn = pdFALSE;
+        }
+        sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];
+
+
+        if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ]  )
+        {
+            xReturn = pdFALSE;
+        }
+        sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];
+    }
+
+    return xReturn;
+}
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/GenQTest.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/GenQTest.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,572 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+/* 
+ * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - 
+ * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and 
+ * mutex behaviour. 
+ *
+ * See the comments above the prvSendFrontAndBackTest() and 
+ * prvLowPriorityMutexTask() prototypes below for more information.
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Demo program include files. */
+#include "GenQTest.h"
+
+#define genqQUEUE_LENGTH        ( 5 )
+#define genqNO_BLOCK            ( 0 )
+
+#define genqMUTEX_LOW_PRIORITY        ( tskIDLE_PRIORITY )
+#define genqMUTEX_TEST_PRIORITY        ( tskIDLE_PRIORITY + 1 )
+#define genqMUTEX_MEDIUM_PRIORITY    ( tskIDLE_PRIORITY + 2 )
+#define genqMUTEX_HIGH_PRIORITY        ( tskIDLE_PRIORITY + 3 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()
+ * macros by using both to fill a queue, then reading from the queue to
+ * check the resultant queue order is as expected.  Queue data is also
+ * peeked.
+ */
+static void prvSendFrontAndBackTest( void *pvParameters );
+
+/*
+ * The following three tasks are used to demonstrate the mutex behaviour.
+ * Each task is given a different priority to demonstrate the priority
+ * inheritance mechanism.
+ *
+ * The low priority task obtains a mutex.  After this a high priority task
+ * attempts to obtain the same mutex, causing its priority to be inherited
+ * by the low priority task.  The task with the inherited high priority then
+ * resumes a medium priority task to ensure it is not blocked by the medium
+ * priority task while it holds the inherited high priority.  Once the mutex
+ * is returned the task with the inherited priority returns to its original
+ * low priority, and is therefore immediately preempted by first the high
+ * priority task and then the medium prioroity task before it can continue.
+ */
+static void prvLowPriorityMutexTask( void *pvParameters );
+static void prvMediumPriorityMutexTask( void *pvParameters );
+static void prvHighPriorityMutexTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be
+detected in any of the tasks. */
+static portBASE_TYPE xErrorDetected = pdFALSE;
+
+/* Counters that are incremented on each cycle of a test.  This is used to
+detect a stalled task - a test that is no longer running. */
+static volatile unsigned portLONG ulLoopCounter = 0;
+static volatile unsigned portLONG ulLoopCounter2 = 0;
+
+/* The variable that is guarded by the mutex in the mutex demo tasks. */
+static volatile unsigned portLONG ulGuardedVariable = 0;
+
+/* Handles used in the mutext test to suspend and resume the high and medium
+priority mutex test tasks. */
+static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;
+
+/*-----------------------------------------------------------*/
+
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )
+{
+xQueueHandle xQueue;
+xSemaphoreHandle xMutex;
+
+    /* Create the queue that we are going to use for the
+    prvSendFrontAndBackTest demo. */
+    xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );
+
+    /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
+    in use.  The queue registry is provided as a means for kernel aware 
+    debuggers to locate queues and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" );
+
+    /* Create the demo task and pass it the queue just created.  We are
+    passing the queue handle by value so it does not matter that it is
+    declared on the stack here. */
+    xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
+
+    /* Create the mutex used by the prvMutexTest task. */
+    xMutex = xSemaphoreCreateMutex();
+
+    /* vQueueAddToRegistry() adds the mutex to the registry, if one is
+    in use.  The registry is provided as a means for kernel aware 
+    debuggers to locate mutexes and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" );
+
+    /* Create the mutex demo tasks and pass it the mutex just created.  We are
+    passing the mutex handle by value so it does not matter that it is declared
+    on the stack here. */
+    xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
+    xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
+    xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
+}
+/*-----------------------------------------------------------*/
+
+static void prvSendFrontAndBackTest( void *pvParameters )
+{
+unsigned portLONG ulData, ulData2;
+xQueueHandle xQueue;
+
+    #ifdef USE_STDIO
+    void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
+    
+        const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";
+
+        /* Queue a message for printing to say the task has started. */
+        vPrintDisplayMessage( &pcTaskStartMsg );
+    #endif
+
+    xQueue = ( xQueueHandle ) pvParameters;
+
+    for( ;; )
+    {
+        /* The queue is empty, so sending an item to the back of the queue
+        should have the same efect as sending it to the front of the queue.
+
+        First send to the front and check everything is as expected. */
+        xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* The data we sent to the queue should equal the data we just received
+        from the queue. */
+        if( ulLoopCounter != ulData )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Then do the same, sending the data to the back, checking everything
+        is as expected. */
+        if( uxQueueMessagesWaiting( xQueue ) != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* The data we sent to the queue should equal the data we just received
+        from the queue. */
+        if( ulLoopCounter != ulData )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        #if configUSE_PREEMPTION == 0
+            taskYIELD();
+        #endif
+
+
+
+        /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
+        for( ulData = 2; ulData < 5; ulData++ )
+        {
+            xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );
+        }
+
+        /* Now the order in the queue should be 2, 3, 4, with 2 being the first
+        thing to be read out.  Now add 1 then 0 to the front of the queue. */
+        if( uxQueueMessagesWaiting( xQueue ) != 3 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+        ulData = 1;
+        xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
+        ulData = 0;
+        xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
+
+        /* Now the queue should be full, and when we read the data out we
+        should receive 0, 1, 2, 3, 4. */
+        if( uxQueueMessagesWaiting( xQueue ) != 5 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        #if configUSE_PREEMPTION == 0
+            taskYIELD();
+        #endif
+
+        /* Check the data we read out is in the expected order. */
+        for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
+        {
+            /* Try peeking the data first. */
+            if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
+            {
+                xErrorDetected = pdTRUE;
+            }
+
+            if( ulData != ulData2 )
+            {
+                xErrorDetected = pdTRUE;
+            }
+            
+
+            /* Now try receiving the data for real.  The value should be the
+            same.  Clobber the value first so we know we really received it. */
+            ulData2 = ~ulData2;
+            if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
+            {
+                xErrorDetected = pdTRUE;
+            }
+
+            if( ulData != ulData2 )
+            {
+                xErrorDetected = pdTRUE;
+            }
+        }
+
+        /* The queue should now be empty again. */
+        if( uxQueueMessagesWaiting( xQueue ) != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        #if configUSE_PREEMPTION == 0
+            taskYIELD();
+        #endif
+
+
+        /* Our queue is empty once more, add 10, 11 to the back. */
+        ulData = 10;
+        if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+        ulData = 11;
+        if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 2 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Now we should have 10, 11 in the queue.  Add 7, 8, 9 to the
+        front. */
+        for( ulData = 9; ulData >= 7; ulData-- )
+        {
+            if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
+            {
+                xErrorDetected = pdTRUE;
+            }
+        }
+
+        /* Now check that the queue is full, and that receiving data provides
+        the expected sequence of 7, 8, 9, 10, 11. */
+        if( uxQueueMessagesWaiting( xQueue ) != 5 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        #if configUSE_PREEMPTION == 0
+            taskYIELD();
+        #endif
+
+        /* Check the data we read out is in the expected order. */
+        for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
+        {
+            if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
+            {
+                xErrorDetected = pdTRUE;
+            }
+
+            if( ulData != ulData2 )
+            {
+                xErrorDetected = pdTRUE;
+            }
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        ulLoopCounter++;
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvLowPriorityMutexTask( void *pvParameters )
+{
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
+
+    #ifdef USE_STDIO
+    void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
+    
+        const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";
+
+        /* Queue a message for printing to say the task has started. */
+        vPrintDisplayMessage( &pcTaskStartMsg );
+    #endif
+
+    for( ;; )
+    {
+        /* Take the mutex.  It should be available now. */
+        if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Set our guarded variable to a known start value. */
+        ulGuardedVariable = 0;
+
+        /* Our priority should be as per that assigned when the task was
+        created. */
+        if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Now unsuspend the high priority task.  This will attempt to take the
+        mutex, and block when it finds it cannot obtain it. */
+        vTaskResume( xHighPriorityMutexTask );
+
+        /* We should now have inherited the prioritoy of the high priority task,
+        as by now it will have attempted to get the mutex. */
+        if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* We can attempt to set our priority to the test priority - between the
+        idle priority and the medium/high test priorities, but our actual
+        prioroity should remain at the high priority. */
+        vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
+        if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Now unsuspend the medium priority task.  This should not run as our
+        inherited priority is above that of the medium priority task. */
+        vTaskResume( xMediumPriorityMutexTask );
+
+        /* If the did run then it will have incremented our guarded variable. */
+        if( ulGuardedVariable != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we give back the semaphore our priority should be disinherited
+        back to the priority to which we attempted to set ourselves.  This means
+        that when the high priority task next blocks, the medium priority task
+        should execute and increment the guarded variable.   When we next run
+        both the high and medium priority tasks will have been suspended again. */
+        if( xSemaphoreGive( xMutex ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Check that the guarded variable did indeed increment... */
+        if( ulGuardedVariable != 1 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* ... and that our priority has been disinherited to
+        genqMUTEX_TEST_PRIORITY. */
+        if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Set our priority back to our original priority ready for the next
+        loop around this test. */
+        vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
+
+        /* Just to show we are still running. */
+        ulLoopCounter2++;
+
+        #if configUSE_PREEMPTION == 0
+            taskYIELD();
+        #endif        
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvMediumPriorityMutexTask( void *pvParameters )
+{
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /* The medium priority task starts by suspending itself.  The low
+        priority task will unsuspend this task when required. */
+        vTaskSuspend( NULL );
+
+        /* When this task unsuspends all it does is increment the guarded
+        variable, this is so the low priority task knows that it has
+        executed. */
+        ulGuardedVariable++;
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighPriorityMutexTask( void *pvParameters )
+{
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
+
+    for( ;; )
+    {
+        /* The high priority task starts by suspending itself.  The low
+        priority task will unsuspend this task when required. */
+        vTaskSuspend( NULL );
+
+        /* When this task unsuspends all it does is attempt to obtain
+        the mutex.  It should find the mutex is not available so a
+        block time is specified. */
+        if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we eventually obtain the mutex we just give it back then
+        return to suspend ready for the next test. */
+        if( xSemaphoreGive( xMutex ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }        
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void )
+{
+static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
+
+    /* If the demo task is still running then we expect the loopcounters to
+    have incremented since this function was last called. */
+    if( ulLastLoopCounter == ulLoopCounter )
+    {
+        xErrorDetected = pdTRUE;
+    }
+
+    if( ulLastLoopCounter2 == ulLoopCounter2 )
+    {
+        xErrorDetected = pdTRUE;
+    }
+
+    ulLastLoopCounter = ulLoopCounter;
+    ulLastLoopCounter2 = ulLoopCounter2;    
+
+    /* Errors detected in the task itself will have latched xErrorDetected
+    to true. */
+
+    return !xErrorDetected;
+}
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/PollQ.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/PollQ.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,246 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * This version of PollQ. c is for use on systems that have limited stack
+ * space and no display facilities.  The complete version can be found in
+ * the Demo/Common/Full directory.
+ *
+ * Creates two tasks that communicate over a single queue.  One task acts as a
+ * producer, the other a consumer.
+ *
+ * The producer loops for three iteration, posting an incrementing number onto the
+ * queue each cycle.  It then delays for a fixed period before doing exactly the
+ * same again.
+ *
+ * The consumer loops emptying the queue.  Each item removed from the queue is
+ * checked to ensure it contains the expected value.  When the queue is empty it
+ * blocks for a fixed period, then does the same again.
+ *
+ * All queue access is performed without blocking.  The consumer completely empties
+ * the queue each time it runs so the producer should never find the queue full.
+ *
+ * An error is flagged if the consumer obtains an unexpected value or the producer
+ * find the queue is full.
+ */
+
+/*
+Changes from V2.0.0
+
+    + Delay periods are now specified using variables and constants of
+      portTickType rather than unsigned long.
+*/
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo program include files. */
+#include "PollQ.h"
+
+#define pollqSTACK_SIZE            configMINIMAL_STACK_SIZE
+#define pollqQUEUE_SIZE            ( 10 )
+#define pollqPRODUCER_DELAY        ( ( portTickType ) 200 / portTICK_RATE_MS )
+#define pollqCONSUMER_DELAY        ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) )
+#define pollqNO_DELAY            ( ( portTickType ) 0 )
+#define pollqVALUES_TO_PRODUCE    ( ( signed portBASE_TYPE ) 3 )
+#define pollqINITIAL_VALUE        ( ( signed portBASE_TYPE ) 0 )
+
+/* The task that posts the incrementing number onto the queue. */
+static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters );
+
+/* The task that empties the queue. */
+static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters );
+
+/* Variables that are used to check that the tasks are still running with no
+errors. */
+static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;
+
+/*-----------------------------------------------------------*/
+
+void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority )
+{
+static xQueueHandle xPolledQueue;
+
+    /* Create the queue used by the producer and consumer. */
+    xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
+
+    /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
+    in use.  The queue registry is provided as a means for kernel aware 
+    debuggers to locate queues and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( xPolledQueue, ( signed char * ) "Poll_Test_Queue" );
+
+    /* Spawn the producer and consumer. */
+    xTaskCreate( vPolledQueueConsumer, ( signed char * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );
+    xTaskCreate( vPolledQueueProducer, ( signed char * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )
+{
+unsigned short usValue = ( unsigned short ) 0;
+signed portBASE_TYPE xError = pdFALSE, xLoop;
+
+    for( ;; )
+    {        
+        for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )
+        {
+            /* Send an incrementing number on the queue without blocking. */
+            if( xQueueSend( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )
+            {
+                /* We should never find the queue full so if we get here there
+                has been an error. */
+                xError = pdTRUE;
+            }
+            else
+            {
+                if( xError == pdFALSE )
+                {
+                    /* If an error has ever been recorded we stop incrementing the
+                    check variable. */
+                    portENTER_CRITICAL();
+                        xPollingProducerCount++;
+                    portEXIT_CRITICAL();
+                }
+
+                /* Update the value we are going to post next time around. */
+                usValue++;
+            }
+        }
+
+        /* Wait before we start posting again to ensure the consumer runs and
+        empties the queue. */
+        vTaskDelay( pollqPRODUCER_DELAY );
+    }
+}  /*lint !e818 Function prototype must conform to API. */
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )
+{
+unsigned short usData, usExpectedValue = ( unsigned short ) 0;
+signed portBASE_TYPE xError = pdFALSE;
+
+    for( ;; )
+    {        
+        /* Loop until the queue is empty. */
+        while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) )
+        {
+            if( xQueueReceive( *( ( xQueueHandle * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS )
+            {
+                if( usData != usExpectedValue )
+                {
+                    /* This is not what we expected to receive so an error has
+                    occurred. */
+                    xError = pdTRUE;
+
+                    /* Catch-up to the value we received so our next expected
+                    value should again be correct. */
+                    usExpectedValue = usData;
+                }
+                else
+                {
+                    if( xError == pdFALSE )
+                    {
+                        /* Only increment the check variable if no errors have
+                        occurred. */
+                        portENTER_CRITICAL();
+                            xPollingConsumerCount++;
+                        portEXIT_CRITICAL();
+                    }
+                }
+
+                /* Next time round we would expect the number to be one higher. */
+                usExpectedValue++;
+            }
+        }
+
+        /* Now the queue is empty we block, allowing the producer to place more
+        items in the queue. */
+        vTaskDelay( pollqCONSUMER_DELAY );
+    }
+} /*lint !e818 Function prototype must conform to API. */
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running with no errors. */
+portBASE_TYPE xArePollingQueuesStillRunning( void )
+{
+portBASE_TYPE xReturn;
+
+    /* Check both the consumer and producer poll count to check they have both
+    been changed since out last trip round.  We do not need a critical section
+    around the check variables as this is called from a higher priority than
+    the other tasks that access the same variables. */
+    if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) ||
+        ( xPollingProducerCount == pollqINITIAL_VALUE )
+      )
+    {
+        xReturn = pdFALSE;
+    }
+    else
+    {
+        xReturn = pdTRUE;
+    }
+
+    /* Set the check variables back down so we know if they have been
+    incremented the next time around. */
+    xPollingConsumerCount = pollqINITIAL_VALUE;
+    xPollingProducerCount = pollqINITIAL_VALUE;
+
+    return xReturn;
+}
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/QPeek.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/QPeek.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,446 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+/* 
+ * Tests the behaviour when data is peeked from a queue when there are
+ * multiple tasks blocked on the queue.
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Demo program include files. */
+#include "QPeek.h"
+
+#define qpeekQUEUE_LENGTH        ( 5 )
+#define qpeekNO_BLOCK            ( 0 )
+#define qpeekSHORT_DELAY        ( 10 )
+
+#define qpeekLOW_PRIORITY            ( tskIDLE_PRIORITY + 0 )
+#define qpeekMEDIUM_PRIORITY        ( tskIDLE_PRIORITY + 1 )
+#define qpeekHIGH_PRIORITY            ( tskIDLE_PRIORITY + 2 )
+#define qpeekHIGHEST_PRIORITY        ( tskIDLE_PRIORITY + 3 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * The following three tasks are used to demonstrate the peeking behaviour.
+ * Each task is given a different priority to demonstrate the order in which
+ * tasks are woken as data is peeked from a queue.
+ */
+static void prvLowPriorityPeekTask( void *pvParameters );
+static void prvMediumPriorityPeekTask( void *pvParameters );
+static void prvHighPriorityPeekTask( void *pvParameters );
+static void prvHighestPriorityPeekTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be
+detected in any of the tasks. */
+static volatile portBASE_TYPE xErrorDetected = pdFALSE;
+
+/* Counter that is incremented on each cycle of a test.  This is used to
+detect a stalled task - a test that is no longer running. */
+static volatile unsigned portLONG ulLoopCounter = 0;
+
+/* Handles to the test tasks. */
+xTaskHandle xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask;
+/*-----------------------------------------------------------*/
+
+void vStartQueuePeekTasks( void )
+{
+xQueueHandle xQueue;
+
+    /* Create the queue that we are going to use for the test/demo. */
+    xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( unsigned portLONG ) );
+
+    /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
+    in use.  The queue registry is provided as a means for kernel aware 
+    debuggers to locate queues and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "QPeek_Test_Queue" );
+
+    /* Create the demo tasks and pass it the queue just created.  We are
+    passing the queue handle by value so it does not matter that it is declared
+    on the stack here. */
+    xTaskCreate( prvLowPriorityPeekTask, ( signed portCHAR * )"PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );
+    xTaskCreate( prvMediumPriorityPeekTask, ( signed portCHAR * )"PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );
+    xTaskCreate( prvHighPriorityPeekTask, ( signed portCHAR * )"PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );
+    xTaskCreate( prvHighestPriorityPeekTask, ( signed portCHAR * )"PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighestPriorityPeekTask( void *pvParameters )
+{
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
+unsigned portLONG ulValue;
+
+    #ifdef USE_STDIO
+    {
+        void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
+    
+        const portCHAR * const pcTaskStartMsg = "Queue peek test started.\r\n";
+
+        /* Queue a message for printing to say the task has started. */
+        vPrintDisplayMessage( &pcTaskStartMsg );
+    }
+    #endif
+
+    for( ;; )
+    {
+        /* Try peeking from the queue.  The queue should be empty so we will
+        block, allowing the high priority task to execute. */
+        if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            /* We expected to have received something by the time we unblock. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we reach here the high and medium priority tasks should still
+        be blocked on the queue.  We unblocked because the low priority task
+        wrote a value to the queue, which we should have peeked.  Peeking the
+        data (rather than receiving it) will leave the data on the queue, so
+        the high priority task should then have also been unblocked, but not
+        yet executed. */
+        if( ulValue != 0x11223344 )
+        {
+            /* We did not receive the expected value. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            /* The message should have been left on the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Now we are going to actually receive the data, so when the high
+        priority task runs it will find the queue empty and return to the
+        blocked state. */
+        ulValue = 0;
+        if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
+        {
+            /* We expected to receive the value. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( ulValue != 0x11223344 )
+        {
+            /* We did not receive the expected value - which should have been
+            the same value as was peeked. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Now we will block again as the queue is once more empty.  The low 
+        priority task can then execute again. */
+        if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            /* We expected to have received something by the time we unblock. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we get here the low priority task should have again written to the
+        queue. */
+        if( ulValue != 0x01234567 )
+        {
+            /* We did not receive the expected value. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            /* The message should have been left on the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* We only peeked the data, so suspending ourselves now should enable
+        the high priority task to also peek the data.  The high priority task
+        will have been unblocked when we peeked the data as we left the data
+        in the queue. */
+        vTaskSuspend( NULL );
+
+
+
+        /* This time we are going to do the same as the above test, but the
+        high priority task is going to receive the data, rather than peek it.
+        This means that the medium priority task should never peek the value. */
+        if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( ulValue != 0xaabbaabb )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        vTaskSuspend( NULL );        
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighPriorityPeekTask( void *pvParameters )
+{
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
+unsigned portLONG ulValue;
+
+    for( ;; )
+    {
+        /* Try peeking from the queue.  The queue should be empty so we will
+        block, allowing the medium priority task to execute.  Both the high
+        and highest priority tasks will then be blocked on the queue. */
+        if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            /* We expected to have received something by the time we unblock. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we get here the highest priority task should have peeked the data
+        (unblocking this task) then suspended (allowing this task to also peek
+        the data). */
+        if( ulValue != 0x01234567 )
+        {
+            /* We did not receive the expected value. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            /* The message should have been left on the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* We only peeked the data, so suspending ourselves now should enable
+        the medium priority task to also peek the data.  The medium priority task
+        will have been unblocked when we peeked the data as we left the data
+        in the queue. */
+        vTaskSuspend( NULL );
+
+
+        /* This time we are going actually receive the value, so the medium
+        priority task will never peek the data - we removed it from the queue. */
+        if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        if( ulValue != 0xaabbaabb )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        vTaskSuspend( NULL );                
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvMediumPriorityPeekTask( void *pvParameters )
+{
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
+unsigned portLONG ulValue;
+
+    for( ;; )
+    {
+        /* Try peeking from the queue.  The queue should be empty so we will
+        block, allowing the low priority task to execute.  The highest, high
+        and medium priority tasks will then all be blocked on the queue. */
+        if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
+        {
+            /* We expected to have received something by the time we unblock. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* When we get here the high priority task should have peeked the data
+        (unblocking this task) then suspended (allowing this task to also peek
+        the data). */
+        if( ulValue != 0x01234567 )
+        {
+            /* We did not receive the expected value. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( uxQueueMessagesWaiting( xQueue ) != 1 )
+        {
+            /* The message should have been left on the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Just so we know the test is still running. */
+        ulLoopCounter++;
+
+        /* Now we can suspend ourselves so the low priority task can execute
+        again. */
+        vTaskSuspend( NULL );
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvLowPriorityPeekTask( void *pvParameters )
+{
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
+unsigned portLONG ulValue;
+
+    for( ;; )
+    {
+        /* Write some data to the queue.  This should unblock the highest 
+        priority task that is waiting to peek data from the queue. */
+        ulValue = 0x11223344;
+        if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
+        {
+            /* We were expecting the queue to be empty so we should not of
+            had a problem writing to the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* By the time we get here the data should have been removed from
+        the queue. */
+        if( uxQueueMessagesWaiting( xQueue ) != 0 )
+        {
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Write another value to the queue, again waking the highest priority
+        task that is blocked on the queue. */
+        ulValue = 0x01234567;
+        if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
+        {
+            /* We were expecting the queue to be empty so we should not of
+            had a problem writing to the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* All the other tasks should now have successfully peeked the data.
+        The data is still in the queue so we should be able to receive it. */
+        ulValue = 0;
+        if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
+        {
+            /* We expected to receive the data. */
+            xErrorDetected = pdTRUE;
+        }
+
+        if( ulValue != 0x01234567 )
+        {
+            /* We did not receive the expected value. */
+        }
+        
+        /* Lets just delay a while as this is an intensive test as we don't
+        want to starve other tests of processing time. */
+        vTaskDelay( qpeekSHORT_DELAY );
+
+        /* Unsuspend the other tasks so we can repeat the test - this time
+        however not all the other tasks will peek the data as the high
+        priority task is actually going to remove it from the queue.  Send
+        to front is used just to be different.  As the queue is empty it
+        makes no difference to the result. */
+        vTaskResume( xMediumPriorityTask );
+        vTaskResume( xHighPriorityTask );
+        vTaskResume( xHighestPriorityTask );
+
+        ulValue = 0xaabbaabb;
+        if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
+        {
+            /* We were expecting the queue to be empty so we should not of
+            had a problem writing to the queue. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* This time we should find that the queue is empty.  The high priority
+        task actually removed the data rather than just peeking it. */
+        if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY )
+        {
+            /* We expected to receive the data. */
+            xErrorDetected = pdTRUE;
+        }
+
+        /* Unsuspend the highest and high priority tasks so we can go back
+        and repeat the whole thing.  The medium priority task should not be
+        suspended as it was not able to peek the data in this last case. */
+        vTaskResume( xHighPriorityTask );
+        vTaskResume( xHighestPriorityTask );        
+
+        /* Lets just delay a while as this is an intensive test as we don't
+        want to starve other tests of processing time. */
+        vTaskDelay( qpeekSHORT_DELAY );
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreQueuePeekTasksStillRunning( void )
+{
+static unsigned portLONG ulLastLoopCounter = 0;
+
+    /* If the demo task is still running then we expect the loopcounter to
+    have incremented since this function was last called. */
+    if( ulLastLoopCounter == ulLoopCounter )
+    {
+        xErrorDetected = pdTRUE;
+    }
+
+    ulLastLoopCounter = ulLoopCounter;
+
+    /* Errors detected in the task itself will have latched xErrorDetected
+    to true. */
+
+    return !xErrorDetected;
+}
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/blocktim.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/blocktim.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,493 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+    
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * This file contains some test scenarios that ensure tasks do not exit queue
+ * send or receive functions prematurely.  A description of the tests is
+ * included within the code.
+ */
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo includes. */
+#include "blocktim.h"
+
+/* Task priorities.  Allow these to be overridden. */
+#ifndef bktPRIMARY_PRIORITY
+    #define bktPRIMARY_PRIORITY            ( 3 )
+#endif
+
+#ifndef bktSECONDARY_PRIORITY
+    #define bktSECONDARY_PRIORITY        ( 2 )
+#endif
+
+/* Task behaviour. */
+#define bktQUEUE_LENGTH                ( 5 )
+#define bktSHORT_WAIT                ( ( ( portTickType ) 20 ) / portTICK_RATE_MS )
+#define bktPRIMARY_BLOCK_TIME        ( 10 )
+#define bktALLOWABLE_MARGIN            ( 15 )
+#define bktTIME_TO_BLOCK            ( 175 )
+#define bktDONT_BLOCK                ( ( portTickType ) 0 )
+#define bktRUN_INDICATOR            ( ( unsigned portBASE_TYPE ) 0x55 )
+
+/* The queue on which the tasks block. */
+static xQueueHandle xTestQueue;
+
+/* Handle to the secondary task is required by the primary task for calls
+to vTaskSuspend/Resume(). */
+static xTaskHandle xSecondary;
+
+/* Used to ensure that tasks are still executing without error. */
+static volatile portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE;
+
+/* Provides a simple mechanism for the primary task to know when the
+secondary task has executed. */
+static volatile unsigned portBASE_TYPE xRunIndicator;
+
+/* The two test tasks.  Their behaviour is commented within the files. */
+static void vPrimaryBlockTimeTestTask( void *pvParameters );
+static void vSecondaryBlockTimeTestTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+void vCreateBlockTimeTasks( void )
+{
+    /* Create the queue on which the two tasks block. */
+    xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) );
+
+    /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
+    in use.  The queue registry is provided as a means for kernel aware
+    debuggers to locate queues and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
+    defined to be less than 1. */
+    vQueueAddToRegistry( xTestQueue, ( signed char * ) "Block_Time_Queue" );
+
+    /* Create the two test tasks. */
+    xTaskCreate( vPrimaryBlockTimeTestTask, ( signed char * )"BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
+    xTaskCreate( vSecondaryBlockTimeTestTask, ( signed char * )"BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
+}
+/*-----------------------------------------------------------*/
+
+static void vPrimaryBlockTimeTestTask( void *pvParameters )
+{
+portBASE_TYPE xItem, xData;
+portTickType xTimeWhenBlocking;
+portTickType xTimeToBlock, xBlockedTime;
+
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /*********************************************************************
+        Test 1
+
+        Simple block time wakeup test on queue receives. */
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            /* The queue is empty. Attempt to read from the queue using a block
+            time.  When we wake, ensure the delta in time is as expected. */
+            xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
+
+            xTimeWhenBlocking = xTaskGetTickCount();
+
+            /* We should unblock after xTimeToBlock having not received
+            anything on the queue. */
+            if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* How long were we blocked for? */
+            xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+            if( xBlockedTime < xTimeToBlock )
+            {
+                /* Should not have blocked for less than we requested. */
+                xErrorOccurred = pdTRUE;
+            }
+
+            if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
+            {
+                /* Should not have blocked for longer than we requested,
+                although we would not necessarily run as soon as we were
+                unblocked so a margin is allowed. */
+                xErrorOccurred = pdTRUE;
+            }
+        }
+
+        /*********************************************************************
+        Test 2
+
+        Simple block time wakeup test on queue sends.
+
+        First fill the queue.  It should be empty so all sends should pass. */
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            #if configUSE_PREEMPTION == 0
+                taskYIELD();
+            #endif
+        }
+
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            /* The queue is full. Attempt to write to the queue using a block
+            time.  When we wake, ensure the delta in time is as expected. */
+            xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
+
+            xTimeWhenBlocking = xTaskGetTickCount();
+
+            /* We should unblock after xTimeToBlock having not received
+            anything on the queue. */
+            if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* How long were we blocked for? */
+            xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+            if( xBlockedTime < xTimeToBlock )
+            {
+                /* Should not have blocked for less than we requested. */
+                xErrorOccurred = pdTRUE;
+            }
+
+            if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
+            {
+                /* Should not have blocked for longer than we requested,
+                although we would not necessarily run as soon as we were
+                unblocked so a margin is allowed. */
+                xErrorOccurred = pdTRUE;
+            }
+        }
+
+        /*********************************************************************
+        Test 3
+
+        Wake the other task, it will block attempting to post to the queue.
+        When we read from the queue the other task will wake, but before it
+        can run we will post to the queue again.  When the other task runs it
+        will find the queue still full, even though it was woken.  It should
+        recognise that its block time has not expired and return to block for
+        the remains of its block time.
+
+        Wake the other task so it blocks attempting to post to the already
+        full queue. */
+        xRunIndicator = 0;
+        vTaskResume( xSecondary );
+
+        /* We need to wait a little to ensure the other task executes. */
+        while( xRunIndicator != bktRUN_INDICATOR )
+        {
+            /* The other task has not yet executed. */
+            vTaskDelay( bktSHORT_WAIT );
+        }
+        /* Make sure the other task is blocked on the queue. */
+        vTaskDelay( bktSHORT_WAIT );
+        xRunIndicator = 0;
+
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            /* Now when we make space on the queue the other task should wake
+            but not execute as this task has higher priority. */
+            if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Now fill the queue again before the other task gets a chance to
+            execute.  If the other task had executed we would find the queue
+            full ourselves, and the other task have set xRunIndicator. */
+            if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            if( xRunIndicator == bktRUN_INDICATOR )
+            {
+                /* The other task should not have executed. */
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Raise the priority of the other task so it executes and blocks
+            on the queue again. */
+            vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
+
+            /* The other task should now have re-blocked without exiting the
+            queue function. */
+            if( xRunIndicator == bktRUN_INDICATOR )
+            {
+                /* The other task should not have executed outside of the
+                queue function. */
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Set the priority back down. */
+            vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
+        }
+
+        /* Let the other task timeout.  When it unblockes it will check that it
+        unblocked at the correct time, then suspend itself. */
+        while( xRunIndicator != bktRUN_INDICATOR )
+        {
+            vTaskDelay( bktSHORT_WAIT );
+        }
+        vTaskDelay( bktSHORT_WAIT );
+        xRunIndicator = 0;
+
+
+        /*********************************************************************
+        Test 4
+
+        As per test 3 - but with the send and receive the other way around.
+        The other task blocks attempting to read from the queue.
+
+        Empty the queue.  We should find that it is full. */
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+        }
+
+        /* Wake the other task so it blocks attempting to read from  the
+        already    empty queue. */
+        vTaskResume( xSecondary );
+
+        /* We need to wait a little to ensure the other task executes. */
+        while( xRunIndicator != bktRUN_INDICATOR )
+        {
+            vTaskDelay( bktSHORT_WAIT );
+        }
+        vTaskDelay( bktSHORT_WAIT );
+        xRunIndicator = 0;
+
+        for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
+        {
+            /* Now when we place an item on the queue the other task should
+            wake but not execute as this task has higher priority. */
+            if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Now empty the queue again before the other task gets a chance to
+            execute.  If the other task had executed we would find the queue
+            empty ourselves, and the other task would be suspended. */
+            if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            if( xRunIndicator == bktRUN_INDICATOR )
+            {
+                /* The other task should not have executed. */
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Raise the priority of the other task so it executes and blocks
+            on the queue again. */
+            vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
+
+            /* The other task should now have re-blocked without exiting the
+            queue function. */
+            if( xRunIndicator == bktRUN_INDICATOR )
+            {
+                /* The other task should not have executed outside of the
+                queue function. */
+                xErrorOccurred = pdTRUE;
+            }
+            vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
+        }
+
+        /* Let the other task timeout.  When it unblockes it will check that it
+        unblocked at the correct time, then suspend itself. */
+        while( xRunIndicator != bktRUN_INDICATOR )
+        {
+            vTaskDelay( bktSHORT_WAIT );
+        }
+        vTaskDelay( bktSHORT_WAIT );
+
+        xPrimaryCycles++;
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void vSecondaryBlockTimeTestTask( void *pvParameters )
+{
+portTickType xTimeWhenBlocking, xBlockedTime;
+portBASE_TYPE xData;
+
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /*********************************************************************
+        Test 1 and 2
+
+        This task does does not participate in these tests. */
+        vTaskSuspend( NULL );
+
+        /*********************************************************************
+        Test 3
+
+        The first thing we do is attempt to read from the queue.  It should be
+        full so we block.  Note the time before we block so we can check the
+        wake time is as per that expected. */
+        xTimeWhenBlocking = xTaskGetTickCount();
+
+        /* We should unblock after bktTIME_TO_BLOCK having not sent
+        anything to the queue. */
+        xData = 0;
+        xRunIndicator = bktRUN_INDICATOR;
+        if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* How long were we inside the send function? */
+        xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+        /* We should not have blocked for less time than bktTIME_TO_BLOCK. */
+        if( xBlockedTime < bktTIME_TO_BLOCK )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* We should of not blocked for much longer than bktALLOWABLE_MARGIN
+        either.  A margin is permitted as we would not necessarily run as
+        soon as we unblocked. */
+        if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* Suspend ready for test 3. */
+        xRunIndicator = bktRUN_INDICATOR;
+        vTaskSuspend( NULL );
+
+        /*********************************************************************
+        Test 4
+
+        As per test three, but with the send and receive reversed. */
+        xTimeWhenBlocking = xTaskGetTickCount();
+
+        /* We should unblock after bktTIME_TO_BLOCK having not received
+        anything on the queue. */
+        xRunIndicator = bktRUN_INDICATOR;
+        if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+        /* We should not have blocked for less time than bktTIME_TO_BLOCK. */
+        if( xBlockedTime < bktTIME_TO_BLOCK )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* We should of not blocked for much longer than bktALLOWABLE_MARGIN
+        either.  A margin is permitted as we would not necessarily run as soon
+        as we unblocked. */
+        if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        xRunIndicator = bktRUN_INDICATOR;
+
+        xSecondaryCycles++;
+    }
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void )
+{
+static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;
+portBASE_TYPE xReturn = pdPASS;
+
+    /* Have both tasks performed at least one cycle since this function was
+    last called? */
+    if( xPrimaryCycles == xLastPrimaryCycleCount )
+    {
+        xReturn = pdFAIL;
+    }
+
+    if( xSecondaryCycles == xLastSecondaryCycleCount )
+    {
+        xReturn = pdFAIL;
+    }
+
+    if( xErrorOccurred == pdTRUE )
+    {
+        xReturn = pdFAIL;
+    }
+
+    xLastSecondaryCycleCount = xSecondaryCycles;
+    xLastPrimaryCycleCount = xPrimaryCycles;
+
+    return xReturn;
+}
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/flash.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/flash.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,145 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/**
+ * This version of flash .c is for use on systems that have limited stack space
+ * and no display facilities.  The complete version can be found in the 
+ * Demo/Common/Full directory.
+ * 
+ * Three tasks are created, each of which flash an LED at a different rate.  The first 
+ * LED flashes every 200ms, the second every 400ms, the third every 600ms.
+ *
+ * The LED flash tasks provide instant visual feedback.  They show that the scheduler 
+ * is still operational.
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Demo program include files. */
+#include "partest.h"
+#include "flash.h"
+
+#define ledSTACK_SIZE        configMINIMAL_STACK_SIZE
+#define ledNUMBER_OF_LEDS    ( 3 )
+#define ledFLASH_RATE_BASE    ( ( portTickType ) 333 )
+
+/* Variable used by the created tasks to calculate the LED number to use, and
+the rate at which they should flash the LED. */
+static volatile unsigned portBASE_TYPE uxFlashTaskNumber = 0;
+
+/* The task that is created three times. */
+static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters );
+
+/*-----------------------------------------------------------*/
+
+void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority )
+{
+signed portBASE_TYPE xLEDTask;
+
+    /* Create the three tasks. */
+    for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )
+    {
+        /* Spawn the task. */
+        xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );
+    }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vLEDFlashTask, pvParameters )
+{
+portTickType xFlashRate, xLastFlashTime;
+unsigned portBASE_TYPE uxLED;
+
+    /* The parameters are not used. */
+    ( void ) pvParameters;
+
+    /* Calculate the LED and flash rate. */
+    portENTER_CRITICAL();
+    {
+        /* See which of the eight LED's we should use. */
+        uxLED = uxFlashTaskNumber;
+
+        /* Update so the next task uses the next LED. */
+        uxFlashTaskNumber++;
+    }
+    portEXIT_CRITICAL();
+
+    xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) uxLED );
+    xFlashRate /= portTICK_RATE_MS;
+
+    /* We will turn the LED on and off again in the delay period, so each
+    delay is only half the total period. */
+    xFlashRate /= ( portTickType ) 2;
+
+    /* We need to initialise xLastFlashTime prior to the first call to 
+    vTaskDelayUntil(). */
+    xLastFlashTime = xTaskGetTickCount();
+
+    for(;;)
+    {
+        /* Delay for half the flash period then turn the LED on. */
+        vTaskDelayUntil( &xLastFlashTime, xFlashRate );
+        vParTestToggleLED( uxLED );
+
+        /* Delay for half the flash period then turn the LED off. */
+        vTaskDelayUntil( &xLastFlashTime, xFlashRate );
+        vParTestToggleLED( uxLED );
+    }
+} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/integer.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/integer.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,212 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * This version of integer. c is for use on systems that have limited stack
+ * space and no display facilities.  The complete version can be found in
+ * the Demo/Common/Full directory.
+ *
+ * As with the full version, the tasks created in this file are a good test 
+ * of the scheduler context switch mechanism.  The processor has to access 
+ * 32bit variables in two or four chunks (depending on the processor).  The low 
+ * priority of these tasks means there is a high probability that a context 
+ * switch will occur mid calculation.  See flop. c documentation for 
+ * more information.
+ *
+ */
+
+/*
+Changes from V1.2.1
+
+    + The constants used in the calculations are larger to ensure the
+      optimiser does not truncate them to 16 bits.
+
+Changes from V1.2.3
+
+    + uxTaskCheck is now just used as a boolean.  Instead of incrementing
+      the variable each cycle of the task, the variable is simply set to
+      true.  sAreIntegerMathsTaskStillRunning() sets it back to false and
+      expects it to have been set back to true by the time it is called
+      again.
+    + A division has been included in the calculation.
+*/
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Demo program include files. */
+#include "integer.h"
+
+/* The constants used in the calculation. */
+#define intgCONST1                ( ( long ) 123 )
+#define intgCONST2                ( ( long ) 234567 )
+#define intgCONST3                ( ( long ) -3 )
+#define intgCONST4                ( ( long ) 7 )
+#define intgEXPECTED_ANSWER        ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 )
+
+#define intgSTACK_SIZE            configMINIMAL_STACK_SIZE
+
+/* As this is the minimal version, we will only create one task. */
+#define intgNUMBER_OF_TASKS        ( 1 )
+
+/* The task function.  Repeatedly performs a 32 bit calculation, checking the
+result against the expected result.  If the result is incorrect then the
+context switch must have caused some corruption. */
+static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters );
+
+/* Variables that are set to true within the calculation task to indicate
+that the task is still executing.  The check task sets the variable back to
+false, flagging an error if the variable is still false the next time it
+is called. */
+static volatile signed portBASE_TYPE xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( signed portBASE_TYPE ) pdFALSE };
+
+/*-----------------------------------------------------------*/
+
+void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
+{
+short sTask;
+
+    for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
+    {
+        xTaskCreate( vCompeteingIntMathTask, ( signed char * ) "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( xTaskHandle * ) NULL );
+    }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters )
+{
+/* These variables are all effectively set to constants so they are volatile to
+ensure the compiler does not just get rid of them. */
+volatile long lValue;
+short sError = pdFALSE;
+volatile signed portBASE_TYPE *pxTaskHasExecuted;
+
+    /* Set a pointer to the variable we are going to set to true each
+    iteration.  This is also a good test of the parameter passing mechanism
+    within each port. */
+    pxTaskHasExecuted = ( volatile signed portBASE_TYPE * ) pvParameters;
+
+    /* Keep performing a calculation and checking the result against a constant. */
+    for( ;; )
+    {
+        /* Perform the calculation.  This will store partial value in
+        registers, resulting in a good test of the context switch mechanism. */
+        lValue = intgCONST1;
+        lValue += intgCONST2;
+
+        /* Yield in case cooperative scheduling is being used. */
+        #if configUSE_PREEMPTION == 0
+        {
+            taskYIELD();
+        }
+        #endif
+
+        /* Finish off the calculation. */
+        lValue *= intgCONST3;
+        lValue /= intgCONST4;
+
+        /* If the calculation is found to be incorrect we stop setting the 
+        TaskHasExecuted variable so the check task can see an error has 
+        occurred. */
+        if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */
+        {
+            sError = pdTRUE;
+        }
+
+        if( sError == pdFALSE )
+        {
+            /* We have not encountered any errors, so set the flag that show
+            we are still executing.  This will be periodically cleared by
+            the check task. */
+            portENTER_CRITICAL();
+                *pxTaskHasExecuted = pdTRUE;
+            portEXIT_CRITICAL();
+        }
+
+        /* Yield in case cooperative scheduling is being used. */
+        #if configUSE_PREEMPTION == 0
+        {
+            taskYIELD();
+        }
+        #endif
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
+{
+portBASE_TYPE xReturn = pdTRUE;
+short sTask;
+
+    /* Check the maths tasks are still running by ensuring their check variables 
+    are still being set to true. */
+    for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
+    {
+        if( xTaskCheck[ sTask ] == pdFALSE )
+        {
+            /* The check has not incremented so an error exists. */
+            xReturn = pdFALSE;
+        }
+
+        /* Reset the check variable so we can tell if it has been set by
+        the next time around. */
+        xTaskCheck[ sTask ] = pdFALSE;
+    }
+
+    return xReturn;
+}
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/recmutex.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/recmutex.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,369 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+    The tasks defined on this page demonstrate the use of recursive mutexes.
+
+    For recursive mutex functionality the created mutex should be created using
+    xSemaphoreCreateRecursiveMutex(), then be manipulated
+    using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API
+    functions.
+
+    This demo creates three tasks all of which access the same recursive mutex:
+
+    prvRecursiveMutexControllingTask() has the highest priority so executes 
+    first and grabs the mutex.  It then performs some recursive accesses - 
+    between each of which it sleeps for a short period to let the lower 
+    priority tasks execute.  When it has completed its demo functionality
+    it gives the mutex back before suspending itself.
+
+    prvRecursiveMutexBlockingTask() attempts to access the mutex by performing
+    a blocking 'take'.  The blocking task has a lower priority than the 
+    controlling    task so by the time it executes the mutex has already been
+    taken by the controlling task,  causing the blocking task to block.  It 
+    does not unblock until the controlling task has given the mutex back, 
+    and it does not actually run until the controlling task has suspended 
+    itself (due to the relative priorities).  When it eventually does obtain
+    the mutex all it does is give the mutex back prior to also suspending 
+    itself.  At this point both the controlling task and the blocking task are 
+    suspended.
+
+    prvRecursiveMutexPollingTask() runs at the idle priority.  It spins round
+    a tight loop attempting to obtain the mutex with a non-blocking call.  As
+    the lowest priority task it will not successfully obtain the mutex until
+    both the controlling and blocking tasks are suspended.  Once it eventually 
+    does obtain the mutex it first unsuspends both the controlling task and
+    blocking task prior to giving the mutex back - resulting in the polling
+    task temporarily inheriting the controlling tasks priority.
+*/
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* Demo app include files. */
+#include "recmutex.h"
+
+/* Priorities assigned to the three tasks. */
+#define recmuCONTROLLING_TASK_PRIORITY    ( tskIDLE_PRIORITY + 2 )
+#define recmuBLOCKING_TASK_PRIORITY        ( tskIDLE_PRIORITY + 1 )
+#define recmuPOLLING_TASK_PRIORITY        ( tskIDLE_PRIORITY + 0 )
+
+/* The recursive call depth. */
+#define recmuMAX_COUNT                    ( 10 )
+
+/* Misc. */
+#define recmuSHORT_DELAY                ( 20 / portTICK_RATE_MS )
+#define recmuNO_DELAY                    ( ( portTickType ) 0 )
+#define recmuTWO_TICK_DELAY                ( ( portTickType ) 2 )
+
+/* The three tasks as described at the top of this file. */
+static void prvRecursiveMutexControllingTask( void *pvParameters );
+static void prvRecursiveMutexBlockingTask( void *pvParameters );
+static void prvRecursiveMutexPollingTask( void *pvParameters );
+
+/* The mutex used by the demo. */
+static xSemaphoreHandle xMutex;
+
+/* Variables used to detect and latch errors. */
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE;
+static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles, uxPollingCycles = 0;
+
+/* Handles of the two higher priority tasks, required so they can be resumed 
+(unsuspended). */
+static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle;
+
+/*-----------------------------------------------------------*/
+
+void vStartRecursiveMutexTasks( void )
+{
+    /* Just creates the mutex and the three tasks. */
+
+    xMutex = xSemaphoreCreateRecursiveMutex();
+
+    /* vQueueAddToRegistry() adds the mutex to the registry, if one is
+    in use.  The registry is provided as a means for kernel aware 
+    debuggers to locate mutex and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Recursive_Mutex" );
+
+
+    if( xMutex != NULL )
+    {
+        xTaskCreate( prvRecursiveMutexControllingTask, ( signed portCHAR * ) "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );
+        xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );
+        xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexControllingTask( void *pvParameters )
+{
+unsigned portBASE_TYPE ux;
+
+    /* Just to remove compiler warning. */
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /* Should not be able to 'give' the mutex, as we have not yet 'taken'
+        it. */
+        if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        for( ux = 0; ux < recmuMAX_COUNT; ux++ )
+        {
+            /* We should now be able to take the mutex as many times as
+            we like.  A one tick delay is used so the polling task will
+            inherit our priority on all but the first cycle of this task. 
+            If we did not block attempting to receive the mutex then no
+            priority inheritance would occur. */
+            if( xSemaphoreTakeRecursive( xMutex, recmuTWO_TICK_DELAY ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+
+            /* Ensure the other task attempting to access the mutex (and the
+            other demo tasks) are able to execute. */
+            vTaskDelay( recmuSHORT_DELAY );
+        }
+
+        /* For each time we took the mutex, give it back. */
+        for( ux = 0; ux < recmuMAX_COUNT; ux++ )
+        {
+            /* Ensure the other task attempting to access the mutex (and the
+            other demo tasks) are able to execute. */
+            vTaskDelay( recmuSHORT_DELAY );
+
+            /* We should now be able to give the mutex as many times as we
+            took it. */
+            if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+        }
+
+        /* Having given it back the same number of times as it was taken, we
+        should no longer be the mutex owner, so the next give sh ould fail. */
+        if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* Keep count of the number of cycles this task has performed so a 
+        stall can be detected. */
+        uxControllingCycles++;
+
+        /* Suspend ourselves to the blocking task can execute. */
+        xControllingIsSuspended = pdTRUE;
+        vTaskSuspend( NULL );
+        xControllingIsSuspended = pdFALSE;
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexBlockingTask( void *pvParameters )
+{
+    /* Just to remove compiler warning. */
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /* Attempt to obtain the mutex.  We should block until the 
+        controlling task has given up the mutex, and not actually execute
+        past this call until the controlling task is suspended. */
+        if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS )
+        {
+            if( xControllingIsSuspended != pdTRUE )
+            {
+                /* Did not expect to execute until the controlling task was
+                suspended. */
+                xErrorOccurred = pdTRUE;
+            }
+            else
+            {
+                /* Give the mutex back before suspending ourselves to allow
+                the polling task to obtain the mutex. */
+                if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
+                {
+                    xErrorOccurred = pdTRUE;
+                }
+
+                xBlockingIsSuspended = pdTRUE;
+                vTaskSuspend( NULL );
+                xBlockingIsSuspended = pdFALSE;
+            }
+        }
+        else
+        {
+            /* We should not leave the xSemaphoreTakeRecursive() function
+            until the mutex was obtained. */
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* The controlling and blocking tasks should be in lock step. */
+        if( uxControllingCycles != ( uxBlockingCycles + 1 ) )
+        {
+            xErrorOccurred = pdTRUE;
+        }
+
+        /* Keep count of the number of cycles this task has performed so a 
+        stall can be detected. */
+        uxBlockingCycles++;
+    }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexPollingTask( void *pvParameters )
+{
+    /* Just to remove compiler warning. */
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /* Keep attempting to obtain the mutex.  We should only obtain it when
+        the blocking task has suspended itself. */
+        if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )
+        {
+            /* Is the blocking task suspended? */
+            if( xBlockingIsSuspended != pdTRUE )
+            {
+                xErrorOccurred = pdTRUE;
+            }
+            else
+            {
+                /* Keep count of the number of cycles this task has performed so 
+                a stall can be detected. */
+                uxPollingCycles++;
+
+                /* We can resume the other tasks here even though they have a
+                higher priority than the polling task.  When they execute they
+                will attempt to obtain the mutex but fail because the polling
+                task is still the mutex holder.  The polling task (this task)
+                will then inherit the higher priority. */                
+                vTaskResume( xBlockingTaskHandle );
+                vTaskResume( xControllingTaskHandle );
+            
+                /* Release the mutex, disinheriting the higher priority again. */
+                if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
+                {
+                    xErrorOccurred = pdTRUE;
+                }
+            }
+        }
+
+        #if configUSE_PREEMPTION == 0
+        {
+            taskYIELD();
+        }
+        #endif
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void )
+{
+portBASE_TYPE xReturn;
+static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0;
+
+    /* Is the controlling task still cycling? */
+    if( uxLastControllingCycles == uxControllingCycles )
+    {
+        xErrorOccurred = pdTRUE;
+    }
+    else
+    {
+        uxLastControllingCycles = uxControllingCycles;
+    }
+
+    /* Is the blocking task still cycling? */
+    if( uxLastBlockingCycles == uxBlockingCycles )
+    {
+        xErrorOccurred = pdTRUE;
+    }
+    else
+    {
+        uxLastBlockingCycles = uxBlockingCycles;
+    }
+
+    /* Is the polling task still cycling? */
+    if( uxLastPollingCycles == uxPollingCycles )
+    {
+        xErrorOccurred = pdTRUE;
+    }
+    else
+    {
+        uxLastPollingCycles = uxPollingCycles;
+    }
+
+    if( xErrorOccurred == pdTRUE )
+    {
+        xReturn = pdFAIL;
+    }
+    else
+    {
+        xReturn = pdTRUE;
+    }
+
+    return xReturn;
+}
+
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/Minimal/semtest.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/Minimal/semtest.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,285 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * Creates two sets of two tasks.  The tasks within a set share a variable, access 
+ * to which is guarded by a semaphore.
+ * 
+ * Each task starts by attempting to obtain the semaphore.  On obtaining a 
+ * semaphore a task checks to ensure that the guarded variable has an expected 
+ * value.  It then clears the variable to zero before counting it back up to the 
+ * expected value in increments of 1.  After each increment the variable is checked 
+ * to ensure it contains the value to which it was just set. When the starting 
+ * value is again reached the task releases the semaphore giving the other task in 
+ * the set a chance to do exactly the same thing.  The starting value is high 
+ * enough to ensure that a tick is likely to occur during the incrementing loop.
+ *
+ * An error is flagged if at any time during the process a shared variable is 
+ * found to have a value other than that expected.  Such an occurrence would 
+ * suggest an error in the mutual exclusion mechanism by which access to the 
+ * variable is restricted.
+ *
+ * The first set of two tasks poll their semaphore.  The second set use blocking 
+ * calls.
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+
+/* Demo app include files. */
+#include "semtest.h"
+
+/* The value to which the shared variables are counted. */
+#define semtstBLOCKING_EXPECTED_VALUE        ( ( unsigned long ) 0xfff )
+#define semtstNON_BLOCKING_EXPECTED_VALUE    ( ( unsigned long ) 0xff  )
+
+#define semtstSTACK_SIZE            configMINIMAL_STACK_SIZE
+
+#define semtstNUM_TASKS                ( 4 )
+
+#define semtstDELAY_FACTOR            ( ( portTickType ) 10 )
+
+/* The task function as described at the top of the file. */
+static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters );
+
+/* Structure used to pass parameters to each task. */
+typedef struct SEMAPHORE_PARAMETERS
+{
+    xSemaphoreHandle xSemaphore;
+    volatile unsigned long *pulSharedVariable;
+    portTickType xBlockTime;
+} xSemaphoreParameters;
+
+/* Variables used to check that all the tasks are still running without errors. */
+static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
+static volatile short sNextCheckVariable = 0;
+
+/*-----------------------------------------------------------*/
+
+void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority )
+{
+xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
+const portTickType xBlockTime = ( portTickType ) 100;
+
+    /* Create the structure used to pass parameters to the first two tasks. */
+    pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
+
+    if( pxFirstSemaphoreParameters != NULL )
+    {
+        /* Create the semaphore used by the first two tasks. */
+        vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore );
+
+        if( pxFirstSemaphoreParameters->xSemaphore != NULL )
+        {
+            /* Create the variable which is to be shared by the first two tasks. */
+            pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
+
+            /* Initialise the share variable to the value the tasks expect. */
+            *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;
+
+            /* The first two tasks do not block on semaphore calls. */
+            pxFirstSemaphoreParameters->xBlockTime = ( portTickType ) 0;
+
+            /* Spawn the first two tasks.  As they poll they operate at the idle priority. */
+            xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
+            xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
+        }
+    }
+
+    /* Do exactly the same to create the second set of tasks, only this time 
+    provide a block time for the semaphore calls. */
+    pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
+    if( pxSecondSemaphoreParameters != NULL )
+    {
+        vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore );
+
+        if( pxSecondSemaphoreParameters->xSemaphore != NULL )
+        {
+            pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
+            *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
+            pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS;
+
+            xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );
+            xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );
+        }
+    }
+
+    /* vQueueAddToRegistry() adds the semaphore to the registry, if one is
+    in use.  The registry is provided as a means for kernel aware 
+    debuggers to locate semaphores and has no purpose if a kernel aware debugger
+    is not being used.  The call to vQueueAddToRegistry() will be removed
+    by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 
+    defined to be less than 1. */
+    vQueueAddToRegistry( ( xQueueHandle ) pxFirstSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_1" );
+    vQueueAddToRegistry( ( xQueueHandle ) pxSecondSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_2" );
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION( prvSemaphoreTest, pvParameters )
+{
+xSemaphoreParameters *pxParameters;
+volatile unsigned long *pulSharedVariable, ulExpectedValue;
+unsigned long ulCounter;
+short sError = pdFALSE, sCheckVariableToUse;
+
+    /* See which check variable to use.  sNextCheckVariable is not semaphore 
+    protected! */
+    portENTER_CRITICAL();
+        sCheckVariableToUse = sNextCheckVariable;
+        sNextCheckVariable++;
+    portEXIT_CRITICAL();
+
+    /* A structure is passed in as the parameter.  This contains the shared 
+    variable being guarded. */
+    pxParameters = ( xSemaphoreParameters * ) pvParameters;
+    pulSharedVariable = pxParameters->pulSharedVariable;
+
+    /* If we are blocking we use a much higher count to ensure loads of context
+    switches occur during the count. */
+    if( pxParameters->xBlockTime > ( portTickType ) 0 )
+    {
+        ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
+    }
+    else
+    {
+        ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
+    }
+
+    for( ;; )
+    {
+        /* Try to obtain the semaphore. */
+        if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
+        {
+            /* We have the semaphore and so expect any other tasks using the
+            shared variable to have left it in the state we expect to find
+            it. */
+            if( *pulSharedVariable != ulExpectedValue )
+            {
+                sError = pdTRUE;
+            }
+            
+            /* Clear the variable, then count it back up to the expected value
+            before releasing the semaphore.  Would expect a context switch or
+            two during this time. */
+            for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
+            {
+                *pulSharedVariable = ulCounter;
+                if( *pulSharedVariable != ulCounter )
+                {
+                    sError = pdTRUE;
+                }
+            }
+
+            /* Release the semaphore, and if no errors have occurred increment the check
+            variable. */
+            if(    xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
+            {
+                sError = pdTRUE;
+            }
+
+            if( sError == pdFALSE )
+            {
+                if( sCheckVariableToUse < semtstNUM_TASKS )
+                {
+                    ( sCheckVariables[ sCheckVariableToUse ] )++;
+                }
+            }
+
+            /* If we have a block time then we are running at a priority higher
+            than the idle priority.  This task takes a long time to complete
+            a cycle    (deliberately so to test the guarding) so will be starving
+            out lower priority tasks.  Block for some time to allow give lower
+            priority tasks some processor time. */
+            vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
+        }
+        else
+        {
+            if( pxParameters->xBlockTime == ( portTickType ) 0 )
+            {
+                /* We have not got the semaphore yet, so no point using the
+                processor.  We are not blocking when attempting to obtain the
+                semaphore. */
+                taskYIELD();
+            }
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreSemaphoreTasksStillRunning( void )
+{
+static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
+portBASE_TYPE xTask, xReturn = pdTRUE;
+
+    for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )
+    {
+        if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )
+        {
+            xReturn = pdFALSE;
+        }
+
+        sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
+    }
+
+    return xReturn;
+}
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/BlockQ.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/BlockQ.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,66 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef BLOCK_Q_H
+#define BLOCK_Q_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xAreBlockingQueuesStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/GenQTest.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/GenQTest.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,67 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef GEN_Q_TEST_H
+#define GEN_Q_TEST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif /* GEN_Q_TEST_H */
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/PollQ.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/PollQ.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,66 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef POLLED_Q_H
+#define POLLED_Q_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xArePollingQueuesStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/QPeek.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/QPeek.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,67 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef Q_PEEK_TEST_H
+#define Q_PEEK_TEST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartQueuePeekTasks( void );
+portBASE_TYPE xAreQueuePeekTasksStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif /* Q_PEEK_TEST_H */
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/blocktim.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/blocktim.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,66 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef BLOCK_TIME_TEST_H
+#define BLOCK_TIME_TEST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vCreateBlockTimeTasks( void );
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/flash.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/flash.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,64 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef FLASH_LED_H
+#define FLASH_LED_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/integer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/integer.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,66 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef INTEGER_TASKS_H
+#define INTEGER_TASKS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xAreIntegerMathsTaskStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/partest.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/partest.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,100 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+/*
+ *  Modified for mbed NXP LPC1768 board
+ *  By Kenji Arai / JH1PJL on April 30th,2010
+ *         August 28th, 2010
+ */
+
+#ifndef PARTEST_H
+#define PARTEST_H
+
+#define partstDEFAULT_PORT_ADDRESS        ( ( unsigned short ) 0x378 )
+
+#if (USE_XPRESSO == 1)
+#define LED_1 ( 1UL << 22UL )
+// Dummy only one LED is available
+#define LED_2 ( 0UL << 0UL )
+#define LED_3 ( 0UL << 0UL )
+#define LED_4 ( 0UL << 0UL )
+#else
+#define LED_1 ( 1UL << 18UL )
+#define LED_2 ( 1UL << 20UL )
+#define LED_3 ( 1UL << 21UL )
+#define LED_4 ( 1UL << 23UL )
+#endif
+
+#define REC_SW ( 1UL )
+
+#define partstFIO1_BITS            ( LED_1 | LED_2 | LED_3 | LED_4 )
+#define partstNUM_LEDS            ( 4 )
+
+/* LED */
+#define LED1 0
+#define LED2 1
+#define LED3 2
+#define LED4 3
+#ifdef __cplusplus
+extern "C" {
+#endif
+static unsigned long ulLEDs[] = { LED_1, LED_2, LED_3, LED_4 };
+void vParTestInitialise( void );
+void vParTestSetLED( unsigned portBASE_TYPE, signed portBASE_TYPE );
+void vParTestToggleLED( unsigned portBASE_TYPE );
+unsigned int vParTestSW_Rec( void );
+unsigned int vParTestSW_Mode( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/recmutex.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/recmutex.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,65 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef RECURSIVE_MUTEX_TEST_H
+#define RECURSIVE_MUTEX_TEST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartRecursiveMutexTasks( void );
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Common/include/semtest.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Common/include/semtest.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,65 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+    
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef SEMAPHORE_TEST_H
+#define SEMAPHORE_TEST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xAreSemaphoreTasksStillRunning( void );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/FreeRTOS.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/FreeRTOS.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,420 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef INC_FREERTOS_H
+#define INC_FREERTOS_H
+
+
+/*
+ * Include the generic headers required for the FreeRTOS port being used.
+ */
+#include <stddef.h>
+
+/* Basic FreeRTOS definitions. */
+#include "projdefs.h"
+
+/* Application specific configuration options. */
+#include "FreeRTOSConfig.h"
+
+/* Definitions specific to the port being used. */
+#include "portable.h"
+
+
+/* Defines the prototype to which the application task hook function must
+conform. */
+typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
+
+
+
+
+
+/*
+ * Check all the required application specific macros have been defined.
+ * These macros are application specific and (as downloaded) are defined
+ * within FreeRTOSConfig.h.
+ */
+
+#ifndef configUSE_PREEMPTION
+    #error Missing definition:  configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_IDLE_HOOK
+    #error Missing definition:  configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_TICK_HOOK
+    #error Missing definition:  configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_CO_ROUTINES
+    #error  Missing definition:  configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskPrioritySet
+    #error Missing definition:  INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_uxTaskPriorityGet
+    #error Missing definition:  INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelete        
+    #error Missing definition:  INCLUDE_vTaskDelete         should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskCleanUpResources
+    #error Missing definition:  INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskSuspend    
+    #error Missing definition:  INCLUDE_vTaskSuspend     should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelayUntil
+    #error Missing definition:  INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelay
+    #error Missing definition:  INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_16_BIT_TICKS
+    #error Missing definition:  configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_APPLICATION_TASK_TAG
+    #define configUSE_APPLICATION_TASK_TAG 0
+#endif
+
+#ifndef INCLUDE_uxTaskGetStackHighWaterMark
+    #define INCLUDE_uxTaskGetStackHighWaterMark 0
+#endif
+
+#ifndef configUSE_RECURSIVE_MUTEXES
+    #define configUSE_RECURSIVE_MUTEXES 0
+#endif
+
+#ifndef configUSE_MUTEXES
+    #define configUSE_MUTEXES 0
+#endif
+
+#ifndef configUSE_COUNTING_SEMAPHORES
+    #define configUSE_COUNTING_SEMAPHORES 0
+#endif
+
+#ifndef configUSE_ALTERNATIVE_API
+    #define configUSE_ALTERNATIVE_API 0
+#endif
+
+#ifndef portCRITICAL_NESTING_IN_TCB
+    #define portCRITICAL_NESTING_IN_TCB 0
+#endif
+
+#ifndef configMAX_TASK_NAME_LEN
+    #define configMAX_TASK_NAME_LEN 16
+#endif
+
+#ifndef configIDLE_SHOULD_YIELD
+    #define configIDLE_SHOULD_YIELD        1
+#endif
+
+#if configMAX_TASK_NAME_LEN < 1
+    #undef configMAX_TASK_NAME_LEN
+    #define configMAX_TASK_NAME_LEN 1
+#endif
+
+#ifndef INCLUDE_xTaskResumeFromISR
+    #define INCLUDE_xTaskResumeFromISR 1
+#endif
+
+#ifndef INCLUDE_xTaskGetSchedulerState
+    #define INCLUDE_xTaskGetSchedulerState 0
+#endif
+
+#if ( configUSE_MUTEXES == 1 )
+    /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
+    within the mutex implementation so must be available if mutexes are used. */
+    #undef INCLUDE_xTaskGetCurrentTaskHandle
+    #define INCLUDE_xTaskGetCurrentTaskHandle 1
+#else
+    #ifndef INCLUDE_xTaskGetCurrentTaskHandle
+        #define INCLUDE_xTaskGetCurrentTaskHandle 0
+    #endif
+#endif
+
+
+#ifndef portSET_INTERRUPT_MASK_FROM_ISR
+    #define portSET_INTERRUPT_MASK_FROM_ISR() 0
+#endif
+
+#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
+    #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
+#endif
+
+
+#ifndef configQUEUE_REGISTRY_SIZE
+    #define configQUEUE_REGISTRY_SIZE 0
+#endif
+
+#if configQUEUE_REGISTRY_SIZE < 1
+    #define configQUEUE_REGISTRY_SIZE 0
+    #define vQueueAddToRegistry( xQueue, pcName )
+    #define vQueueUnregisterQueue( xQueue )
+#endif
+
+
+/* Remove any unused trace macros. */
+#ifndef traceSTART
+    /* Used to perform any necessary initialisation - for example, open a file
+    into which trace is to be written. */
+    #define traceSTART()
+#endif
+
+#ifndef traceEND
+    /* Use to close a trace, for example close a file into which trace has been
+    written. */
+    #define traceEND()
+#endif
+
+#ifndef traceTASK_SWITCHED_IN
+    /* Called after a task has been selected to run.  pxCurrentTCB holds a pointer
+    to the task control block of the selected task. */
+    #define traceTASK_SWITCHED_IN()
+#endif
+
+#ifndef traceTASK_SWITCHED_OUT
+    /* Called before a task has been selected to run.  pxCurrentTCB holds a pointer
+    to the task control block of the task being switched out. */
+    #define traceTASK_SWITCHED_OUT()
+#endif
+
+#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
+    /* Task is about to block because it cannot read from a 
+    queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
+    upon which the read was attempted.  pxCurrentTCB points to the TCB of the 
+    task that attempted the read. */
+    #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
+#endif
+
+#ifndef traceBLOCKING_ON_QUEUE_SEND
+    /* Task is about to block because it cannot write to a 
+    queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
+    upon which the write was attempted.  pxCurrentTCB points to the TCB of the 
+    task that attempted the write. */
+    #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
+#endif
+
+#ifndef configCHECK_FOR_STACK_OVERFLOW
+    #define configCHECK_FOR_STACK_OVERFLOW 0
+#endif
+
+/* The following event macros are embedded in the kernel API calls. */
+
+#ifndef traceQUEUE_CREATE    
+    #define traceQUEUE_CREATE( pxNewQueue )
+#endif
+
+#ifndef traceQUEUE_CREATE_FAILED
+    #define traceQUEUE_CREATE_FAILED()
+#endif
+
+#ifndef traceCREATE_MUTEX
+    #define traceCREATE_MUTEX( pxNewQueue )
+#endif
+
+#ifndef traceCREATE_MUTEX_FAILED
+    #define traceCREATE_MUTEX_FAILED()
+#endif
+
+#ifndef traceGIVE_MUTEX_RECURSIVE
+    #define traceGIVE_MUTEX_RECURSIVE( pxMutex )
+#endif
+
+#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
+    #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
+#endif
+
+#ifndef traceTAKE_MUTEX_RECURSIVE
+    #define traceTAKE_MUTEX_RECURSIVE( pxMutex )
+#endif
+
+#ifndef traceCREATE_COUNTING_SEMAPHORE
+    #define traceCREATE_COUNTING_SEMAPHORE()
+#endif
+
+#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
+    #define traceCREATE_COUNTING_SEMAPHORE_FAILED()
+#endif
+
+#ifndef traceQUEUE_SEND
+    #define traceQUEUE_SEND( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FAILED
+    #define traceQUEUE_SEND_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE
+    #define traceQUEUE_RECEIVE( pxQueue )
+#endif
+
+#ifndef traceQUEUE_PEEK
+    #define traceQUEUE_PEEK( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FAILED
+    #define traceQUEUE_RECEIVE_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FROM_ISR
+    #define traceQUEUE_SEND_FROM_ISR( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
+    #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FROM_ISR
+    #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
+    #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_DELETE
+    #define traceQUEUE_DELETE( pxQueue )
+#endif
+
+#ifndef traceTASK_CREATE
+    #define traceTASK_CREATE( pxNewTCB )
+#endif
+
+#ifndef traceTASK_CREATE_FAILED
+    #define traceTASK_CREATE_FAILED( pxNewTCB )
+#endif
+
+#ifndef traceTASK_DELETE
+    #define traceTASK_DELETE( pxTaskToDelete )
+#endif
+
+#ifndef traceTASK_DELAY_UNTIL
+    #define traceTASK_DELAY_UNTIL()
+#endif
+
+#ifndef traceTASK_DELAY
+    #define traceTASK_DELAY()
+#endif
+
+#ifndef traceTASK_PRIORITY_SET
+    #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
+#endif
+
+#ifndef traceTASK_SUSPEND
+    #define traceTASK_SUSPEND( pxTaskToSuspend )
+#endif
+
+#ifndef traceTASK_RESUME
+    #define traceTASK_RESUME( pxTaskToResume )
+#endif
+
+#ifndef traceTASK_RESUME_FROM_ISR
+    #define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
+#endif
+
+#ifndef traceTASK_INCREMENT_TICK
+    #define traceTASK_INCREMENT_TICK( xTickCount )
+#endif
+
+#ifndef configGENERATE_RUN_TIME_STATS
+    #define configGENERATE_RUN_TIME_STATS 0
+#endif
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+    #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
+        #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined.  portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
+    #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
+
+    #ifndef portGET_RUN_TIME_COUNTER_VALUE
+        #error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined.  portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base.
+    #endif /* portGET_RUN_TIME_COUNTER_VALUE */
+
+#endif /* configGENERATE_RUN_TIME_STATS */
+
+#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
+    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
+#endif
+
+#ifndef configUSE_MALLOC_FAILED_HOOK
+    #define configUSE_MALLOC_FAILED_HOOK 0
+#endif
+
+#ifndef portPRIVILEGE_BIT
+    #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
+#endif
+
+#ifndef portYIELD_WITHIN_API
+    #define portYIELD_WITHIN_API portYIELD
+#endif
+
+#ifndef pvPortMallocAligned
+    #define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) )
+#endif
+
+#ifndef vPortFreeAligned
+    #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
+#endif
+
+#endif /* INC_FREERTOS_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/StackMacros.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/StackMacros.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,172 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef STACK_MACROS_H
+#define STACK_MACROS_H
+
+/*
+ * Call the stack overflow hook function if the stack of the task being swapped
+ * out is currently overflowed, or looks like it might have overflowed in the
+ * past.
+ *
+ * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
+ * the current stack state only - comparing the current top of stack value to
+ * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
+ * will also cause the last few stack bytes to be checked to ensure the value
+ * to which the bytes were set when the task was created have not been 
+ * overwritten.  Note this second test does not guarantee that an overflowed
+ * stack will always be recognised.
+ */
+
+/*-----------------------------------------------------------*/
+
+#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
+
+    /* FreeRTOSConfig.h is not set to check for stack overflows. */
+    #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
+    #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
+
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
+/*-----------------------------------------------------------*/
+
+#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
+
+    /* FreeRTOSConfig.h is only set to use the first method of
+    overflow checking. */
+    #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
+    /* Only the current stack state is to be checked. */
+    // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+    #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()                                                        \
+    {                                                                                                    \
+    extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );            \
+                                                                                                        \
+        /* Is the currently saved stack pointer within the stack limit? */                                \
+        if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )                                        \
+        {                                                                                                \
+            vApplicationStackOverflowHook( ( xTaskHandle *) pxCurrentTCB, pxCurrentTCB->pcTaskName );    \
+        }                                                                                                \
+    }
+#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
+    // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+    /* Only the current stack state is to be checked. */
+    #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()                                                        \
+    {                                                                                                    \
+    extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );        \
+                                                                                                        \
+        /* Is the currently saved stack pointer within the stack limit? */                                \
+        if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack )                                    \
+        {                                                                                                \
+            vApplicationStackOverflowHook( ( xTaskHandle *) pxCurrentTCB, pxCurrentTCB->pcTaskName );    \
+        }                                                                                                \
+    }
+
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
+    // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+    #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()                                                                                                    \
+    {                                                                                                                                                \
+    extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );                                                    \
+    static const unsigned char ucExpectedStackBytes[] = {    tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };    \
+                                                                                                                                                    \
+                                                                                                                                                    \
+        /* Has the extremity of the task stack ever been written over? */                                                                            \
+        if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )                        \
+        {                                                                                                                                            \
+            vApplicationStackOverflowHook( ( xTaskHandle *) pxCurrentTCB, pxCurrentTCB->pcTaskName );                                                \
+        }                                                                                                                                            \
+    }
+
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
+    // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+    #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()                                                                                                    \
+    {                                                                                                                                                \
+    extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );                                                    \
+    char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack;                                                                                \
+    static const unsigned char ucExpectedStackBytes[] = {    tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,        \
+                                                                tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };    \
+                                                                                                                                                    \
+                                                                                                                                                    \
+        pcEndOfStack -= sizeof( ucExpectedStackBytes );                                                                                                \
+                                                                                                                                                    \
+        /* Has the extremity of the task stack ever been written over? */                                                                            \
+        if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )                                \
+        {                                                                                                                                            \
+            vApplicationStackOverflowHook( ( xTaskHandle *) pxCurrentTCB, pxCurrentTCB->pcTaskName );                                                \
+        }                                                                                                                                            \
+    }
+
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
+/*-----------------------------------------------------------*/
+
+#endif /* STACK_MACROS_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/croutine.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/croutine.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,749 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef INC_FREERTOS_H
+    #error "#include FreeRTOS.h" must appear in source files before "#include croutine.h"
+#endif
+
+
+
+
+#ifndef CO_ROUTINE_H
+#define CO_ROUTINE_H
+
+#include "list.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Used to hide the implementation of the co-routine control block.  The
+control block structure however has to be included in the header due to
+the macro implementation of the co-routine functionality. */
+typedef void * xCoRoutineHandle;
+
+/* Defines the prototype to which co-routine functions must conform. */
+typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
+
+typedef struct corCoRoutineControlBlock
+{
+    crCOROUTINE_CODE         pxCoRoutineFunction;
+    xListItem                xGenericListItem;    /*< List item used to place the CRCB in ready and blocked queues. */
+    xListItem                xEventListItem;        /*< List item used to place the CRCB in event lists. */
+    unsigned portBASE_TYPE     uxPriority;            /*< The priority of the co-routine in relation to other co-routines. */
+    unsigned portBASE_TYPE     uxIndex;            /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
+    unsigned short         uxState;            /*< Used internally by the co-routine implementation. */
+} corCRCB; /* Co-routine control block.  Note must be identical in size down to uxPriority with tskTCB. */
+
+/**
+ * croutine. h
+ *<pre>
+ portBASE_TYPE xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 unsigned portBASE_TYPE uxPriority,
+                                 unsigned portBASE_TYPE uxIndex
+                               );</pre>
+ *
+ * Create a new co-routine and add it to the list of co-routines that are
+ * ready to run.
+ *
+ * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine
+ * functions require special syntax - see the co-routine section of the WEB
+ * documentation for more information.
+ *
+ * @param uxPriority The priority with respect to other co-routines at which
+ *  the co-routine will run.
+ *
+ * @param uxIndex Used to distinguish between different co-routines that
+ * execute the same function.  See the example below and the co-routine section
+ * of the WEB documentation for further information.
+ *
+ * @return pdPASS if the co-routine was successfully created and added to a ready
+ * list, otherwise an error code defined with ProjDefs.h.
+ *
+ * Example usage:
+   <pre>
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how long to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+        
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   </pre>
+ * \defgroup xCoRoutineCreate xCoRoutineCreate
+ * \ingroup Tasks
+ */
+signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
+
+
+/**
+ * croutine. h
+ *<pre>
+ void vCoRoutineSchedule( void );</pre>
+ *
+ * Run a co-routine.
+ *
+ * vCoRoutineSchedule() executes the highest priority co-routine that is able
+ * to run.  The co-routine will execute until it either blocks, yields or is
+ * preempted by a task.  Co-routines execute cooperatively so one
+ * co-routine cannot be preempted by another, but can be preempted by a task.
+ *
+ * If an application comprises of both tasks and co-routines then
+ * vCoRoutineSchedule should be called from the idle task (in an idle task
+ * hook).
+ *
+ * Example usage:
+   <pre>
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+    vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ </pre>
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule
+ * \ingroup Tasks
+ */
+void vCoRoutineSchedule( void );
+
+/**
+ * croutine. h
+ * <pre>
+ crSTART( xCoRoutineHandle xHandle );</pre>
+ *
+ * This macro MUST always be called at the start of a co-routine function.
+ *
+ * Example usage:
+   <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
+
+/**
+ * croutine. h
+ * <pre>
+ crEND();</pre>
+ *
+ * This macro MUST always be called at the end of a co-routine function.
+ *
+ * Example usage:
+   <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crEND() }
+
+/*
+ * These macros are intended for internal use by the co-routine implementation
+ * only.  The macros should not be used directly by application writers.
+ */
+#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
+#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
+
+/**
+ * croutine. h
+ *<pre>
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
+ *
+ * Delay a co-routine for a fixed period of time.
+ *
+ * crDELAY can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function.  This is because
+ * co-routines do not maintain their own stack.
+ *
+ * @param xHandle The handle of the co-routine to delay.  This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should delay
+ * for.  The actual amount of time this equates to is defined by
+ * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_RATE_MS
+ * can be used to convert ticks to milliseconds.
+ *
+ * Example usage:
+   <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }</pre>
+ * \defgroup crDELAY crDELAY
+ * \ingroup Tasks
+ */
+#define crDELAY( xHandle, xTicksToDelay )                                                \
+    if( xTicksToDelay > 0 )                                                                \
+    {                                                                                    \
+        vCoRoutineAddToDelayedList( xTicksToDelay, NULL );                                \
+    }                                                                                    \
+    crSET_STATE0( xHandle );
+
+/**
+ * <pre>
+ crQUEUE_SEND(
+                  xCoRoutineHandle xHandle,
+                  xQueueHandle pxQueue,
+                  void *pvItemToQueue,
+                  portTickType xTicksToWait,
+                  portBASE_TYPE *pxResult
+             )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_SEND can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function.  This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine.  This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue on which the data will be posted.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvItemToQueue A pointer to the data being posted onto the queue.
+ * The number of bytes of each queued item is specified when the queue is
+ * created.  This number of bytes is copied from pvItemToQueue into the queue
+ * itself.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for space to become available on the queue, should space not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
+ * below).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully posted onto the queue, otherwise it will be set to an
+ * error defined within ProjDefs.h.
+ *
+ * Example usage:
+   <pre>
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }</pre>
+ * \defgroup crQUEUE_SEND crQUEUE_SEND
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )            \
+{                                                                                        \
+    *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait );                    \
+    if( *pxResult == errQUEUE_BLOCKED )                                                    \
+    {                                                                                    \
+        crSET_STATE0( xHandle );                                                        \
+        *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 );                            \
+    }                                                                                    \
+    if( *pxResult == errQUEUE_YIELD )                                                    \
+    {                                                                                    \
+        crSET_STATE1( xHandle );                                                        \
+        *pxResult = pdPASS;                                                                \
+    }                                                                                    \
+}
+
+/**
+ * croutine. h
+ * <pre>
+  crQUEUE_RECEIVE(
+                     xCoRoutineHandle xHandle,
+                     xQueueHandle pxQueue,
+                     void *pvBuffer,
+                     portTickType xTicksToWait,
+                     portBASE_TYPE *pxResult
+                 )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function.  This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine.  This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue from which the data will be received.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvBuffer The buffer into which the received item is to be copied.
+ * The number of bytes of each queued item is specified when the queue is
+ * created.  This number of bytes is copied into pvBuffer.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for data to become available from the queue, should data not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
+ * crQUEUE_SEND example).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully retrieved from the queue, otherwise it will be set to
+ * an error code as defined within ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )            \
+{                                                                                        \
+    *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait );                        \
+    if( *pxResult == errQUEUE_BLOCKED )                                                 \
+    {                                                                                    \
+        crSET_STATE0( xHandle );                                                        \
+        *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 );                            \
+    }                                                                                    \
+    if( *pxResult == errQUEUE_YIELD )                                                    \
+    {                                                                                    \
+        crSET_STATE1( xHandle );                                                        \
+        *pxResult = pdPASS;                                                                \
+    }                                                                                    \
+}
+
+/**
+ * croutine. h
+ * <pre>
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvItemToQueue,
+                            portBASE_TYPE xCoRoutinePreviouslyWoken
+                       )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
+ * that is being used from within a co-routine.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
+ * the same queue multiple times from a single interrupt.  The first call
+ * should always pass in pdFALSE.  Subsequent calls should pass in
+ * the value returned from the previous call.
+ *
+ * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is
+ * used by the ISR to determine if a context switch may be required following
+ * the ISR.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ char cRxedChar;
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }</pre>
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
+
+
+/**
+ * croutine. h
+ * <pre>
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvBuffer,
+                            portBASE_TYPE * pxCoRoutineWoken
+                       )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
+ * from a queue that is being used from within a co-routine (a co-routine
+ * posted to the queue).
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvBuffer A pointer to a buffer into which the received item will be
+ * placed.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from the queue into
+ * pvBuffer.
+ *
+ * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
+ * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a
+ * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
+ * *pxCoRoutineWoken will remain unchanged.
+ *
+ * @return pdTRUE an item was successfully received from the queue, otherwise
+ * pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+         else
+         {
+            // Could not post the character to the queue.
+         }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+         // hypothetical UART.  The interrupt will obtain the character
+         // from the queue and send it.
+         ENABLE_RX_INTERRUPT();
+
+         // Increment to the next character then block for a fixed period.
+         // cCharToTx will maintain its value across the delay as it is
+         // declared static.
+         cCharToTx++;
+         if( cCharToTx > 'x' )
+         {
+            cCharToTx = 'a';
+         }
+         crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+         // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+         // is woken by the post - ensuring that only a single co-routine is
+         // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+         {
+             SEND_CHARACTER( cCharToTx );
+         }
+     }
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
+
+/*
+ * This function is intended for internal use by the co-routine macros only.
+ * The macro nature of the co-routine implementation requires that the
+ * prototype appears here.  The function should not be used by application
+ * writers.
+ *
+ * Removes the current co-routine from its ready list and places it in the
+ * appropriate delayed list.
+ */
+void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
+
+/*
+ * This function is intended for internal use by the queue implementation only.
+ * The function should not be used by application writers.
+ *
+ * Removes the highest priority co-routine from the event list and places it in
+ * the pending ready list.
+ */
+signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CO_ROUTINE_H */
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/list.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/list.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,305 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ * This is the list implementation used by the scheduler.  While it is tailored
+ * heavily for the schedulers needs, it is also available for use by
+ * application code.
+ *
+ * xLists can only store pointers to xListItems.  Each xListItem contains a
+ * numeric value (xItemValue).  Most of the time the lists are sorted in
+ * descending item value order.
+ *
+ * Lists are created already containing one list item.  The value of this
+ * item is the maximum possible that can be stored, it is therefore always at
+ * the end of the list and acts as a marker.  The list member pxHead always
+ * points to this marker - even though it is at the tail of the list.  This
+ * is because the tail contains a wrap back pointer to the true head of
+ * the list.
+ *
+ * In addition to it's value, each list item contains a pointer to the next
+ * item in the list (pxNext), a pointer to the list it is in (pxContainer)
+ * and a pointer to back to the object that contains it.  These later two
+ * pointers are included for efficiency of list manipulation.  There is
+ * effectively a two way link between the object containing the list item and
+ * the list item itself.
+ *
+ *
+ * \page ListIntroduction List Implementation
+ * \ingroup FreeRTOSIntro
+ */
+
+/*
+    Changes from V4.3.1
+
+    + Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist
+      compiler with optimisation.  Thanks B.R.
+*/
+
+#ifndef LIST_H
+#define LIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Definition of the only type of object that a list can contain.
+ */
+struct xLIST_ITEM
+{
+    portTickType xItemValue;                /*< The value being listed.  In most cases this is used to sort the list in descending order. */
+    volatile struct xLIST_ITEM * pxNext;    /*< Pointer to the next xListItem in the list. */
+    volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
+    void * pvOwner;                            /*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
+    void * pvContainer;                        /*< Pointer to the list in which this list item is placed (if any). */
+};
+typedef struct xLIST_ITEM xListItem;        /* For some reason lint wants this as two separate definitions. */
+
+struct xMINI_LIST_ITEM
+{
+    portTickType xItemValue;
+    volatile struct xLIST_ITEM *pxNext;
+    volatile struct xLIST_ITEM *pxPrevious;
+};
+typedef struct xMINI_LIST_ITEM xMiniListItem;
+
+/*
+ * Definition of the type of queue used by the scheduler.
+ */
+typedef struct xLIST
+{
+    volatile unsigned portBASE_TYPE uxNumberOfItems;
+    volatile xListItem * pxIndex;            /*< Used to walk through the list.  Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
+    volatile xMiniListItem xListEnd;        /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
+} xList;
+
+/*
+ * Access macro to set the owner of a list item.  The owner of a list item
+ * is the object (usually a TCB) that contains the list item.
+ *
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )        ( pxListItem )->pvOwner = ( void * ) pxOwner
+
+/*
+ * Access macro to set the value of the list item.  In most cases the value is
+ * used to sort the list in descending order.
+ *
+ * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )        ( pxListItem )->xItemValue = xValue
+
+/*
+ * Access macro the retrieve the value of the list item.  The value can
+ * represent anything - for example a the priority of a task, or the time at
+ * which a task should be unblocked.
+ *
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listGET_LIST_ITEM_VALUE( pxListItem )                ( ( pxListItem )->xItemValue )
+
+/*
+ * Access macro to determine if a list contains any items.  The macro will
+ * only have the value true if the list is empty.
+ *
+ * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
+ * \ingroup LinkedList
+ */
+#define listLIST_IS_EMPTY( pxList )                ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
+
+/*
+ * Access macro to return the number of items in the list.
+ */
+#define listCURRENT_LIST_LENGTH( pxList )        ( ( pxList )->uxNumberOfItems )
+
+/*
+ * Access function to obtain the owner of the next entry in a list.
+ *
+ * The list member pxIndex is used to walk through a list.  Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
+ * and returns that entries pxOwner parameter.  Using multiple calls to this
+ * function it is therefore possible to move through every item contained in
+ * a list.
+ *
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item.  In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the next item owner is to be returned.
+ *
+ * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
+ * \ingroup LinkedList
+ */
+// Modified by  Kenji Arai / JH1PJL, October 31st,2010
+#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                    \
+{                                                                                        \
+xList * const pxConstList = pxList;                                                        \
+    /* Increment the index to the next item and return the item, ensuring */            \
+    /* we don't return the marker used at the end of the list.  */                        \
+    ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                        \
+    if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) )    \
+    {                                                                                    \
+        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                    \
+    }                                                                                    \
+    pxTCB = (tskTCB *)(( pxConstList )->pxIndex->pvOwner);                                \
+}
+
+/*
+ * Access function to obtain the owner of the first entry in a list.  Lists
+ * are normally sorted in ascending item value order.
+ *
+ * This function returns the pxOwner member of the first item in the list.
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item.  In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the owner of the head item is to be
+ * returned.
+ *
+ * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
+
+/*
+ * Check to see if a list item is within a list.  The list item maintains a
+ * "container" pointer that points to the list it is in.  All this macro does
+ * is check to see if the container and the list match.
+ *
+ * @param pxList The list we want to know if the list item is within.
+ * @param pxListItem The list item we want to know if is in the list.
+ * @return pdTRUE is the list item is in the list, otherwise pdFALSE.
+ * pointer against
+ */
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
+
+/*
+ * Must be called before a list is used!  This initialises all the members
+ * of the list structure and inserts the xListEnd item into the list as a
+ * marker to the back of the list.
+ *
+ * @param pxList Pointer to the list being initialised.
+ *
+ * \page vListInitialise vListInitialise
+ * \ingroup LinkedList
+ */
+void vListInitialise( xList *pxList );
+
+/*
+ * Must be called before a list item is used.  This sets the list container to
+ * null so the item does not think that it is already contained in a list.
+ *
+ * @param pxItem Pointer to the list item being initialised.
+ *
+ * \page vListInitialiseItem vListInitialiseItem
+ * \ingroup LinkedList
+ */
+void vListInitialiseItem( xListItem *pxItem );
+
+/*
+ * Insert a list item into a list.  The item will be inserted into the list in
+ * a position determined by its item value (descending item value order).
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The item to that is to be placed in the list.
+ *
+ * \page vListInsert vListInsert
+ * \ingroup LinkedList
+ */
+void vListInsert( xList *pxList, xListItem *pxNewListItem );
+
+/*
+ * Insert a list item into a list.  The item will be inserted in a position
+ * such that it will be the last item within the list returned by multiple
+ * calls to listGET_OWNER_OF_NEXT_ENTRY.
+ *
+ * The list member pvIndex is used to walk through a list.  Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
+ * Placing an item in a list using vListInsertEnd effectively places the item
+ * in the list position pointed to by pvIndex.  This means that every other
+ * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
+ * the pvIndex parameter again points to the item being inserted.
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The list item to be inserted into the list.
+ *
+ * \page vListInsertEnd vListInsertEnd
+ * \ingroup LinkedList
+ */
+void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
+
+/*
+ * Remove an item from a list.  The list item has a pointer to the list that
+ * it is in, so only the list item need be passed into the function.
+ *
+ * @param vListRemove The item to be removed.  The item will remove itself from
+ * the list pointed to by it's pxContainer parameter.
+ *
+ * \page vListRemove vListRemove
+ * \ingroup LinkedList
+ */
+void vListRemove( xListItem *pxItemToRemove );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/mpu_wrappers.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/mpu_wrappers.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,143 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef MPU_WRAPPERS_H
+#define MPU_WRAPPERS_H
+
+// Modified by  Kenji Arai / JH1PJL, November 3rd,2010
+#if 0
+/* This file redefines API functions to be called through a wrapper macro, but
+only for ports that are using the MPU. */
+#ifdef portUSING_MPU_WRAPPERS
+
+    /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
+    included from queue.c or task.c to prevent it from having an effect within
+    those files. */
+    #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+        #define xTaskGenericCreate                MPU_xTaskGenericCreate
+        #define vTaskAllocateMPURegions            MPU_vTaskAllocateMPURegions
+        #define vTaskDelete                        MPU_vTaskDelete
+        #define vTaskDelayUntil                    MPU_vTaskDelayUntil
+        #define vTaskDelay                        MPU_vTaskDelay
+        #define uxTaskPriorityGet                MPU_uxTaskPriorityGet
+        #define vTaskPrioritySet                MPU_vTaskPrioritySet
+        #define vTaskSuspend                    MPU_vTaskSuspend
+        #define xTaskIsTaskSuspended            MPU_xTaskIsTaskSuspended
+        #define vTaskResume                        MPU_vTaskResume
+        #define vTaskSuspendAll                    MPU_vTaskSuspendAll
+        #define xTaskResumeAll                    MPU_xTaskResumeAll
+        #define xTaskGetTickCount                MPU_xTaskGetTickCount
+        #define uxTaskGetNumberOfTasks            MPU_uxTaskGetNumberOfTasks
+        #define vTaskList                        MPU_vTaskList
+        #define vTaskGetRunTimeStats            MPU_vTaskGetRunTimeStats
+        #define vTaskStartTrace                    MPU_vTaskStartTrace
+        #define ulTaskEndTrace                    MPU_ulTaskEndTrace
+        #define vTaskSetApplicationTaskTag        MPU_vTaskSetApplicationTaskTag
+        #define xTaskGetApplicationTaskTag        MPU_xTaskGetApplicationTaskTag
+        #define xTaskCallApplicationTaskHook    MPU_xTaskCallApplicationTaskHook
+        #define uxTaskGetStackHighWaterMark        MPU_uxTaskGetStackHighWaterMark
+        #define xTaskGetCurrentTaskHandle        MPU_xTaskGetCurrentTaskHandle
+        #define xTaskGetSchedulerState            MPU_xTaskGetSchedulerState
+
+        #define xQueueCreate                    MPU_xQueueCreate
+        #define xQueueCreateMutex                MPU_xQueueCreateMutex
+        #define xQueueGiveMutexRecursive        MPU_xQueueGiveMutexRecursive
+        #define xQueueTakeMutexRecursive        MPU_xQueueTakeMutexRecursive
+        #define xQueueCreateCountingSemaphore    MPU_xQueueCreateCountingSemaphore
+        #define xQueueGenericSend                MPU_xQueueGenericSend
+        #define xQueueAltGenericSend            MPU_xQueueAltGenericSend
+        #define xQueueAltGenericReceive            MPU_xQueueAltGenericReceive
+        #define xQueueGenericReceive            MPU_xQueueGenericReceive
+        #define uxQueueMessagesWaiting            MPU_uxQueueMessagesWaiting
+        #define vQueueDelete                    MPU_vQueueDelete
+
+        #define pvPortMalloc                    MPU_pvPortMalloc
+        #define vPortFree                        MPU_vPortFree
+        #define xPortGetFreeHeapSize            MPU_xPortGetFreeHeapSize
+        #define vPortInitialiseBlocks            MPU_vPortInitialiseBlocks
+
+        #if configQUEUE_REGISTRY_SIZE > 0
+            #define vQueueAddToRegistry                MPU_vQueueAddToRegistry
+            #define vQueueUnregisterQueue            MPU_vQueueUnregisterQueue
+        #endif
+
+        /* Remove the privileged function macro. */
+        #define PRIVILEGED_FUNCTION
+
+    #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
+
+        /* Ensure API functions go in the privileged execution section. */
+        #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
+        #define PRIVILEGED_DATA __attribute__((section("privileged_data")))
+        //#define PRIVILEGED_DATA
+
+    #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
+
+#else /* portUSING_MPU_WRAPPERS */
+
+    #define PRIVILEGED_FUNCTION
+    #define PRIVILEGED_DATA
+    #define portUSING_MPU_WRAPPERS 0
+
+#endif /* portUSING_MPU_WRAPPERS */
+#endif
+
+// Modified by  Kenji Arai / JH1PJL, November 3rd,2010
+    #define PRIVILEGED_FUNCTION
+    #define PRIVILEGED_DATA
+    #define portUSING_MPU_WRAPPERS 0
+
+
+#endif /* MPU_WRAPPERS_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/portable.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/portable.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,396 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*-----------------------------------------------------------
+ * Portable layer API.  Each function must be defined for each port.
+ *----------------------------------------------------------*/
+
+#ifndef PORTABLE_H
+#define PORTABLE_H
+
+// Modified by  Kenji Arai / JH1PJL, November 3rd,2010
+#if 0
+/* Include the macro file relevant to the port being used. */
+
+#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
+    #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
+    typedef void ( __interrupt __far *pxISR )();
+#endif
+
+#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
+    #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
+    typedef void ( __interrupt __far *pxISR )();
+#endif
+
+#ifdef GCC_MEGA_AVR
+    #include "../portable/GCC/ATMega323/portmacro.h"
+#endif
+
+#ifdef IAR_MEGA_AVR
+    #include "../portable/IAR/ATMega323/portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC24_PORT
+    #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_DSPIC_PORT
+    #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC18F_PORT
+    #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC32MX_PORT
+    #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
+#endif
+
+#ifdef _FEDPICC
+    #include "libFreeRTOS/Include/portmacro.h"
+#endif
+
+#ifdef SDCC_CYGNAL
+    #include "../../Source/portable/SDCC/Cygnal/portmacro.h"
+#endif
+
+#ifdef GCC_ARM7
+    #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
+#endif
+
+#ifdef GCC_ARM7_ECLIPSE
+    #include "portmacro.h"
+#endif
+
+#ifdef ROWLEY_LPC23xx
+    #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
+#endif
+
+#ifdef IAR_MSP430
+    #include "..\..\Source\portable\IAR\MSP430\portmacro.h"    
+#endif
+    
+#ifdef GCC_MSP430
+    #include "../../Source/portable/GCC/MSP430F449/portmacro.h"
+#endif
+
+#ifdef ROWLEY_MSP430
+    #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
+#endif
+
+#ifdef ARM7_LPC21xx_KEIL_RVDS
+    #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
+#endif
+
+#ifdef SAM7_GCC
+    #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
+#endif
+
+#ifdef SAM7_IAR
+    #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
+#endif
+
+#ifdef SAM9XE_IAR
+    #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
+#endif
+
+#ifdef LPC2000_IAR
+    #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
+#endif
+
+#ifdef STR71X_IAR
+    #include "..\..\Source\portable\IAR\STR71x\portmacro.h"
+#endif
+
+#ifdef STR75X_IAR
+    #include "..\..\Source\portable\IAR\STR75x\portmacro.h"
+#endif
+    
+#ifdef STR75X_GCC
+    #include "..\..\Source\portable\GCC\STR75x\portmacro.h"
+#endif
+
+#ifdef STR91X_IAR
+    #include "..\..\Source\portable\IAR\STR91x\portmacro.h"
+#endif
+    
+#ifdef GCC_H8S
+    #include "../../Source/portable/GCC/H8S2329/portmacro.h"
+#endif
+
+#ifdef GCC_AT91FR40008
+    #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
+#endif
+
+#ifdef RVDS_ARMCM3_LM3S102
+    #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef GCC_ARMCM3_LM3S102
+    #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef GCC_ARMCM3
+    #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef IAR_ARM_CM3
+    #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef IAR_ARMCM3_LM
+    #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
+#endif
+    
+#ifdef HCS12_CODE_WARRIOR
+    #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
+#endif    
+
+#ifdef MICROBLAZE_GCC
+    #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
+#endif
+
+#ifdef TERN_EE
+    #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
+#endif
+
+#ifdef GCC_HCS12
+    #include "../../Source/portable/GCC/HCS12/portmacro.h"
+#endif
+
+#ifdef GCC_MCF5235
+    #include "../../Source/portable/GCC/MCF5235/portmacro.h"
+#endif
+
+#ifdef COLDFIRE_V2_GCC
+    #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
+#endif
+
+#ifdef COLDFIRE_V2_CODEWARRIOR
+    #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
+#endif
+
+#ifdef GCC_PPC405
+    #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
+#endif
+
+#ifdef GCC_PPC440
+    #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
+#endif
+
+#ifdef _16FX_SOFTUNE
+    #include "..\..\Source\portable\Softune\MB96340\portmacro.h"
+#endif
+
+#ifdef BCC_INDUSTRIAL_PC_PORT
+    /* A short file name has to be used in place of the normal
+    FreeRTOSConfig.h when using the Borland compiler. */
+    #include "frconfig.h"
+    #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
+    typedef void ( __interrupt __far *pxISR )();
+#endif
+
+#ifdef BCC_FLASH_LITE_186_PORT
+    /* A short file name has to be used in place of the normal
+    FreeRTOSConfig.h when using the Borland compiler. */
+    #include "frconfig.h"
+    #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
+    typedef void ( __interrupt __far *pxISR )();
+#endif
+
+#ifdef __GNUC__
+   #ifdef __AVR32_AVR32A__
+       #include "portmacro.h"
+   #endif
+#endif
+
+#ifdef __ICCAVR32__
+   #ifdef __CORE__
+      #if __CORE__ == __AVR32A__
+          #include "portmacro.h"
+      #endif
+   #endif
+#endif
+
+#ifdef __91467D
+    #include "portmacro.h"
+#endif
+
+#ifdef __96340
+    #include "portmacro.h"
+#endif
+
+
+#ifdef __IAR_V850ES_Fx3__
+    #include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx3__
+    #include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx3_L__
+    #include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx2__
+    #include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Hx2__
+    #include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_78K0R_Kx3__
+    #include "../../Source/portable/IAR/78K0R/portmacro.h"
+#endif
+    
+#ifdef __IAR_78K0R_Kx3L__
+    #include "../../Source/portable/IAR/78K0R/portmacro.h"
+#endif
+#endif
+
+/* Catch all to ensure portmacro.h is included in the build.  Newer demos
+have the path as part of the project options, rather than as relative from
+the project location.  If portENTER_CRITICAL() has not been defined then
+portmacro.h has not yet been included - as every portmacro.h provides a
+portENTER_CRITICAL() definition.  Check the demo application for your demo
+to find the path to the correct portmacro.h file. */
+#ifndef portENTER_CRITICAL
+    #include "../portable/GCC/ARM_CM3/portmacro.h"
+#endif
+    
+#if portBYTE_ALIGNMENT == 8
+    #define portBYTE_ALIGNMENT_MASK ( 0x0007 )
+#endif
+
+// Modified by  Kenji Arai / JH1PJL, November 3rd,2010
+#if 0
+#if portBYTE_ALIGNMENT == 4
+    #define portBYTE_ALIGNMENT_MASK    ( 0x0003 )
+#endif
+
+#if portBYTE_ALIGNMENT == 2
+    #define portBYTE_ALIGNMENT_MASK    ( 0x0001 )
+#endif
+
+#if portBYTE_ALIGNMENT == 1
+    #define portBYTE_ALIGNMENT_MASK    ( 0x0000 )
+#endif
+
+#ifndef portBYTE_ALIGNMENT_MASK
+    #error "Invalid portBYTE_ALIGNMENT definition"
+#endif
+#endif
+
+#ifndef portNUM_CONFIGURABLE_REGIONS
+    #define portNUM_CONFIGURABLE_REGIONS 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mpu_wrappers.h"
+
+/*
+ * Setup the stack of a new task so it is ready to be placed under the
+ * scheduler control.  The registers have to be placed on the stack in
+ * the order that the port expects to find them.
+ *
+ */
+#if( portUSING_MPU_WRAPPERS == 1 )
+    portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
+#else
+    portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
+#endif
+
+/*
+ * Map to the memory management routines required for the port.
+ */
+void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
+void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
+void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
+size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Setup the hardware ready for the scheduler to take control.  This generally
+ * sets up a tick interrupt and sets timers for the correct tick frequency.
+ */
+portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
+ * the hardware is left in its original condition after the scheduler stops
+ * executing.
+ */
+void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * The structures and methods of manipulating the MPU are contained within the
+ * port layer.
+ *
+ * Fills the xMPUSettings structure with the memory region information
+ * contained in xRegions.
+ */
+#if( portUSING_MPU_WRAPPERS == 1 ) 
+    struct xMEMORY_REGION;
+    void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTABLE_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/projdefs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/projdefs.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,77 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef PROJDEFS_H
+#define PROJDEFS_H
+
+/* Defines the prototype to which task functions must conform. */
+typedef void (*pdTASK_CODE)( void * );
+
+#define pdTRUE        ( 1 )
+#define pdFALSE        ( 0 )
+
+#define pdPASS                                    ( 1 )
+#define pdFAIL                                    ( 0 )
+#define errQUEUE_EMPTY                            ( 0 )
+#define errQUEUE_FULL                            ( 0 )
+
+/* Error definitions. */
+#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY    ( -1 )
+#define errNO_TASK_TO_RUN                        ( -2 )
+#define errQUEUE_BLOCKED                        ( -4 )
+#define errQUEUE_YIELD                            ( -5 )
+
+#endif /* PROJDEFS_H */
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/queue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/queue.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,1259 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef INC_FREERTOS_H
+    #error "#include FreeRTOS.h" must appear in source files before "#include queue.h"
+#endif
+
+
+
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mpu_wrappers.h"
+
+typedef void * xQueueHandle;
+
+
+/* For internal use only. */
+#define    queueSEND_TO_BACK    ( 0 )
+#define    queueSEND_TO_FRONT    ( 1 )
+
+
+/**
+ * queue. h
+ * <pre>
+ xQueueHandle xQueueCreate(
+                              unsigned portBASE_TYPE uxQueueLength,
+                              unsigned portBASE_TYPE uxItemSize
+                          );
+ * </pre>
+ *
+ * Creates a new queue instance.  This allocates the storage required by the
+ * new queue and returns a handle for the queue.
+ *
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ *
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * Items are queued by copy, not by reference, so this is the number of bytes
+ * that will be copied for each posted item.  Each item on the queue must be
+ * the same size.
+ *
+ * @return If the queue is successfully create then a handle to the newly
+ * created queue is returned.  If the queue cannot be created then 0 is
+ * returned.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+    // Create a queue capable of containing 10 unsigned long values.
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+    if( xQueue1 == 0 )
+    {
+        // Queue was not created and must not be used.
+    }
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+    if( xQueue2 == 0 )
+    {
+        // Queue was not created and must not be used.
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueCreate xQueueCreate
+ * \ingroup QueueManagement
+ */
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToToFront(
+                                   xQueueHandle    xQueue,
+                                   const    void    *    pvItemToQueue,
+                                   portTickType    xTicksToWait
+                               );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the front of a queue.  The item is queued by copy, not by
+ * reference.  This function must not be called from an interrupt service
+ * routine.  See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full.  The call will return immediately if this is set to 0 and the
+ * queue is full.  The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 unsigned long values.
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+    // ...
+
+    if( xQueue1 != 0 )
+    {
+        // Send an unsigned long.  Wait for 10 ticks for space to become
+        // available if necessary.
+        if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+        {
+            // Failed to post the message, even after 10 ticks.
+        }
+    }
+
+    if( xQueue2 != 0 )
+    {
+        // Send a pointer to a struct AMessage object.  Don't block if the
+        // queue is already full.
+        pxMessage = & xMessage;
+        xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToBack(
+                                   xQueueHandle    xQueue,
+                                   const    void    *    pvItemToQueue,
+                                   portTickType    xTicksToWait
+                               );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the back of a queue.  The item is queued by copy, not by
+ * reference.  This function must not be called from an interrupt service
+ * routine.  See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full.  The call will return immediately if this is set to 0 and the queue
+ * is full.  The  time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 unsigned long values.
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+    // ...
+
+    if( xQueue1 != 0 )
+    {
+        // Send an unsigned long.  Wait for 10 ticks for space to become
+        // available if necessary.
+        if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+        {
+            // Failed to post the message, even after 10 ticks.
+        }
+    }
+
+    if( xQueue2 != 0 )
+    {
+        // Send a pointer to a struct AMessage object.  Don't block if the
+        // queue is already full.
+        pxMessage = & xMessage;
+        xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSend(
+                              xQueueHandle xQueue,
+                              const void * pvItemToQueue,
+                              portTickType xTicksToWait
+                         );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend().  It is included for
+ * backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToFront() and xQueueSendToBack() macros.  It is
+ * equivalent to xQueueSendToBack().
+ *
+ * Post an item on a queue.  The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full.  The call will return immediately if this is set to 0 and the
+ * queue is full.  The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 unsigned long values.
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+    // ...
+
+    if( xQueue1 != 0 )
+    {
+        // Send an unsigned long.  Wait for 10 ticks for space to become
+        // available if necessary.
+        if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+        {
+            // Failed to post the message, even after 10 ticks.
+        }
+    }
+
+    if( xQueue2 != 0 )
+    {
+        // Send a pointer to a struct AMessage object.  Don't block if the
+        // queue is already full.
+        pxMessage = & xMessage;
+        xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericSend(
+                                    xQueueHandle xQueue,
+                                    const void * pvItemToQueue,
+                                    portTickType xTicksToWait
+                                    portBASE_TYPE xCopyPosition
+                                );
+ * </pre>
+ *
+ * It is preferred that the macros xQueueSend(), xQueueSendToFront() and
+ * xQueueSendToBack() are used in place of calling this function directly.
+ *
+ * Post an item on a queue.  The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full.  The call will return immediately if this is set to 0 and the
+ * queue is full.  The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 unsigned long values.
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+    // ...
+
+    if( xQueue1 != 0 )
+    {
+        // Send an unsigned long.  Wait for 10 ticks for space to become
+        // available if necessary.
+        if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
+        {
+            // Failed to post the message, even after 10 ticks.
+        }
+    }
+
+    if( xQueue2 != 0 )
+    {
+        // Send a pointer to a struct AMessage object.  Don't block if the
+        // queue is already full.
+        pxMessage = & xMessage;
+        xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueuePeek(
+                             xQueueHandle xQueue,
+                             void *pvBuffer,
+                             portTickType xTicksToWait
+                         );</pre>
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue without removing the item from the queue.
+ * The item is received by copy so a buffer of adequate size must be
+ * provided.  The number of bytes copied into the buffer was defined when
+ * the queue was created.
+ *
+ * Successfully received items remain on the queue so will be returned again
+ * by the next call, or a call to xQueueReceive().
+ *
+ * This macro must not be used in an interrupt service routine.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call.     The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue
+ * is empty.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+    if( xQueue == 0 )
+    {
+        // Failed to create the queue.
+    }
+
+    // ...
+
+    // Send a pointer to a struct AMessage object.  Don't block if the
+    // queue is already full.
+    pxMessage = & xMessage;
+    xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+    // ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+    if( xQueue != 0 )
+    {
+        // Peek a message on the created queue.  Block for 10 ticks if a
+        // message is not immediately available.
+        if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+        {
+            // pcRxedMessage now points to the struct AMessage variable posted
+            // by vATask, but the item still remains on the queue.
+        }
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceive(
+                                 xQueueHandle xQueue,
+                                 void *pvBuffer,
+                                 portTickType xTicksToWait
+                            );</pre>
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue.  The item is received by copy so a buffer of
+ * adequate size must be provided.  The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * Successfully received items are removed from the queue.
+ *
+ * This function must not be used in an interrupt service routine.  See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call.     xQueueReceive() will return immediately if xTicksToWait
+ * is zero and the queue is empty.  The time is defined in tick periods so the
+ * constant portTICK_RATE_MS should be used to convert to real time if this is
+ * required.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+    if( xQueue == 0 )
+    {
+        // Failed to create the queue.
+    }
+
+    // ...
+
+    // Send a pointer to a struct AMessage object.  Don't block if the
+    // queue is already full.
+    pxMessage = & xMessage;
+    xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+    // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+    if( xQueue != 0 )
+    {
+        // Receive a message on the created queue.  Block for 10 ticks if a
+        // message is not immediately available.
+        if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+        {
+            // pcRxedMessage now points to the struct AMessage variable posted
+            // by vATask.
+        }
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
+
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericReceive(
+                                       xQueueHandle    xQueue,
+                                       void    *pvBuffer,
+                                       portTickType    xTicksToWait
+                                       portBASE_TYPE    xJustPeek
+                                    );</pre>
+ *
+ * It is preferred that the macro xQueueReceive() be used rather than calling
+ * this function directly.
+ *
+ * Receive an item from a queue.  The item is received by copy so a buffer of
+ * adequate size must be provided.  The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * This function must not be used in an interrupt service routine.  See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call.     The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ * xQueueGenericReceive() will return immediately if the queue is empty and
+ * xTicksToWait is 0.
+ *
+ * @param xJustPeek When set to true, the item received from the queue is not
+ * actually removed from the queue - meaning a subsequent call to
+ * xQueueReceive() will return the same item.  When set to false, the item
+ * being received from the queue is also removed from the queue.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+   <pre>
+ struct AMessage
+ {
+    char ucMessageID;
+    char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+    // Create a queue capable of containing 10 pointers to AMessage structures.
+    // These should be passed by pointer as they contain a lot of data.
+    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+    if( xQueue == 0 )
+    {
+        // Failed to create the queue.
+    }
+
+    // ...
+
+    // Send a pointer to a struct AMessage object.  Don't block if the
+    // queue is already full.
+    pxMessage = & xMessage;
+    xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+    // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+    if( xQueue != 0 )
+    {
+        // Receive a message on the created queue.  Block for 10 ticks if a
+        // message is not immediately available.
+        if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+        {
+            // pcRxedMessage now points to the struct AMessage variable posted
+            // by vATask.
+        }
+    }
+
+    // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek );
+
+/**
+ * queue. h
+ * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );</pre>
+ *
+ * Return the number of messages stored in a queue.
+ *
+ * @param xQueue A handle to the queue being queried.
+ *
+ * @return The number of messages available in the queue.
+ *
+ * \page uxQueueMessagesWaiting uxQueueMessagesWaiting
+ * \ingroup QueueManagement
+ */
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
+
+/**
+ * queue. h
+ * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>
+ *
+ * Delete a queue - freeing all the memory allocated for storing of items
+ * placed on the queue.
+ *
+ * @param xQueue A handle to the queue to be deleted.
+ *
+ * \page vQueueDelete vQueueDelete
+ * \ingroup QueueManagement
+ */
+void vQueueDelete( xQueueHandle xQueue );
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToFrontFromISR(
+                                         xQueueHandle pxQueue,
+                                         const void *pvItemToQueue,
+                                         portBASE_TYPE *pxHigherPriorityTaskWoken
+                                      );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the front of a queue.  It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR.  In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task.  If xQueueSendToFromFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+   <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPrioritTaskWoken;
+
+    // We have not woken a task at the start of the ISR.
+    xHigherPriorityTaskWoken = pdFALSE;
+
+    // Loop until the buffer is empty.
+    do
+    {
+        // Obtain a byte from the buffer.
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+        // Post the byte.
+        xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+    // Now the buffer is empty we can switch context if necessary.
+    if( xHigherPriorityTaskWoken )
+    {
+        taskYIELD ();
+    }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT )
+
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToBackFromISR(
+                                         xQueueHandle pxQueue,
+                                         const void *pvItemToQueue,
+                                         portBASE_TYPE *pxHigherPriorityTaskWoken
+                                      );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the back of a queue.  It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR.  In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task.  If xQueueSendToBackFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+   <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // We have not woken a task at the start of the ISR.
+    xHigherPriorityTaskWoken = pdFALSE;
+
+    // Loop until the buffer is empty.
+    do
+    {
+        // Obtain a byte from the buffer.
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+        // Post the byte.
+        xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+    // Now the buffer is empty we can switch context if necessary.
+    if( xHigherPriorityTaskWoken )
+    {
+        taskYIELD ();
+    }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendFromISR(
+                                     xQueueHandle pxQueue,
+                                     const void *pvItemToQueue,
+                                     portBASE_TYPE *pxHigherPriorityTaskWoken
+                                );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().  It is included
+ * for backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()
+ * macros.
+ *
+ * Post an item to the back of a queue.  It is safe to use this function from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR.  In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task.  If xQueueSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+   <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // We have not woken a task at the start of the ISR.
+    xHigherPriorityTaskWoken = pdFALSE;
+
+    // Loop until the buffer is empty.
+    do
+    {
+        // Obtain a byte from the buffer.
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+        // Post the byte.
+        xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+    // Now the buffer is empty we can switch context if necessary.
+    if( xHigherPriorityTaskWoken )
+    {
+        // Actual macro used here is port specific.
+        taskYIELD_FROM_ISR ();
+    }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericSendFromISR(
+                                           xQueueHandle    pxQueue,
+                                           const    void    *pvItemToQueue,
+                                           portBASE_TYPE    *pxHigherPriorityTaskWoken,
+                                           portBASE_TYPE    xCopyPosition
+                                       );
+ </pre>
+ *
+ * It is preferred that the macros xQueueSendFromISR(),
+ * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place
+ * of calling this function directly.
+ *
+ * Post an item on a queue.  It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR.  In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue.  The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task.  If xQueueGenericSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+   <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;
+
+    // We have not woken a task at the start of the ISR.
+    xHigherPriorityTaskWokenByPost = pdFALSE;
+
+    // Loop until the buffer is empty.
+    do
+    {
+        // Obtain a byte from the buffer.
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+        // Post each byte.
+        xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+    // Now the buffer is empty we can switch context if necessary.  Note that the
+    // name of the yield function required is port specific.
+    if( xHigherPriorityTaskWokenByPost )
+    {
+        taskYIELD_YIELD_FROM_ISR();
+    }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceiveFromISR(
+                                       xQueueHandle    pxQueue,
+                                       void    *pvBuffer,
+                                       portBASE_TYPE    *pxTaskWoken
+                                   );
+ * </pre>
+ *
+ * Receive an item from a queue.  It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param pxTaskWoken A task may be blocked waiting for space to become
+ * available on the queue.  If xQueueReceiveFromISR causes such a task to
+ * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will
+ * remain unchanged.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+   <pre>
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+    // Create a queue capable of containing 10 characters.
+    xQueue = xQueueCreate( 10, sizeof( char ) );
+    if( xQueue == 0 )
+    {
+        // Failed to create the queue.
+    }
+
+    // ...
+
+    // Post some characters that will be used within an ISR.  If the queue
+    // is full then this task will block for xBlockTime ticks.
+    cValueToPost = 'a';
+    xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+    cValueToPost = 'b';
+    xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+    // ... keep posting characters ... this task may block when the queue
+    // becomes full.
+
+    cValueToPost = 'c';
+    xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+    while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+    {
+        // A character was received.  Output the character now.
+        vOutputCharacter( cRxedChar );
+
+        // If removing the character from the queue woke the task that was
+        // posting onto the queue cTaskWokenByReceive will have been set to
+        // pdTRUE.  No matter how many times this loop iterates only one
+        // task will be woken.
+    }
+
+    if( cTaskWokenByPost != ( char ) pdFALSE;
+    {
+        taskYIELD ();
+    }
+ }
+ </pre>
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
+
+/*
+ * Utilities to query queue that are safe to use from an ISR.  These utilities
+ * should be used only from witin an ISR, or within a critical section.
+ */
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );
+
+
+/*
+ * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().
+ * Likewise xQueueAltGenericReceive() is an alternative version of
+ * xQueueGenericReceive().
+ *
+ * The source code that implements the alternative (Alt) API is much
+ * simpler    because it executes everything from within a critical section.
+ * This is    the approach taken by many other RTOSes, but FreeRTOS.org has the
+ * preferred fully featured API too.  The fully featured API has more
+ * complex    code that takes longer to execute, but makes much less use of
+ * critical sections.  Therefore the alternative API sacrifices interrupt
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
+#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
+#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
+#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
+
+/*
+ * The functions defined above are for passing data to and from tasks.  The
+ * functions below are the equivalents for passing data to and from
+ * co-routines.
+ *
+ * These functions are called from the co-routine macro implementation and
+ * should not be called directly from application code.  Instead use the macro
+ * wrappers defined within croutine.h.
+ */
+signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
+signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
+signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );
+signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
+
+/*
+ * For internal use only.  Use xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting() instead of calling these functions directly.
+ */
+xQueueHandle xQueueCreateMutex( void );
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
+
+/*
+ * For internal use only.  Use xSemaphoreTakeMutexRecursive() or
+ * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
+ */
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );
+
+/*
+ * The registry is provided as a means for kernel aware debuggers to
+ * locate queues, semaphores and mutexes.  Call vQueueAddToRegistry() add
+ * a queue, semaphore or mutex handle to the registry if you want the handle
+ * to be available to a kernel aware debugger.  If you are not using a kernel
+ * aware debugger then this function can be ignored.
+ *
+ * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the
+ * registry can hold.  configQUEUE_REGISTRY_SIZE must be greater than 0
+ * within FreeRTOSConfig.h for the registry to be available.  Its value
+ * does not effect the number of queues, semaphores and mutexes that can be
+ * created - just the number that the registry can hold.
+ *
+ * @param xQueue The handle of the queue being added to the registry.  This
+ * is the handle returned by a call to xQueueCreate().  Semaphore and mutex
+ * handles can also be passed in here.
+ *
+ * @param pcName The name to be associated with the handle.  This is the
+ * name that the kernel aware debugger will display.
+ */
+//#if configQUEUE_REGISTRY_SIZE > 0
+    void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );
+//#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QUEUE_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/semphr.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/semphr.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,711 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#ifndef INC_FREERTOS_H
+    #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
+#endif
+
+#ifndef SEMAPHORE_H
+#define SEMAPHORE_H
+
+#include "queue.h"
+
+typedef xQueueHandle xSemaphoreHandle;
+
+#define semBINARY_SEMAPHORE_QUEUE_LENGTH    ( ( unsigned char ) 1 )
+#define semSEMAPHORE_QUEUE_ITEM_LENGTH        ( ( unsigned char ) 0 )
+#define semGIVE_BLOCK_TIME                    ( ( portTickType ) 0 )
+
+
+/**
+ * semphr. h
+ * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
+ * The queue length is 1 as this is a binary semaphore.  The data size is 0
+ * as we don't want to actually store any data - we just want to know if the
+ * queue is empty or full.
+ *
+ * This type of semaphore can be used for pure synchronisation between tasks or
+ * between an interrupt and a task.  The semaphore need not be given back once
+ * obtained, so one task/interrupt can continuously 'give' the semaphore while
+ * another continuously 'takes' the semaphore.  For this reason this type of
+ * semaphore does not use a priority inheritance mechanism.  For an alternative
+ * that does use priority inheritance see xSemaphoreCreateMutex().
+ *
+ * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#define vSemaphoreCreateBinary( xSemaphore )        {                                                                                                \
+                                                        xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH );    \
+                                                        if( xSemaphore != NULL )                                                                    \
+                                                        {                                                                                            \
+                                                            xSemaphoreGive( xSemaphore );                                                            \
+                                                        }                                                                                            \
+                                                    }
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreTake( 
+ *                   xSemaphoreHandle xSemaphore, 
+ *                   portTickType xBlockTime 
+ *               )</pre>
+ *
+ * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting().
+ *
+ * @param xSemaphore A handle to the semaphore being taken - obtained when
+ * the semaphore was created.
+ *
+ * @param xBlockTime The time in ticks to wait for the semaphore to become
+ * available.  The macro portTICK_RATE_MS can be used to convert this to a
+ * real time.  A block time of zero can be used to poll the semaphore.  A block
+ * time of portMAX_DELAY can be used to block indefinitely (provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
+ *
+ * @return pdTRUE if the semaphore was obtained.  pdFALSE
+ * if xBlockTime expired without the semaphore becoming available.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.    
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the 
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreTake xSemaphoreTake
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTake( xSemaphore, xBlockTime )        xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
+
+/**
+ * semphr. h
+ * xSemaphoreTakeRecursive( 
+ *                          xSemaphoreHandle xMutex, 
+ *                          portTickType xBlockTime 
+ *                        )
+ *
+ * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.  
+ * The mutex must have previously been created using a call to 
+ * xSemaphoreCreateRecursiveMutex();
+ * 
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
+ * macro to be available.
+ * 
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 
+ * doesn't become available again until the owner has called 
+ * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, 
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will 
+ * not be available to any other task until it has also  'given' the mutex back
+ * exactly five times.
+ *
+ * @param xMutex A handle to the mutex being obtained.  This is the
+ * handle returned by xSemaphoreCreateRecursiveMutex();
+ *
+ * @param xBlockTime The time in ticks to wait for the semaphore to become
+ * available.  The macro portTICK_RATE_MS can be used to convert this to a
+ * real time.  A block time of zero can be used to poll the semaphore.  If
+ * the task already owns the semaphore then xSemaphoreTakeRecursive() will
+ * return immediately no matter what the value of xBlockTime. 
+ *
+ * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
+ * expired without the semaphore becoming available.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.    
+        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, but instead buried in a more complex
+            // call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTakeRecursive( xMutex, xBlockTime )    xQueueTakeMutexRecursive( xMutex, xBlockTime )
+
+
+/* 
+ * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
+ *
+ * The source code that implements the alternative (Alt) API is much 
+ * simpler    because it executes everything from within a critical section.  
+ * This is    the approach taken by many other RTOSes, but FreeRTOS.org has the 
+ * preferred fully featured API too.  The fully featured API has more 
+ * complex    code that takes longer to execute, but makes much less use of 
+ * critical sections.  Therefore the alternative API sacrifices interrupt 
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+#define xSemaphoreAltTake( xSemaphore, xBlockTime )        xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> to release a semaphore.  The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
+ *
+ * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for
+ * an alternative which can be used from an ISR.
+ *
+ * This macro must also not be used on semaphores created using 
+ * xSemaphoreCreateRecursiveMutex().
+ *
+ * @param xSemaphore A handle to the semaphore being released.  This is the
+ * handle returned when the semaphore was created.
+ *
+ * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
+ * Semaphores are implemented using queues.  An error can occur if there is
+ * no space on the queue to post a message - indicating that the 
+ * semaphore was not first obtained correctly.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreGive xSemaphoreGive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGive( xSemaphore )        xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
+ *
+ * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
+ * The mutex must have previously been created using a call to 
+ * xSemaphoreCreateRecursiveMutex();
+ * 
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
+ * macro to be available.
+ *
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
+ * 
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 
+ * doesn't become available again until the owner has called 
+ * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, 
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will 
+ * not be available to any other task until it has also  'given' the mutex back
+ * exactly five times.
+ *
+ * @param xMutex A handle to the mutex being released, or 'given'.  This is the
+ * handle returned by xSemaphoreCreateMutex();
+ *
+ * @return pdTRUE if the semaphore was given.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.    
+        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, it would be more likely that the calls
+            // to xSemaphoreGiveRecursive() would be called as a call stack
+            // unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveRecursive( xMutex )    xQueueGiveMutexRecursive( xMutex )
+
+/* 
+ * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
+ *
+ * The source code that implements the alternative (Alt) API is much 
+ * simpler    because it executes everything from within a critical section.  
+ * This is    the approach taken by many other RTOSes, but FreeRTOS.org has the 
+ * preferred fully featured API too.  The fully featured API has more 
+ * complex    code that takes longer to execute, but makes much less use of 
+ * critical sections.  Therefore the alternative API sacrifices interrupt 
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+#define xSemaphoreAltGive( xSemaphore )        xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>
+ xSemaphoreGiveFromISR( 
+                          xSemaphoreHandle xSemaphore, 
+                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
+                      )</pre>
+ *
+ * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
+ *
+ * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
+ * must not be used with this macro.
+ *
+ * This macro can be used from an ISR.
+ *
+ * @param xSemaphore A handle to the semaphore being released.  This is the
+ * handle returned when the semaphore was created.
+ *
+ * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT    10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore 
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute 
+            // again.  Note when using the semaphore for synchronisation with an
+            // ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned char ucLocalTickCount = 0;
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+    xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )            xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
+ *
+ * <i>Macro</i> that implements a mutex semaphore by using the existing queue 
+ * mechanism.
+ *
+ * Mutexes created using this macro can be accessed using the xSemaphoreTake()
+ * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and 
+ * xSemaphoreGiveRecursive() macros should not be used.
+ * 
+ * This type of semaphore uses a priority inheritance mechanism so a task 
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 
+ * semaphore it is no longer required.  
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.  
+ *
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be 
+ * used for pure synchronisation (where one task or interrupt always 'gives' the 
+ * semaphore and another always 'takes' the semaphore) and from within interrupt 
+ * service routines.
+ *
+ * @return xSemaphore Handle to the created mutex semaphore.  Should be of type 
+ *        xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateMutex() xQueueCreateMutex()
+
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
+ *
+ * <i>Macro</i> that implements a recursive mutex by using the existing queue 
+ * mechanism.
+ *
+ * Mutexes created using this macro can be accessed using the 
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The 
+ * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 
+ * doesn't become available again until the owner has called 
+ * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, 
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will 
+ * not be available to any other task until it has also  'given' the mutex back
+ * exactly five times.
+ * 
+ * This type of semaphore uses a priority inheritance mechanism so a task 
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 
+ * semaphore it is no longer required.  
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.  
+ *
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be 
+ * used for pure synchronisation (where one task or interrupt always 'gives' the 
+ * semaphore and another always 'takes' the semaphore) and from within interrupt 
+ * service routines.
+ *
+ * @return xSemaphore Handle to the created mutex semaphore.  Should be of type 
+ *        xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
+ *
+ * <i>Macro</i> that creates a counting semaphore by using the existing 
+ * queue mechanism.  
+ *
+ * Counting semaphores are typically used for two things:
+ *
+ * 1) Counting events.  
+ *
+ *    In this usage scenario an event handler will 'give' a semaphore each time
+ *    an event occurs (incrementing the semaphore count value), and a handler 
+ *    task will 'take' a semaphore each time it processes an event 
+ *    (decrementing the semaphore count value).  The count value is therefore 
+ *    the difference between the number of events that have occurred and the 
+ *    number that have been processed.  In this case it is desirable for the 
+ *    initial count value to be zero.
+ *
+ * 2) Resource management.
+ *
+ *    In this usage scenario the count value indicates the number of resources
+ *    available.  To obtain control of a resource a task must first obtain a 
+ *    semaphore - decrementing the semaphore count value.  When the count value
+ *    reaches zero there are no free resources.  When a task finishes with the
+ *    resource it 'gives' the semaphore back - incrementing the semaphore count
+ *    value.  In this case it is desirable for the initial count value to be
+ *    equal to the maximum count value, indicating that all resources are free.
+ *
+ * @param uxMaxCount The maximum count value that can be reached.  When the 
+ *        semaphore reaches this value it can no longer be 'given'.
+ *
+ * @param uxInitialCount The count value assigned to the semaphore when it is
+ *        created.
+ *
+ * @return Handle to the created semaphore.  Null if the semaphore could not be
+ *         created.
+ * 
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ xSemaphoreHandle xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
+
+
+#endif /* SEMAPHORE_H */
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/include/task.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/include/task.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,1267 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+#ifndef INC_FREERTOS_H
+    #error "#include FreeRTOS.h" must appear in source files before "#include task.h"
+#endif
+
+
+
+#ifndef TASK_H
+#define TASK_H
+
+#include "portable.h"
+#include "list.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------
+ * MACROS AND DEFINITIONS
+ *----------------------------------------------------------*/
+
+#define tskKERNEL_VERSION_NUMBER "V6.0.3"
+
+/**
+ * task. h
+ *
+ * Type by which tasks are referenced.  For example, a call to xTaskCreate
+ * returns (via a pointer parameter) an xTaskHandle variable that can then
+ * be used as a parameter to vTaskDelete to delete the task.
+ *
+ * \page xTaskHandle xTaskHandle
+ * \ingroup Tasks
+ */
+typedef void * xTaskHandle;
+
+/*
+ * Used internally only.
+ */
+typedef struct xTIME_OUT
+{
+    portBASE_TYPE xOverflowCount;
+    portTickType  xTimeOnEntering;
+} xTimeOutType;
+
+/*
+ * Defines the memory ranges allocated to the task when an MPU is used.
+ */
+typedef struct xMEMORY_REGION
+{
+    void *pvBaseAddress;
+    unsigned long ulLengthInBytes;
+    unsigned long ulParameters;
+} xMemoryRegion;
+
+#if 0
+//  modified by K.Arai Oct. 28th, 2010
+//  due to compile error!
+/*
+ * Parameters required to create an MPU protected task.
+ */
+typedef struct xTASK_PARAMTERS
+{
+    pdTASK_CODE pvTaskCode;
+    const signed char * const pcName;
+    unsigned short usStackDepth;
+    void *pvParameters;
+    unsigned portBASE_TYPE uxPriority;
+    portSTACK_TYPE *puxStackBuffer;
+    xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];
+} xTaskParameters;
+#endif
+
+/*
+ * Defines the priority used by the idle task.  This must not be modified.
+ *
+ * \ingroup TaskUtils
+ */
+#define tskIDLE_PRIORITY            ( ( unsigned portBASE_TYPE ) 0 )
+
+/**
+ * task. h
+ *
+ * Macro for forcing a context switch.
+ *
+ * \page taskYIELD taskYIELD
+ * \ingroup SchedulerControl
+ */
+#define taskYIELD()                    portYIELD()
+
+/**
+ * task. h
+ *
+ * Macro to mark the start of a critical code region.  Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskENTER_CRITICAL taskENTER_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskENTER_CRITICAL()        portENTER_CRITICAL()
+
+/**
+ * task. h
+ *
+ * Macro to mark the end of a critical code region.  Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskEXIT_CRITICAL taskEXIT_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskEXIT_CRITICAL()            portEXIT_CRITICAL()
+
+/**
+ * task. h
+ *
+ * Macro to disable all maskable interrupts.
+ *
+ * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskDISABLE_INTERRUPTS()    portDISABLE_INTERRUPTS()
+
+/**
+ * task. h
+ *
+ * Macro to enable microcontroller interrupts.
+ *
+ * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskENABLE_INTERRUPTS()        portENABLE_INTERRUPTS()
+
+/* Definitions returned by xTaskGetSchedulerState(). */
+#define taskSCHEDULER_NOT_STARTED    0
+#define taskSCHEDULER_RUNNING        1
+#define taskSCHEDULER_SUSPENDED        2
+
+/*-----------------------------------------------------------
+ * TASK CREATION API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ *<pre>
+ portBASE_TYPE xTaskCreate(
+                              pdTASK_CODE pvTaskCode,
+                              const char * const pcName,
+                              unsigned short usStackDepth,
+                              void *pvParameters,
+                              unsigned portBASE_TYPE uxPriority,
+                              xTaskHandle *pvCreatedTask
+                          );</pre>
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ * 
+ * xTaskCreate() can only be used to create a task that has unrestricted
+ * access to the entire microcontroller memory map.  Systems that include MPU
+ * support can alternatively create an MPU constrained task using 
+ * xTaskCreateRestricted().
+ *
+ * @param pvTaskCode Pointer to the task entry function.  Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task.  This is mainly used to
+ * facilitate debugging.  Max length defined by tskMAX_TASK_NAME_LEN - default
+ * is 16.
+ *
+ * @param usStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes.  For example, if
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task should run.  Systems that
+ * include MPU support can optionally create tasks in a privileged (system)
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter.  For
+ * example, to create a privileged task at priority 2 the uxPriority parameter
+ * should be set to ( 2 | portPRIVILEGE_BIT ).
+ *
+ * @param pvCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file errors. h
+ *
+ * Example usage:
+   <pre>
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+     for( ;; )
+     {
+         // Task code goes here.
+     }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+     // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+     // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+     // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+     // the new task attempts to access it.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+     // Use the handle to delete the task.
+     vTaskDelete( xHandle );
+ }
+   </pre>
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
+
+/**
+ * task. h
+ *<pre>
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );</pre>
+ *
+ * xTaskCreateRestricted() should only be used in systems that include an MPU
+ * implementation.
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ * The function parameters define the memory regions and associated access
+ * permissions allocated to the task.
+ *
+ * @param pxTaskDefinition Pointer to a structure that contains a member
+ * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
+ * documentation) plus an optional stack buffer and the memory region 
+ * definitions.
+ *
+ * @param pxCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file errors. h
+ *
+ * Example usage:
+   <pre>
+// Create an xTaskParameters structure that defines the task to be created.
+static const xTaskParameters xCheckTaskParameters =
+{
+    vATask,        // pvTaskCode - the function that implements the task.
+    "ATask",    // pcName - just a text name for the task to assist debugging.
+    100,        // usStackDepth    - the stack size DEFINED IN WORDS.
+    NULL,        // pvParameters - passed into the task function as the function parameters.
+    ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+    cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+    // xRegions - Allocate up to three separate memory regions for access by
+    // the task, with appropriate access permissions.  Different processors have
+    // different memory alignment requirements - refer to the FreeRTOS documentation
+    // for full information.
+    {                                            
+        // Base address                    Length    Parameters
+        { cReadWriteArray,                32,        portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,                32,        portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,    128,    portMPU_REGION_PRIVILEGED_READ_WRITE }
+    }
+};
+
+int main( void )
+{
+xTaskHandle xHandle;
+
+    // Create a task from the const structure defined above.  The task handle
+    // is requested (the second parameter is not NULL) but in this case just for
+    // demonstration purposes as its not actually used.
+    xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+    // Start the scheduler.
+    vTaskStartScheduler();
+
+    // Will only get here if there was insufficient memory to create the idle
+    // task.
+    for( ;; );
+}
+   </pre>
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )
+
+/**
+ * task. h
+ *<pre>
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );</pre>
+ *
+ * Memory regions are assigned to a restricted task when the task is created by
+ * a call to xTaskCreateRestricted().  These regions can be redefined using
+ * vTaskAllocateMPURegions().
+ * 
+ * @param xTask The handle of the task being updated.
+ *
+ * @param xRegions A pointer to an xMemoryRegion structure that contains the
+ * new memory region definitions.
+ *
+ * Example usage:
+   <pre>
+// Define an array of xMemoryRegion structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{                                            
+    // Base address        Length        Parameters
+    { ucOneKByte,        1024,        portMPU_REGION_READ_WRITE },
+    { 0,                0,            0 },
+    { 0,                0,            0 }
+};
+
+void vATask( void *pvParameters )
+{
+    // This task was created such that it has access to certain regions of
+    // memory as defined by the MPU configuration.  At some point it is 
+    // desired that these MPU regions are replaced with that defined in the
+    // xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+    // for this purpose.  NULL is used as the task handle to indicate that this
+    // function should modify the MPU regions of the calling task.
+    vTaskAllocateMPURegions( NULL, xAltRegions );
+    
+    // Now the task can continue its function, but from this point on can only
+    // access its stack and the ucOneKByte array (unless any other statically
+    // defined or shared regions have been declared elsewhere).
+}
+   </pre>
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskDelete( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Remove a task from the RTOS real time kernels management.  The task being
+ * deleted will be removed from all ready, blocked, suspended and event lists.
+ *
+ * NOTE:  The idle task is responsible for freeing the kernel allocated
+ * memory from tasks that have been deleted.  It is therefore important that
+ * the idle task is not starved of microcontroller processing time if your
+ * application makes any calls to vTaskDelete ().  Memory allocated by the
+ * task code is not automatically freed, and should be freed before the task
+ * is deleted.
+ *
+ * See the demo application file death.c for sample code that utilises
+ * vTaskDelete ().
+ *
+ * @param pxTask The handle of the task to be deleted.  Passing NULL will
+ * cause the calling task to be deleted.
+ *
+ * Example usage:
+   <pre>
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+     // Create the task, storing the handle.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+     // Use the handle to delete the task.
+     vTaskDelete( xHandle );
+ }
+   </pre>
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>
+ *
+ * Delay a task for a given number of ticks.  The actual time that the
+ * task remains blocked depends on the tick rate.  The constant
+ * portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ *
+ * vTaskDelay() specifies a time at which the task wishes to unblock relative to
+ * the time at which vTaskDelay() is called.  For example, specifying a block
+ * period of 100 ticks will cause the task to unblock 100 ticks after
+ * vTaskDelay() is called.  vTaskDelay() does not therefore provide a good method
+ * of controlling the frequency of a cyclical task as the path taken through the
+ * code, as well as other task and interrupt activity, will effect the frequency
+ * at which vTaskDelay() gets called and therefore the time at which the task
+ * next executes.  See vTaskDelayUntil() for an alternative API function designed
+ * to facilitate fixed frequency execution.  It does this by specifying an
+ * absolute time (rather than a relative time) at which the calling task should
+ * unblock.
+ *
+ * @param xTicksToDelay The amount of time, in tick periods, that
+ * the calling task should block.
+ *
+ * Example usage:
+
+ void vTaskFunction( void * pvParameters )
+ {
+ void vTaskFunction( void * pvParameters )
+ {
+ // Block for 500ms.
+ const portTickType xDelay = 500 / portTICK_RATE_MS;
+
+     for( ;; )
+     {
+         // Simply toggle the LED every 500ms, blocking between each toggle.
+         vToggleLED();
+         vTaskDelay( xDelay );
+     }
+ }
+
+ * \defgroup vTaskDelay vTaskDelay
+ * \ingroup TaskCtrl
+ */
+void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>
+ *
+ * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Delay a task until a specified time.  This function can be used by cyclical
+ * tasks to ensure a constant execution frequency.
+ *
+ * This function differs from vTaskDelay () in one important aspect:  vTaskDelay () will
+ * cause a task to block for the specified number of ticks from the time vTaskDelay () is
+ * called.  It is therefore difficult to use vTaskDelay () by itself to generate a fixed
+ * execution frequency as the time between a task starting to execute and that task
+ * calling vTaskDelay () may not be fixed [the task may take a different path though the
+ * code between calls, or may get interrupted or preempted a different number of times
+ * each time it executes].
+ *
+ * Whereas vTaskDelay () specifies a wake time relative to the time at which the function
+ * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to
+ * unblock.
+ *
+ * The constant portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
+ * task was last unblocked.  The variable must be initialised with the current time
+ * prior to its first use (see the example below).  Following this the variable is
+ * automatically updated within vTaskDelayUntil ().
+ *
+ * @param xTimeIncrement The cycle time period.  The task will be unblocked at
+ * time *pxPreviousWakeTime + xTimeIncrement.  Calling vTaskDelayUntil with the
+ * same xTimeIncrement parameter value will cause the task to execute with
+ * a fixed interface period.
+ *
+ * Example usage:
+   <pre>
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+     // Initialise the xLastWakeTime variable with the current time.
+     xLastWakeTime = xTaskGetTickCount ();
+     for( ;; )
+     {
+         // Wait for the next cycle.
+         vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+         // Perform action here.
+     }
+ }
+   </pre>
+ * \defgroup vTaskDelayUntil vTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Obtain the priority of any task.
+ *
+ * @param pxTask Handle of the task to be queried.  Passing a NULL
+ * handle results in the priority of the calling task being returned.
+ *
+ * @return The priority of pxTask.
+ *
+ * Example usage:
+   <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+     // Create a task, storing the handle.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+     // ...
+
+     // Use the handle to obtain the priority of the created task.
+     // It was created with tskIDLE_PRIORITY, but may have changed
+     // it itself.
+     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+     {
+         // The task has changed it's priority.
+     }
+
+     // ...
+
+     // Is our priority higher than the created task?
+     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+     {
+         // Our priority (obtained using NULL handle) is higher.
+     }
+ }
+   </pre>
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet
+ * \ingroup TaskCtrl
+ */
+unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>
+ *
+ * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Set the priority of any task.
+ *
+ * A context switch will occur before the function returns if the priority
+ * being set is higher than the currently executing task.
+ *
+ * @param pxTask Handle to the task for which the priority is being set.
+ * Passing a NULL handle results in the priority of the calling task being set.
+ *
+ * @param uxNewPriority The priority to which the task will be set.
+ *
+ * Example usage:
+   <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+     // Create a task, storing the handle.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+     // ...
+
+     // Use the handle to raise the priority of the created task.
+     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+     // ...
+
+     // Use a NULL handle to raise our priority to the same value.
+     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   </pre>
+ * \defgroup vTaskPrioritySet vTaskPrioritySet
+ * \ingroup TaskCtrl
+ */
+void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Suspend any task.  When suspended a task will never get any microcontroller
+ * processing time, no matter what its priority.
+ *
+ * Calls to vTaskSuspend are not accumulative -
+ * i.e. calling vTaskSuspend () twice on the same task still only requires one
+ * call to vTaskResume () to ready the suspended task.
+ *
+ * @param pxTaskToSuspend Handle to the task being suspended.  Passing a NULL
+ * handle will cause the calling task to be suspended.
+ *
+ * Example usage:
+   <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+     // Create a task, storing the handle.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+     // ...
+
+     // Use the handle to suspend the created task.
+     vTaskSuspend( xHandle );
+
+     // ...
+
+     // The created task will not run during this period, unless
+     // another task calls vTaskResume( xHandle ).
+
+     //...
+
+
+     // Suspend ourselves.
+     vTaskSuspend( NULL );
+
+     // We cannot get here unless another task calls vTaskResume
+     // with our handle as the parameter.
+ }
+   </pre>
+ * \defgroup vTaskSuspend vTaskSuspend
+ * \ingroup TaskCtrl
+ */
+void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Resumes a suspended task.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * vTaskResume ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * Example usage:
+   <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+     // Create a task, storing the handle.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+     // ...
+
+     // Use the handle to suspend the created task.
+     vTaskSuspend( xHandle );
+
+     // ...
+
+     // The created task will not run during this period, unless
+     // another task calls vTaskResume( xHandle ).
+
+     //...
+
+
+     // Resume the suspended task ourselves.
+     vTaskResume( xHandle );
+
+     // The created task will once again get microcontroller processing
+     // time in accordance with it priority within the system.
+ }
+   </pre>
+ * \defgroup vTaskResume vTaskResume
+ * \ingroup TaskCtrl
+ */
+void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be
+ * available.  See the configuration section for more information.
+ *
+ * An implementation of vTaskResume() that can be called from within an ISR.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * xTaskResumeFromISR ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * \defgroup vTaskResumeFromISR vTaskResumeFromISR
+ * \ingroup TaskCtrl
+ */
+portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------
+ * SCHEDULER CONTROL
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <pre>void vTaskStartScheduler( void );</pre>
+ *
+ * Starts the real time kernel tick processing.  After calling the kernel
+ * has control over which tasks are executed and when.  This function
+ * does not return until an executing task calls vTaskEndScheduler ().
+ *
+ * At least one task should be created via a call to xTaskCreate ()
+ * before calling vTaskStartScheduler ().  The idle task is created
+ * automatically when the first application task is created.
+ *
+ * See the demo application file main.c for an example of creating
+ * tasks and starting the kernel.
+ *
+ * Example usage:
+   <pre>
+ void vAFunction( void )
+ {
+     // Create at least one task before starting the kernel.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+     // Start the real time kernel with preemption.
+     vTaskStartScheduler ();
+
+     // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   </pre>
+ *
+ * \defgroup vTaskStartScheduler vTaskStartScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskEndScheduler( void );</pre>
+ *
+ * Stops the real time kernel tick.  All created tasks will be automatically
+ * deleted and multitasking (either preemptive or cooperative) will
+ * stop.  Execution then resumes from the point where vTaskStartScheduler ()
+ * was called, as if vTaskStartScheduler () had just returned.
+ *
+ * See the demo application file main. c in the demo/PC directory for an
+ * example that uses vTaskEndScheduler ().
+ *
+ * vTaskEndScheduler () requires an exit function to be defined within the
+ * portable layer (see vPortEndScheduler () in port. c for the PC port).  This
+ * performs hardware specific operations such as stopping the kernel tick.
+ *
+ * vTaskEndScheduler () will cause all of the resources allocated by the
+ * kernel to be freed - but will not free resources allocated by application
+ * tasks.
+ *
+ * Example usage:
+   <pre>
+ void vTaskCode( void * pvParameters )
+ {
+     for( ;; )
+     {
+         // Task code goes here.
+
+         // At some point we want to end the real time kernel processing
+         // so call ...
+         vTaskEndScheduler ();
+     }
+ }
+
+ void vAFunction( void )
+ {
+     // Create at least one task before starting the kernel.
+     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+     // Start the real time kernel with preemption.
+     vTaskStartScheduler ();
+
+     // Will only get here when the vTaskCode () task has called
+     // vTaskEndScheduler ().  When we get here we are back to single task
+     // execution.
+ }
+   </pre>
+ *
+ * \defgroup vTaskEndScheduler vTaskEndScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>void vTaskSuspendAll( void );</pre>
+ *
+ * Suspends all real time kernel activity while keeping interrupts (including the
+ * kernel tick) enabled.
+ *
+ * After calling vTaskSuspendAll () the calling task will continue to execute
+ * without risk of being swapped out until a call to xTaskResumeAll () has been
+ * made.
+ *
+ * API functions that have the potential to cause a context switch (for example,
+ * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler
+ * is suspended.
+ *
+ * Example usage:
+   <pre>
+ void vTask1( void * pvParameters )
+ {
+     for( ;; )
+     {
+         // Task code goes here.
+
+         // ...
+
+         // At some point the task wants to perform a long operation during
+         // which it does not want to get swapped out.  It cannot use
+         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+         // operation may cause interrupts to be missed - including the
+         // ticks.
+
+         // Prevent the real time kernel swapping out the task.
+         vTaskSuspendAll ();
+
+         // Perform the operation here.  There is no need to use critical
+         // sections as we have all the microcontroller processing time.
+         // During this time interrupts will still operate and the kernel
+         // tick count will be maintained.
+
+         // ...
+
+         // The operation is complete.  Restart the kernel.
+         xTaskResumeAll ();
+     }
+ }
+   </pre>
+ * \defgroup vTaskSuspendAll vTaskSuspendAll
+ * \ingroup SchedulerControl
+ */
+void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>char xTaskResumeAll( void );</pre>
+ *
+ * Resumes real time kernel activity following a call to vTaskSuspendAll ().
+ * After a call to vTaskSuspendAll () the kernel will take control of which
+ * task is executing at any time.
+ *
+ * @return If resuming the scheduler caused a context switch then pdTRUE is
+ *          returned, otherwise pdFALSE is returned.
+ *
+ * Example usage:
+   <pre>
+ void vTask1( void * pvParameters )
+ {
+     for( ;; )
+     {
+         // Task code goes here.
+
+         // ...
+
+         // At some point the task wants to perform a long operation during
+         // which it does not want to get swapped out.  It cannot use
+         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+         // operation may cause interrupts to be missed - including the
+         // ticks.
+
+         // Prevent the real time kernel swapping out the task.
+         vTaskSuspendAll ();
+
+         // Perform the operation here.  There is no need to use critical
+         // sections as we have all the microcontroller processing time.
+         // During this time interrupts will still operate and the real
+         // time kernel tick count will be maintained.
+
+         // ...
+
+         // The operation is complete.  Restart the kernel.  We want to force
+         // a context switch - but there is no point if resuming the scheduler
+         // caused a context switch already.
+         if( !xTaskResumeAll () )
+         {
+              taskYIELD ();
+         }
+     }
+ }
+   </pre>
+ * \defgroup xTaskResumeAll xTaskResumeAll
+ * \ingroup SchedulerControl
+ */
+signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <pre>signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );</pre>
+ *
+ * Utility task that simply returns pdTRUE if the task referenced by xTask is
+ * currently in the Suspended state, or pdFALSE if the task referenced by xTask
+ * is in any other state.
+ *
+ */
+signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------
+ * TASK UTILITIES
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <PRE>volatile portTickType xTaskGetTickCount( void );</PRE>
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * \page xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <PRE>unsigned short uxTaskGetNumberOfTasks( void );</PRE>
+ *
+ * @return The number of tasks that the real time kernel is currently managing.
+ * This includes all ready, blocked and suspended tasks.  A task that
+ * has been deleted but not yet freed by the idle task will also be
+ * included in the count.
+ *
+ * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
+ * \ingroup TaskUtils
+ */
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <PRE>void vTaskList( char *pcWriteBuffer );</PRE>
+ *
+ * configUSE_TRACE_FACILITY must be defined as 1 for this function to be
+ * available.  See the configuration section for more information.
+ *
+ * NOTE: This function will disable interrupts for its duration.  It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Lists all the current tasks, along with their current state and stack
+ * usage high water mark.
+ *
+ * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
+ * suspended ('S').
+ *
+ * @param pcWriteBuffer A buffer into which the above mentioned details
+ * will be written, in ascii form.  This buffer is assumed to be large
+ * enough to contain the generated report.  Approximately 40 bytes per
+ * task should be sufficient.
+ *
+ * \page vTaskList vTaskList
+ * \ingroup TaskUtils
+ */
+void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>
+ *
+ * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function
+ * to be available.  The application must also then provide definitions
+ * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
+ * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter
+ * and return the timers current count value respectively.  The counter
+ * should be at least 10 times the frequency of the tick count.
+ *
+ * NOTE: This function will disable interrupts for its duration.  It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
+ * accumulated execution time being stored for each task.  The resolution
+ * of the accumulated time value depends on the frequency of the timer
+ * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
+ * Calling vTaskGetRunTimeStats() writes the total execution time of each
+ * task into a buffer, both as an absolute count value and as a percentage
+ * of the total system execution time.
+ *
+ * @param pcWriteBuffer A buffer into which the execution times will be
+ * written, in ascii form.  This buffer is assumed to be large enough to
+ * contain the generated report.  Approximately 40 bytes per task should
+ * be sufficient.
+ *
+ * \page vTaskGetRunTimeStats vTaskGetRunTimeStats
+ * \ingroup TaskUtils
+ */
+void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <PRE>void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );</PRE>
+ *
+ * Starts a real time kernel activity trace.  The trace logs the identity of
+ * which task is running when.
+ *
+ * The trace file is stored in binary format.  A separate DOS utility called
+ * convtrce.exe is used to convert this into a tab delimited text file which
+ * can be viewed and plotted in a spread sheet.
+ *
+ * @param pcBuffer The buffer into which the trace will be written.
+ *
+ * @param ulBufferSize The size of pcBuffer in bytes.  The trace will continue
+ * until either the buffer in full, or ulTaskEndTrace () is called.
+ *
+ * \page vTaskStartTrace vTaskStartTrace
+ * \ingroup TaskUtils
+ */
+void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * <PRE>unsigned long ulTaskEndTrace( void );</PRE>
+ *
+ * Stops a kernel activity trace.  See vTaskStartTrace ().
+ *
+ * @return The number of bytes that have been written into the trace buffer.
+ *
+ * \page usTaskEndTrace usTaskEndTrace
+ * \ingroup TaskUtils
+ */
+unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * <PRE>unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );</PRE>
+ *
+ * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for
+ * this function to be available.
+ *
+ * Returns the high water mark of the stack associated with xTask.  That is,
+ * the minimum free stack space there has been (in bytes) since the task
+ * started.  The smaller the returned number the closer the task has come
+ * to overflowing its stack.
+ *
+ * @param xTask Handle of the task associated with the stack to be checked.
+ * Set xTask to NULL to check the stack of the calling task.
+ *
+ * @return The smallest amount of free stack space there has been (in bytes)
+ * since the task referenced by xTask was created.
+ */
+unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * <pre>void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>
+ *
+ * Sets pxHookFunction to be the task hook function used by the task xTask.
+ * Passing xTask as NULL has the effect of setting the calling tasks hook
+ * function.
+ */
+void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * <pre>void xTaskGetApplicationTaskTag( xTaskHandle xTask );</pre>
+ *
+ * Returns the pxHookFunction value assigned to the task xTask.
+ */
+pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * <pre>portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>
+ *
+ * Calls the hook function associated with xTask.  Passing xTask as NULL has
+ * the effect of calling the Running tasks (the calling task) hook function.
+ *
+ * pvParameter is passed to the hook function for the task to interpret as it
+ * wants.
+ */
+portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION;
+
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ *----------------------------------------------------------*/
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Called from the real time kernel tick (either preemptive or cooperative),
+ * this increments the tick count and checks if any tasks that are blocked
+ * for a finite period required removing from a blocked list and placing on
+ * a ready list.
+ */
+void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes the calling task from the ready list and places it both
+ * on the list of tasks waiting for a particular event, and the
+ * list of delayed tasks.  The task will be removed from both lists
+ * and replaced on the ready list should either the event occur (and
+ * there be no higher priority tasks waiting on the same event) or
+ * the delay period expires.
+ *
+ * @param pxEventList The list containing tasks that are blocked waiting
+ * for the event to occur.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait
+ * for the event to occur.  This is specified in kernel ticks,the constant
+ * portTICK_RATE_MS can be used to convert kernel ticks into a real time
+ * period.
+ */
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes a task from both the specified event list and the list of blocked
+ * tasks, and places it on a ready queue.
+ *
+ * xTaskRemoveFromEventList () will be called if either an event occurs to
+ * unblock a task, or the block timeout period expires.
+ *
+ * @return pdTRUE if the task being removed has a higher priority than the task
+ * making the call, otherwise pdFALSE.
+ */
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1
+ * for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Empties the ready and delayed queues of task control blocks, freeing the
+ * memory allocated for the task control block and task stacks as it goes.
+ */
+void vTaskCleanUpResources( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Sets the pointer to the current TCB to the TCB of the highest priority task
+ * that is ready to run.
+ */
+void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Return the handle of the calling task.
+ */
+xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Capture the current time status for future reference.
+ */
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION;
+
+/*
+ * Compare the time status now with that previously captured to see if the
+ * timeout has expired.
+ */
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION;
+
+/*
+ * Shortcut used by the queue implementation to prevent unnecessary call to
+ * taskYIELD();
+ */
+void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Returns the scheduler state as taskSCHEDULER_RUNNING,
+ * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.
+ */
+portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Raises the priority of the mutex holder to that of the calling task should
+ * the mutex holder have a priority less than the calling task.
+ */
+void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;
+
+/*
+ * Set the priority of a task back to its proper priority in the case that it
+ * inherited a higher priority while it was holding a semaphore.
+ */
+void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;
+
+/*
+ * Generic version of the task creation function which is in turn called by the
+ * xTaskCreate() and xTaskCreateRestricted() macros.
+ */
+signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* TASK_H */
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/list.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/list.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,191 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+#include "stdlib.h"
+#include "./FreeRTOS/Source/include/FreeRTOS.h"
+#include "./FreeRTOS/Source/include/list.h"
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+void vListInitialise( xList *pxList )
+{
+    /* The list structure contains a list item which is used to mark the
+    end of the list.  To initialise the list the list end is inserted
+    as the only list entry. */
+    pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
+
+    /* The list end value is the highest possible value in the list to
+    ensure it remains at the end of the list. */
+    pxList->xListEnd.xItemValue = portMAX_DELAY;
+
+    /* The list end next and previous pointers point to itself so we know
+    when the list is empty. */
+    pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
+    pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
+
+    pxList->uxNumberOfItems = 0;
+}
+/*-----------------------------------------------------------*/
+
+void vListInitialiseItem( xListItem *pxItem )
+{
+    /* Make sure the list item is not recorded as being on a list. */
+    pxItem->pvContainer = NULL;
+}
+/*-----------------------------------------------------------*/
+
+void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
+{
+volatile xListItem * pxIndex;
+
+    /* Insert a new list item into pxList, but rather than sort the list,
+    makes the new list item the last item to be removed by a call to
+    pvListGetOwnerOfNextEntry.  This means it has to be the item pointed to by
+    the pxIndex member. */
+    pxIndex = pxList->pxIndex;
+
+    pxNewListItem->pxNext = pxIndex->pxNext;
+    pxNewListItem->pxPrevious = pxList->pxIndex;
+    pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
+    pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
+    pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
+
+    /* Remember which list the item is in. */
+    pxNewListItem->pvContainer = ( void * ) pxList;
+
+    ( pxList->uxNumberOfItems )++;
+}
+/*-----------------------------------------------------------*/
+
+void vListInsert( xList *pxList, xListItem *pxNewListItem )
+{
+volatile xListItem *pxIterator;
+portTickType xValueOfInsertion;
+
+    /* Insert the new list item into the list, sorted in ulListItem order. */
+    xValueOfInsertion = pxNewListItem->xItemValue;
+
+    /* If the list already contains a list item with the same item value then
+    the new list item should be placed after it.  This ensures that TCB's which
+    are stored in ready lists (all of which have the same ulListItem value)
+    get an equal share of the CPU.  However, if the xItemValue is the same as 
+    the back marker the iteration loop below will not end.  This means we need
+    to guard against this by checking the value first and modifying the 
+    algorithm slightly if necessary. */
+    if( xValueOfInsertion == portMAX_DELAY )
+    {
+        pxIterator = pxList->xListEnd.pxPrevious;
+    }
+    else
+    {
+        /* *** NOTE ***********************************************************
+        If you find your application is crashing here then likely causes are:
+            1) Stack overflow - 
+               see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
+            2) Incorrect interrupt priority assignment, especially on Cortex M3 
+               parts where numerically high priority values denote low actual 
+               interrupt priories, which can seem counter intuitive.  See 
+               configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
+            3) Calling an API function from within a critical section or when
+               the scheduler is suspended.
+            4) Using a queue or semaphore before it has been initialised or
+               before the scheduler has been started (are interrupts firing
+               before vTaskStartScheduler() has been called?).
+        See http://www.freertos.org/FAQHelp.html for more tips. 
+        **********************************************************************/
+        
+        for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
+        {
+            /* There is nothing to do here, we are just iterating to the
+            wanted insertion position. */
+        }
+    }
+
+    pxNewListItem->pxNext = pxIterator->pxNext;
+    pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
+    pxNewListItem->pxPrevious = pxIterator;
+    pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
+
+    /* Remember which list the item is in.  This allows fast removal of the
+    item later. */
+    pxNewListItem->pvContainer = ( void * ) pxList;
+
+    ( pxList->uxNumberOfItems )++;
+}
+/*-----------------------------------------------------------*/
+
+void vListRemove( xListItem *pxItemToRemove )
+{
+xList * pxList;
+
+    pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
+    pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
+    
+    /* The list item knows which list it is in.  Obtain the list from the list
+    item. */
+    pxList = ( xList * ) pxItemToRemove->pvContainer;
+
+    /* Make sure the index is left pointing to a valid item. */
+    if( pxList->pxIndex == pxItemToRemove )
+    {
+        pxList->pxIndex = pxItemToRemove->pxPrevious;
+    }
+
+    pxItemToRemove->pvContainer = NULL;
+    ( pxList->uxNumberOfItems )--;
+}
+/*-----------------------------------------------------------*/
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/portable/GCC/ARM_CM3/port.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,313 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the ARM CM3 port.
+ *----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+// Some functions go to port_asm.c
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
+defined.  The value should also ensure backward compatibility.
+FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
+#ifndef configKERNEL_INTERRUPT_PRIORITY
+    #define configKERNEL_INTERRUPT_PRIORITY 255
+#endif
+
+/* Constants required to manipulate the NVIC. */
+#define portNVIC_SYSTICK_CTRL        ( ( volatile unsigned long *) 0xe000e010 )
+#define portNVIC_SYSTICK_LOAD        ( ( volatile unsigned long *) 0xe000e014 )
+#define portNVIC_INT_CTRL            ( ( volatile unsigned long *) 0xe000ed04 )
+#define portNVIC_SYSPRI2            ( ( volatile unsigned long *) 0xe000ed20 )
+#define portNVIC_SYSTICK_CLK        0x00000004
+#define portNVIC_SYSTICK_INT        0x00000002
+#define portNVIC_SYSTICK_ENABLE        0x00000001
+#define portNVIC_PENDSVSET            0x10000000
+#define portNVIC_PENDSV_PRI            ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
+#define portNVIC_SYSTICK_PRI        ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
+
+/* Constants required to set up the initial stack. */
+#define portINITIAL_XPSR            ( 0x01000000 )
+
+/* The priority used by the kernel is assigned to a variable to make access
+from inline assembler easier. */
+//const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
+
+/* Each task maintains its own interrupt status in the critical nesting
+variable. */
+#if 0
+static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
+#else
+unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
+#endif
+/*
+ * Setup the timer to generate the tick interrupts.
+ */
+static void prvSetupTimerInterrupt( void );
+
+/*
+ * Exception handlers.
+ */
+#if 0
+void xPortPendSVHandler( void ) __attribute__ (( naked ));
+#else
+extern void xPortPendSVHandler( void );
+#endif
+void xPortSysTickHandler( void );
+#if 0
+void vPortSVCHandler( void ) __attribute__ (( naked ));
+#else
+extern void vPortSVCHandler( void );
+#endif
+
+/*
+ * Start first task is a separate function so it can be tested in isolation.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+void vPortStartFirstTask( void ) __attribute__ (( naked ));
+#else
+extern void vPortStartFirstTask( void );
+#endif
+#ifdef __cplusplus
+}
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
+{
+    /* Simulate the stack frame as it would be created by a context switch
+    interrupt. */
+    pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
+    *pxTopOfStack = portINITIAL_XPSR;    /* xPSR */
+    pxTopOfStack--;
+    *pxTopOfStack = ( portSTACK_TYPE ) pxCode;    /* PC */
+    pxTopOfStack--;
+    *pxTopOfStack = 0;    /* LR */
+    pxTopOfStack -= 5;    /* R12, R3, R2 and R1. */
+    *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;    /* R0 */
+    pxTopOfStack -= 8;    /* R11, R10, R9, R8, R7, R6, R5 and R4. */
+
+    return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+#if 0
+void vPortSVCHandler( void )
+{
+    __asm volatile (
+                    "    ldr    r3, pxCurrentTCBConst2        \n" /* Restore the context. */
+                    "    ldr r1, [r3]                    \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
+                    "    ldr r0, [r1]                    \n" /* The first item in pxCurrentTCB is the task top of stack. */
+                    "    ldmia r0!, {r4-r11}                \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
+                    "    msr psp, r0                        \n" /* Restore the task stack pointer. */
+                    "    mov r0, #0                         \n"
+                    "    msr    basepri, r0                    \n"
+                    "    orr r14, #0xd                    \n"
+                    "    bx r14                            \n"
+                    "                                    \n"
+                    "    .align 2                        \n"
+                    "pxCurrentTCBConst2: .word pxCurrentTCB                \n"
+                );
+}
+/*-----------------------------------------------------------*/
+#endif
+
+#if 0
+void vPortStartFirstTask( void )
+{
+    __asm volatile(
+                    " ldr r0, =0xE000ED08     \n" /* Use the NVIC offset register to locate the stack. */
+                    " ldr r0, [r0]             \n"
+                    " ldr r0, [r0]             \n"
+                    " msr msp, r0            \n" /* Set the msp back to the start of the stack. */
+                    " svc 0                    \n" /* System call to start first task. */
+                );
+}
+/*-----------------------------------------------------------*/
+#endif
+
+/*
+ * See header file for description.
+ */
+portBASE_TYPE xPortStartScheduler( void )
+{
+    /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
+    *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
+    *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
+
+    /* Start the timer that generates the tick ISR.  Interrupts are disabled
+    here already. */
+    prvSetupTimerInterrupt();
+
+    /* Initialise the critical nesting count ready for the first task. */
+    uxCriticalNesting = 0;
+
+    /* Start the first task. */
+    vPortStartFirstTask();
+
+    /* Should not get here! */
+    return 0;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler( void )
+{
+    /* It is unlikely that the CM3 port will require this function as there
+    is nothing to return to.  */
+}
+/*-----------------------------------------------------------*/
+
+void vPortYieldFromISR( void )
+{
+    /* Set a PendSV to request a context switch. */
+    *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+}
+/*-----------------------------------------------------------*/
+
+#if 0
+void vPortEnterCritical( void )
+{
+    portDISABLE_INTERRUPTS();
+    uxCriticalNesting++;
+}
+/*-----------------------------------------------------------*/
+
+void vPortExitCritical( void )
+{
+    uxCriticalNesting--;
+    if( uxCriticalNesting == 0 )
+    {
+        portENABLE_INTERRUPTS();
+    }
+}
+/*-----------------------------------------------------------*/
+
+
+void xPortPendSVHandler( void )
+{
+    /* This is a naked function. */
+
+    __asm volatile
+    (
+    "    mrs r0, psp                            \n"
+    "                                        \n"
+    "    ldr    r3, pxCurrentTCBConst            \n" /* Get the location of the current TCB. */
+    "    ldr    r2, [r3]                        \n"
+    "                                        \n"
+    "    stmdb r0!, {r4-r11}                    \n" /* Save the remaining registers. */
+    "    str r0, [r2]                        \n" /* Save the new top of stack into the first member of the TCB. */
+    "                                        \n"
+    "    stmdb sp!, {r3, r14}                \n"
+    "    mov r0, %0                            \n"
+    "    msr basepri, r0                        \n"
+    "    bl vTaskSwitchContext                \n"
+    "    mov r0, #0                            \n"
+    "    msr basepri, r0                        \n"
+    "    ldmia sp!, {r3, r14}                \n"
+    "                                        \n"    /* Restore the context, including the critical nesting count. */
+    "    ldr r1, [r3]                        \n"
+    "    ldr r0, [r1]                        \n" /* The first item in pxCurrentTCB is the task top of stack. */
+    "    ldmia r0!, {r4-r11}                    \n" /* Pop the registers. */
+    "    msr psp, r0                            \n"
+    "    bx r14                                \n"
+    "                                        \n"
+    "    .align 2                            \n"
+    "pxCurrentTCBConst: .word pxCurrentTCB    \n"
+    ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
+    );
+}
+/*-----------------------------------------------------------*/
+
+void xPortSysTickHandler( void )
+{
+unsigned long ulDummy;
+
+    /* If using preemption, also force a context switch. */
+    #if configUSE_PREEMPTION == 1
+        *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+    #endif
+
+    // Modified by  Kenji Arai / JH1PJL, October 30th,2010
+    ulDummy = 0;
+    portSET_INTERRUPT_MASK_FROM_ISR();
+    {
+        vTaskIncrementTick();
+    }
+    portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
+}
+/*-----------------------------------------------------------*/
+#endif
+
+/*
+ * Setup the systick timer to generate the tick interrupts at the required
+ * frequency.
+ */
+void prvSetupTimerInterrupt( void )
+{
+    /* Configure SysTick to interrupt at the requested rate. */
+    *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
+    *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
+}
+/*-----------------------------------------------------------*/
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/portable/GCC/ARM_CM3/port_asm_mbed.s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/port_asm_mbed.s	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,606 @@
+;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+;
+; This is a program for FreeRTOS on LPC1768 mbed IDE
+;
+;    C source file:             port_asm.c
+;    Compiled on:             GCC: (Sourcery G++ Lite 2010q1-188) 4.4.1
+;    Hand modification by:    Kenji Arai / JH1PJL
+;                        http://www.page.sannet.ne.jp/kenjia/index.html
+;
+;    Started on:                October 31st, 2010
+;    updated on:                October 31st, 2010
+;
+;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+;    .syntax unified
+;    .cpu cortex-m3
+;    .fpu softvfp
+;    .eabi_attribute 20, 1
+;    .eabi_attribute 21, 1
+;    .eabi_attribute 23, 3
+;    .eabi_attribute 24, 1
+;    .eabi_attribute 25, 1
+;    .eabi_attribute 26, 1
+;    .eabi_attribute 30, 6
+;    .eabi_attribute 18, 4
+
+    EXTERN  pxCurrentTCB
+    EXTERN  uxCriticalNesting
+    EXTERN  vTaskSwitchContext
+    EXTERN  vTaskIncrementTick
+    EXTERN  prvCopyDataToQueue
+    EXTERN  xTaskRemoveFromEventList
+    EXTERN  prvCopyDataFromQueue
+    EXTERN  prvIdleTask
+    EXTERN  xTaskGenericCreate
+    EXTERN  xSchedulerRunning
+    EXTERN  xTickCount
+    EXTERN  vConfigureTimerForRunTimeStats  
+    EXTERN  xPortStartScheduler
+    EXTERN  vPortEndScheduler
+    
+    CODE16
+    PRESERVE8
+    AREA    Port, CODE, READONLY
+;//////////////////////////////////////////////////////
+;    .thumb
+    THUMB
+;    .file    "port_asm.c"
+;    .text
+;    .align    2
+    ALIGN    2
+    GLOBAL  Reset_Handler
+    THUMB
+Reset_Handler
+    push    {r7, lr}
+    pop    {r7, pc}
+
+;///////////////////////////////////////////////////////    
+    ALIGN   2    
+;    .global    vPortSVCHandler
+    GLOBAL    vPortSVCHandler
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vPortSVCHandler, %function
+;vPortSVCHandler:
+vPortSVCHandler
+;    @ Naked Function: prologue and epilogue provided by programmer.
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+;@ 199 "port_asm.c" 1
+    ldr        r3, pxCurrentTCBConst2        
+    ldr        r1, [r3]                    
+    ldr        r0, [r1]                    
+    ldmia    r0!, {r4-r11}                
+    msr        psp, r0                        
+    mov        r0, #0                         
+    msr        basepri, r0                    
+    orr        r14, #0xd                    
+    bx        r14                            
+                                    
+;    .align    2
+    ALIGN    2                        
+;pxCurrentTCBConst2: .word pxCurrentTCB                
+pxCurrentTCBConst2 DCD pxCurrentTCB
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+;    .size    vPortSVCHandler, .-vPortSVCHandler
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    vPortStartFirstTask
+    GLOBAL    vPortStartFirstTask
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vPortStartFirstTask, %function
+;vPortStartFirstTask:
+vPortStartFirstTask
+;    @ Naked Function: prologue and epilogue provided by programmer.
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+;@ 218 "port_asm.c" 1
+    ldr        r0, =0xE000ED08     
+    ldr        r0, [r0]             
+    ldr        r0, [r0]             
+    msr        msp, r0            
+    svc        0                    
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+;    .size    vPortStartFirstTask, .-vPortStartFirstTask
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    vPortEnterCritical
+    GLOBAL    vPortEnterCritical
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vPortEnterCritical, %function
+;vPortEnterCritical:
+vPortEnterCritical
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+;    @ link register save eliminated.
+    push       {r7}
+    add        r7, sp, #0
+;@ 270 "port_asm.c" 1
+    mov        r0, #40                                
+    msr        basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    movw    r3, #:lower16:uxCriticalNesting
+    movt        r3, #:upper16:uxCriticalNesting
+    ldr        r3, [r3, #0]
+    add        r2, r3, #1
+    movw    r3, #:lower16:uxCriticalNesting
+    movt        r3, #:upper16:uxCriticalNesting
+    str        r2, [r3, #0]
+    mov        sp, r7
+    pop        {r7}
+    bx        lr
+;    .size    vPortEnterCritical, .-vPortEnterCritical
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    vPortExitCritical
+    GLOBAL    vPortExitCritical
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vPortExitCritical, %function
+;vPortExitCritical:
+vPortExitCritical
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+;    @ link register save eliminated.
+    push        {r7}
+    add        r7, sp, #0
+    movw    r3, #:lower16:uxCriticalNesting
+    movt        r3, #:upper16:uxCriticalNesting
+    ldr        r3, [r3, #0]
+    add        r2, r3, #-1
+    movw    r3, #:lower16:uxCriticalNesting
+    movt        r3, #:upper16:uxCriticalNesting
+    str        r2, [r3, #0]
+    movw    r3, #:lower16:uxCriticalNesting
+    movt        r3, #:upper16:uxCriticalNesting
+    ldr        r3, [r3, #0]
+    cmp        r3, #0
+;    bne    .L9
+    bne        Jmp0
+;@ 280 "port_asm.c" 1
+    mov        r0, #0                    
+    msr        basepri, r0                
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+;.L9:
+Jmp0
+    mov        sp, r7
+    pop        {r7}
+    bx        lr
+;    .size    vPortExitCritical, .-vPortExitCritical
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    xPortPendSVHandler
+    GLOBAL    xPortPendSVHandler
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    xPortPendSVHandler, %function
+;xPortPendSVHandler:
+xPortPendSVHandler
+;    @ Naked Function: prologue and epilogue provided by programmer.
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+;@ 289 "port_asm.c" 1
+    mrs        r0, psp                            
+                                        
+    ldr        r3, pxCurrentTCBConst            
+    ldr        r2, [r3]                        
+                                        
+    stmdb    r0!, {r4-r11}                    
+    str        r0, [r2]                        
+                                        
+    stmdb    sp!, {r3, r14}                
+    mov        r0, #40                            
+    msr        basepri, r0
+;   error      " port_asm_mbed.s.s.LPC1768.o(Port) contains invalid call from '~PRES8 (The user did not require code to preserve 8-byte aligment of 8-byte data objects)' function to 'REQ8 (Code was permitted to depend on the 8-byte aligment of 8-byte data items)' function vTaskSwitchContext. (EL6238E)                     
+    bl        vTaskSwitchContext
+                    
+    mov        r0, #0                            
+    msr        basepri, r0                        
+    ldmia    sp!, {r3, r14}                
+                                        
+    ldr        r1, [r3]                        
+    ldr        r0, [r1]                        
+    ldmia    r0!, {r4-r11}                    
+    msr        psp, r0                            
+    bx        r14                                
+                                        
+;    .align    2
+    ALIGN    2                            
+;pxCurrentTCBConst: .word pxCurrentTCB
+pxCurrentTCBConst DCD pxCurrentTCB    
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+;    .size    xPortPendSVHandler, .-xPortPendSVHandler
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    xPortSysTickHandler
+    GLOBAL    xPortSysTickHandler
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    xPortSysTickHandler, %function
+;xPortSysTickHandler:
+xPortSysTickHandler
+;    @ args = 0, pretend = 0, frame = 8
+;    @ frame_needed = 1, uses_anonymous_args = 0
+    push       {r7, lr}
+    sub        sp, sp, #8
+    add        r7, sp, #0
+;    movw       r3, #:lower16:-536810236
+;    movt       r3, #:upper16:-536810236
+    movw       r3, #0xED04
+    movt       r3, #0xE000
+;    movw       r3, #:LDW:(-536810236)
+;    movt       r3, #:HDW:(-536810236)
+;    mov32      r3, -536810236
+;    mov        r2, #268435456
+    str        r2, [r3, #0]
+    mov        r3, #0
+    str        r3, [r7, #4]
+;@ 329 "port_asm.c" 1
+    mov        r0, #40                                
+    msr        basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    bl    vTaskIncrementTick
+;@ 333 "port_asm.c" 1
+    mov        r0, #0                    
+    msr        basepri, r0                
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    add    r7, r7, #8
+    mov    sp, r7
+    pop    {r7, pc}
+;    .size    xPortSysTickHandler, .-xPortSysTickHandler
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    xQueueGenericSendFromISR
+    GLOBAL    xQueueGenericSendFromISR
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    xQueueGenericSendFromISR, %function
+;xQueueGenericSendFromISR:
+xQueueGenericSendFromISR
+;    @ args = 0, pretend = 0, frame = 24
+;    @ frame_needed = 1, uses_anonymous_args = 0
+    push    {r7, lr}
+    sub    sp, sp, #24
+    add    r7, sp, #0
+    str    r0, [r7, #12]
+    str    r1, [r7, #8]
+    str    r2, [r7, #4]
+    str    r3, [r7, #0]
+    mov    r3, #0
+    str    r3, [r7, #20]
+;@ 399 "port_asm.c" 1
+    mov r0, #40                                
+    msr basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    ldr    r3, [r7, #12]
+    ldr    r2, [r3, #56]
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #60]
+    cmp    r2, r3
+;    bcs    .L15
+    bcs    Jmp5
+    ldr    r0, [r7, #12]
+    ldr    r1, [r7, #8]
+    ldr    r2, [r7, #0]
+    bl    prvCopyDataToQueue
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #72]
+    cmp    r3, #-1
+;    bne    .L16
+    bne    Jmp1
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #36]
+    cmp    r3, #0
+;    beq    .L21
+    beq    Jmp2
+    ldr    r3, [r7, #12]
+    add    r3, r3, #36
+    mov    r0, r3
+    bl    xTaskRemoveFromEventList
+    mov    r3, r0
+    cmp    r3, #0
+;    beq    .L22
+    beq    Jmp3
+    ldr    r3, [r7, #4]
+    mov    r2, #1
+    str    r2, [r3, #0]
+;    b    .L18
+    b    Jmp4
+;.L16:
+Jmp1
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #72]
+    add    r2, r3, #1
+    ldr    r3, [r7, #12]
+    str    r2, [r3, #72]
+;    b    .L18
+    b    Jmp4
+;.L21:
+Jmp2
+    nop
+;    b    .L18
+    b    Jmp4
+;.L22:
+Jmp3
+    nop
+;.L18:
+Jmp4
+    mov    r3, #1
+    str    r3, [r7, #16]
+;    b    .L19
+    b    Jmp6
+;.L15:
+Jmp5
+    mov    r3, #0
+    str    r3, [r7, #16]
+;.L19:
+Jmp6
+;@ 436 "port_asm.c" 1
+    mov r0, #0                    
+    msr basepri, r0                
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    ldr    r3, [r7, #16]
+    mov    r0, r3
+    add    r7, r7, #24
+    mov    sp, r7
+    pop    {r7, pc}
+;    .size    xQueueGenericSendFromISR, .-xQueueGenericSendFromISR
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    xQueueReceiveFromISR
+    GLOBAL    xQueueReceiveFromISR
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    xQueueReceiveFromISR, %function
+;xQueueReceiveFromISR:
+xQueueReceiveFromISR
+;    @ args = 0, pretend = 0, frame = 24
+;    @ frame_needed = 1, uses_anonymous_args = 0
+    push    {r7, lr}
+    sub    sp, sp, #24
+    add    r7, sp, #0
+    str    r0, [r7, #12]
+    str    r1, [r7, #8]
+    str    r2, [r7, #4]
+    mov    r3, #0
+    str    r3, [r7, #20]
+;@ 449 "port_asm.c" 1
+    mov r0, #40                                
+    msr basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #56]
+    cmp    r3, #0
+;    beq    .L24
+    beq    Jmp11
+    ldr    r0, [r7, #12]
+    ldr    r1, [r7, #8]
+    bl    prvCopyDataFromQueue
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #56]
+    add    r2, r3, #-1
+    ldr    r3, [r7, #12]
+    str    r2, [r3, #56]
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #68]
+    cmp    r3, #-1
+;    bne    .L25
+    bne    Jmp7
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #16]
+    cmp    r3, #0
+;    beq    .L30
+    beq    Jmp8
+    ldr    r3, [r7, #12]
+    add    r3, r3, #16
+    mov    r0, r3
+    bl    xTaskRemoveFromEventList
+    mov    r3, r0
+    cmp    r3, #0
+;    beq    .L31
+    beq    Jmp9
+    ldr    r3, [r7, #4]
+    mov    r2, #1
+    str    r2, [r3, #0]
+;    b    .L27
+    b    Jmp10
+;.L25:
+Jmp7
+    ldr    r3, [r7, #12]
+    ldr    r3, [r3, #68]
+    add    r2, r3, #1
+    ldr    r3, [r7, #12]
+    str    r2, [r3, #68]
+;    b    .L27
+    b    Jmp10
+;.L30:
+Jmp8
+    nop
+;    b    .L27
+    b    Jmp10
+;.L31:
+Jmp9
+    nop
+;.L27:
+Jmp10
+    mov    r3, #1
+    str    r3, [r7, #16]
+;    b    .L28
+    b    Jmp12
+;.L24:
+Jmp11
+    mov    r3, #0
+    str    r3, [r7, #16]
+;.L28:
+Jmp12
+;@ 489 "port_asm.c" 1
+    mov r0, #0                    
+    msr basepri, r0                
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    ldr    r3, [r7, #16]
+    mov    r0, r3
+    add    r7, r7, #24
+    mov    sp, r7
+    pop    {r7, pc}
+;    .size    xQueueReceiveFromISR, .-xQueueReceiveFromISR
+;///////////////////////////////////////////////////////
+;    .section    .rodata
+;    AREA    Text, CODE, READONLY ??????????????????????????????????????????????
+;    .align    2
+    ALIGN    2
+;.LC0:
+Txt0
+;    .ascii    "IDLE\000"
+     DCB       "IDLE\000",0
+;    .text
+;    AREA    Port, CODE, READONLY  ??????????????????????????????????????????????
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    vTaskStartScheduler
+    GLOBAL    vTaskStartScheduler
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vTaskStartScheduler, %function
+;vTaskStartScheduler:
+vTaskStartScheduler
+;    @ args = 0, pretend = 0, frame = 8
+;    @ frame_needed = 1, uses_anonymous_args = 0
+    push    {r7, lr}
+    sub    sp, sp, #24
+    add    r7, sp, #16
+;    movw    r3, #:lower16:.LC0
+;    movt    r3, #:upper16:.LC0
+;    movw    r3, # LDW Txt0
+;    movt    r3, # HDW Txt0
+    movw    r3, #:lower16:Txt0
+    movt    r3, #:upper16:Txt0
+    mov    r2, #0
+    str    r2, [sp, #0]
+    mov    r2, #0
+    str    r2, [sp, #4]
+    mov    r2, #0
+    str    r2, [sp, #8]
+    mov    r2, #0
+    str    r2, [sp, #12]
+    movw    r0, #:lower16:prvIdleTask
+    movt    r0, #:upper16:prvIdleTask
+    mov    r1, r3
+    mov    r2, #64
+    mov    r3, #0
+    bl    xTaskGenericCreate
+    mov    r3, r0
+    str    r3, [r7, #4]
+    ldr    r3, [r7, #4]
+    cmp    r3, #1
+;    bne    .L34
+    bne    Jmp13
+;@ 514 "port_asm.c" 1
+    mov r0, #40                                
+    msr basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    movw    r3, #:lower16:xSchedulerRunning
+    movt        r3, #:upper16:xSchedulerRunning
+    mov        r2, #1
+    str        r2, [r3, #0]
+    movw    r3, #:lower16:xTickCount
+    movt        r3, #:upper16:xTickCount
+    mov        r2, #0
+    str        r2, [r3, #0]
+    bl        vConfigureTimerForRunTimeStats
+    bl        xPortStartScheduler
+;.L34:
+Jmp13
+    add    r7, r7, #8
+    mov    sp, r7
+    pop    {r7, pc}
+;    .size    vTaskStartScheduler, .-vTaskStartScheduler
+;///////////////////////////////////////////////////////
+;    .align    2
+    ALIGN    2
+;    .global    vTaskEndScheduler
+    GLOBAL    vTaskEndScheduler
+;    .thumb
+    THUMB
+;    .thumb_func
+;    .type    vTaskEndScheduler, %function
+;vTaskEndScheduler:
+vTaskEndScheduler
+;    @ args = 0, pretend = 0, frame = 0
+;    @ frame_needed = 1, uses_anonymous_args = 0
+    push    {r7, lr}
+    add    r7, sp, #0
+;@ 546 "port_asm.c" 1
+    mov r0, #40                                
+    msr basepri, r0                            
+
+;@ 0 "" 2
+;    .thumb
+    THUMB
+    movw    r3, #:lower16:xSchedulerRunning
+    movt    r3, #:upper16:xSchedulerRunning
+    mov    r2, #0
+    str    r2, [r3, #0]
+    bl    vPortEndScheduler
+    pop    {r7, pc}
+;    .size    vTaskEndScheduler, .-vTaskEndScheduler
+;    .ident    "GCC: (Sourcery G++ Lite 2010q1-188) 4.4.1"
+    ALIGN    2
+    nop
+    nop
+    nop
+    END
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,226 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------
+ * Port specific definitions.  
+ *
+ * The settings in this file configure FreeRTOS correctly for the
+ * given hardware and compiler.
+ *
+ * These settings should not be altered.
+ *-----------------------------------------------------------
+ */
+
+/* Type definitions. */
+#define portCHAR        char
+#define portFLOAT        float
+#define portDOUBLE        double
+#define portLONG        long
+#define portSHORT        short
+#define portSTACK_TYPE    unsigned portLONG
+#define portBASE_TYPE    long
+
+#if( configUSE_16_BIT_TICKS == 1 )
+    typedef unsigned portSHORT portTickType;
+    #define portMAX_DELAY ( portTickType ) 0xffff
+#else
+    typedef unsigned portLONG portTickType;
+    #define portMAX_DELAY ( portTickType ) 0xffffffff
+#endif
+/*-----------------------------------------------------------*/    
+
+/* Architecture specifics. */
+#define portSTACK_GROWTH            ( -1 )
+#define portTICK_RATE_MS            ( ( portTickType ) 1000 / configTICK_RATE_HZ )        
+#define portBYTE_ALIGNMENT            8
+/*-----------------------------------------------------------*/    
+
+
+/* Scheduler utilities. */
+extern void vPortYieldFromISR( void );
+
+#define portYIELD()    vPortYieldFromISR()
+
+#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+#if 0
+/* Critical section management. */
+
+/* 
+ * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
+ * registers.  r0 is clobbered.
+ */ 
+//#define portSET_INTERRUPT_MASK()                        \
+    __asm volatile                                        \
+    (                                                    \
+        "    mov r0, %0                                \n"    \
+        "    msr basepri, r0                            \n" \
+        ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0"    \
+    )
+    
+/*
+ * Set basepri back to 0 without effective other registers.
+ * r0 is clobbered.
+ */
+//#define portCLEAR_INTERRUPT_MASK()            \
+    __asm volatile                            \
+    (                                        \
+        "    mov r0, #0                    \n"    \
+        "    msr basepri, r0                \n"    \
+        :::"r0"                                \
+    )
+
+//#define portSET_INTERRUPT_MASK_FROM_ISR()        0;portSET_INTERRUPT_MASK()
+//#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    portCLEAR_INTERRUPT_MASK();(void)x
+
+extern void vPortEnterCritical( void );
+extern void vPortExitCritical( void );
+
+#define portDISABLE_INTERRUPTS()    portSET_INTERRUPT_MASK()
+#define portENABLE_INTERRUPTS()        portCLEAR_INTERRUPT_MASK()
+#define portENTER_CRITICAL()        vPortEnterCritical()
+#define portEXIT_CRITICAL()            vPortExitCritical()
+#else
+
+/* Critical section management. */
+
+/*
+ * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
+ * registers.  r0 is clobbered.
+ */
+#define portSET_INTERRUPT_MASK()                         \
+    __asm volatile                                         \
+    (                                                     \
+        "    mov r0, %0                                \n"     \
+        "    msr basepri, r0                            \n"  \
+        ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \
+    )
+
+
+/*
+ * Set basepri back to 0 without effective other registers.
+ * r0 is clobbered.
+ */
+#define portCLEAR_INTERRUPT_MASK()            \
+    __asm volatile                            \
+    (                                        \
+        "    mov r0, #0                    \n"    \
+        "    msr basepri, r0                \n"    \
+        :::"r0"                                \
+    )
+
+
+#define portSET_INTERRUPT_MASK_FROM_ISR()        0;portSET_INTERRUPT_MASK()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    portCLEAR_INTERRUPT_MASK();(void)x
+
+extern void vPortEnterCritical( void );
+extern void vPortExitCritical( void );
+
+#define portDISABLE_INTERRUPTS()    portSET_INTERRUPT_MASK()
+#define portENABLE_INTERRUPTS()        portCLEAR_INTERRUPT_MASK()
+#define portENTER_CRITICAL()        vPortEnterCritical()
+#define portEXIT_CRITICAL()            vPortExitCritical()
+
+#if 0
+/* Critical section management. */
+
+/*
+ * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
+ * registers.  r0 is clobbered.
+ */
+extern void portSET_INTERRUPT_MASK( unsigned portBASE_TYPE );
+/*
+ * Set basepri back to 0 without effective other registers.
+ * r0 is clobbered.
+ */
+extern void portCLEAR_INTERRUPT_MASK( unsigned portBASE_TYPE );
+
+//extern void portCLEAR_INTERRUPT_MASK_FROM_ISR( unsigned portBASE_TYPE );
+
+extern void vPortEnterCritical( void );
+extern void vPortExitCritical( void );
+
+#define portSET_INTERRUPT_MASK_FROM_ISR()         portSET_INTERRUPT_MASK(0)
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    portCLEAR_INTERRUPT_MASK();
+#define portDISABLE_INTERRUPTS()    portSET_INTERRUPT_MASK()
+#define portENABLE_INTERRUPTS()        portCLEAR_INTERRUPT_MASK()
+#define portENTER_CRITICAL()        vPortEnterCritical()
+#define portEXIT_CRITICAL()            vPortExitCritical()
+#endif
+
+
+#endif
+/*-----------------------------------------------------------*/
+
+/* Task function macros as described on the FreeRTOS.org WEB site. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+
+#define portNOP()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTMACRO_H */
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/portable/MemMang/heap_1.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/portable/MemMang/heap_1.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,153 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+/*
+ * The simplest possible implementation of pvPortMalloc().  Note that this
+ * implementation does NOT allow allocated memory to be freed again.
+ *
+ * See heap_2.c and heap_3.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+
+#include <stdlib.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers.  That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/* Allocate the memory for the heap.  The struct is used to force byte
+alignment without using any non-portable code. */
+static union xRTOS_HEAP
+{
+    #if portBYTE_ALIGNMENT == 8
+        volatile portDOUBLE dDummy;
+    #else
+        volatile unsigned long ulDummy;
+    #endif    
+    unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
+} xHeap;
+
+static size_t xNextFreeByte = ( size_t ) 0;
+/*-----------------------------------------------------------*/
+
+void *pvPortMalloc( size_t xWantedSize )
+{
+void *pvReturn = NULL; 
+
+    /* Ensure that blocks are always aligned to the required number of bytes. */
+    #if portBYTE_ALIGNMENT != 1
+        if( xWantedSize & portBYTE_ALIGNMENT_MASK )
+        {
+            /* Byte alignment required. */
+            xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
+        }
+    #endif
+
+    vTaskSuspendAll();
+    {
+        /* Check there is enough room left for the allocation. */
+        if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&
+            ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte )    )/* Check for overflow. */
+        {
+            /* Return the next free byte then increment the index past this
+            block. */
+            pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );
+            xNextFreeByte += xWantedSize;            
+        }    
+    }
+    xTaskResumeAll();
+    
+    #if( configUSE_MALLOC_FAILED_HOOK == 1 )
+    {
+        if( pvReturn == NULL )
+        {
+            extern void vApplicationMallocFailedHook( void );
+            vApplicationMallocFailedHook();
+        }
+    }
+    #endif    
+
+    return pvReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vPortFree( void *pv )
+{
+    /* Memory cannot be freed using this scheme.  See heap_2.c and heap_3.c 
+    for alternative implementations, and the memory management pages of 
+    http://www.FreeRTOS.org for more information. */
+    ( void ) pv;
+}
+/*-----------------------------------------------------------*/
+
+void vPortInitialiseBlocks( void )
+{
+    /* Only required when static memory is not cleared. */
+    xNextFreeByte = ( size_t ) 0;
+}
+/*-----------------------------------------------------------*/
+
+size_t xPortGetFreeHeapSize( void )
+{
+    return ( configTOTAL_HEAP_SIZE - xNextFreeByte );
+}
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/queue.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/queue.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,1541 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers.  That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "croutine.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+/* Constants used with the cRxLock and cTxLock structure members. */
+#define queueUNLOCKED                    ( ( signed portBASE_TYPE ) -1 )
+#define queueLOCKED_UNMODIFIED            ( ( signed portBASE_TYPE ) 0 )
+
+#define queueERRONEOUS_UNBLOCK            ( -1 )
+
+/* For internal use only. */
+#define    queueSEND_TO_BACK                ( 0 )
+#define    queueSEND_TO_FRONT                ( 1 )
+
+/* Effectively make a union out of the xQUEUE structure. */
+#define pxMutexHolder                    pcTail
+#define uxQueueType                        pcHead
+#define uxRecursiveCallCount            pcReadFrom
+#define queueQUEUE_IS_MUTEX                NULL
+
+/* Semaphores do not actually store or copy data, so have an items size of
+zero. */
+#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
+#define queueDONT_BLOCK                     ( ( portTickType ) 0 )
+#define queueMUTEX_GIVE_BLOCK_TIME         ( ( portTickType ) 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Definition of the queue used by the scheduler.
+ * Items are queued by copy, not reference.
+ */
+typedef struct QueueDefinition
+{
+    signed char *pcHead;                /*< Points to the beginning of the queue storage area. */
+    signed char *pcTail;                /*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
+
+    signed char *pcWriteTo;                /*< Points to the free next place in the storage area. */
+    signed char *pcReadFrom;            /*< Points to the last place that a queued item was read from. */
+
+    xList xTasksWaitingToSend;                /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */
+    xList xTasksWaitingToReceive;            /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */
+
+    volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
+    unsigned portBASE_TYPE uxLength;        /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
+    unsigned portBASE_TYPE uxItemSize;        /*< The size of each items that the queue will hold. */
+
+    signed portBASE_TYPE xRxLock;            /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */
+    signed portBASE_TYPE xTxLock;            /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */
+
+} xQUEUE;
+/*-----------------------------------------------------------*/
+
+/*
+ * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
+ * To keep the definition private the API header file defines it as a
+ * pointer to void.
+ */
+typedef xQUEUE * xQueueHandle;
+
+#if 0
+/*
+ * Prototypes for public functions are included here so we don't have to
+ * include the API header file (as it defines xQueueHandle differently).  These
+ * functions are documented in the API header file.
+ */
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
+xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION;
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+
+/*
+ * Co-routine queue functions differ from task queue functions.  Co-routines are
+ * an optional component.
+ */
+#if configUSE_CO_ROUTINES == 1
+    signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;
+    signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
+    signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
+    signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
+#endif
+#else
+/*
+ * Prototypes for public functions are included here so we don't have to
+ * include the API header file (as it defines xQueueHandle differently).  These
+ * functions are documented in the API header file.
+ */
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue );
+void vQueueDelete( xQueueHandle xQueue );
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
+xQueueHandle xQueueCreateMutex( void );
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );
+
+/*
+ * Co-routine queue functions differ from task queue functions.  Co-routines are
+ * an optional component.
+ */
+#if configUSE_CO_ROUTINES == 1
+    signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
+    signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
+    signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );
+    signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
+#endif
+#endif
+/*
+ * The queue registry is just a means for kernel aware debuggers to locate
+ * queue structures.  It has no other purpose so is an optional component.
+ */
+//#if configQUEUE_REGISTRY_SIZE > 0
+
+    /* The type stored within the queue registry array.  This allows a name
+    to be assigned to each queue making kernel aware debugging a little
+    more user friendly. */
+    typedef struct QUEUE_REGISTRY_ITEM
+    {
+        signed char *pcQueueName;
+        xQueueHandle xHandle;
+    } xQueueRegistryItem;
+
+    /* The queue registry is simply an array of xQueueRegistryItem structures.
+    The pcQueueName member of a structure being NULL is indicative of the
+    array position being vacant. */
+    xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
+
+    /* Removes a queue from the registry by simply setting the pcQueueName
+    member to NULL. */
+    static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
+    //void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;
+    extern void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName );
+//#endif
+
+/*
+ * Unlocks a queue locked by a call to prvLockQueue.  Locking a queue does not
+ * prevent an ISR from adding or removing items to the queue, but does prevent
+ * an ISR from removing tasks from the queue event lists.  If an ISR finds a
+ * queue is locked it will instead increment the appropriate queue lock count
+ * to indicate that a task may require unblocking.  When the queue in unlocked
+ * these lock counts are inspected, and the appropriate action taken.
+ */
+static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+
+/*
+ * Uses a critical section to determine if there is any data in a queue.
+ *
+ * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
+ */
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+
+/*
+ * Uses a critical section to determine if there is any space in a queue.
+ *
+ * @return pdTRUE if there is no space, otherwise pdFALSE;
+ */
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
+
+/*
+ * Copies an item into the queue, either at the front of the queue or the
+ * back of the queue.
+ */
+#if 0
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
+#else
+void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition );
+#endif
+/*
+ * Copies an item out of a queue.
+ */
+// Modified by  Kenji Arai / JH1PJL, October 31st,2010
+#if 0
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
+#else
+void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer );
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro to mark a queue as locked.  Locking a queue prevents an ISR from
+ * accessing the queue event lists.
+ */
+#define prvLockQueue( pxQueue )                            \
+{                                                        \
+    taskENTER_CRITICAL();                                \
+    {                                                    \
+        if( pxQueue->xRxLock == queueUNLOCKED )            \
+        {                                                \
+            pxQueue->xRxLock = queueLOCKED_UNMODIFIED;    \
+        }                                                \
+        if( pxQueue->xTxLock == queueUNLOCKED )            \
+        {                                                \
+            pxQueue->xTxLock = queueLOCKED_UNMODIFIED;    \
+        }                                                \
+    }                                                    \
+    taskEXIT_CRITICAL();                                \
+}
+/*-----------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+/*-----------------------------------------------------------
+ * PUBLIC QUEUE MANAGEMENT API documented in queue.h
+ *----------------------------------------------------------*/
+
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )
+{
+xQUEUE *pxNewQueue;
+size_t xQueueSizeInBytes;
+
+    /* Allocate the new queue structure. */
+    if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
+    {
+        pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
+        if( pxNewQueue != NULL )
+        {
+            /* Create the list of pointers to queue items.  The queue is one byte
+            longer than asked for to make wrap checking easier/faster. */
+            xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
+
+            pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
+            if( pxNewQueue->pcHead != NULL )
+            {
+                /* Initialise the queue members as described above where the
+                queue type is defined. */
+                pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
+                pxNewQueue->uxMessagesWaiting = 0;
+                pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
+                pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
+                pxNewQueue->uxLength = uxQueueLength;
+                pxNewQueue->uxItemSize = uxItemSize;
+                pxNewQueue->xRxLock = queueUNLOCKED;
+                pxNewQueue->xTxLock = queueUNLOCKED;
+
+                /* Likewise ensure the event queues start with the correct state. */
+                vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
+                vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
+
+                traceQUEUE_CREATE( pxNewQueue );
+                return  pxNewQueue;
+            }
+            else
+            {
+                traceQUEUE_CREATE_FAILED();
+                vPortFree( pxNewQueue );
+            }
+        }
+    }
+
+    /* Will only reach here if we could not allocate enough memory or no memory
+    was required. */
+    return NULL;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+    xQueueHandle xQueueCreateMutex( void )
+    {
+    xQUEUE *pxNewQueue;
+
+        /* Allocate the new queue structure. */
+        pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
+        if( pxNewQueue != NULL )
+        {
+            /* Information required for priority inheritance. */
+            pxNewQueue->pxMutexHolder = NULL;
+            pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
+
+            /* Queues used as a mutex no data is actually copied into or out
+            of the queue. */
+            pxNewQueue->pcWriteTo = NULL;
+            pxNewQueue->pcReadFrom = NULL;
+
+            /* Each mutex has a length of 1 (like a binary semaphore) and
+            an item size of 0 as nothing is actually copied into or out
+            of the mutex. */
+            pxNewQueue->uxMessagesWaiting = 0;
+            pxNewQueue->uxLength = 1;
+            pxNewQueue->uxItemSize = 0;
+            pxNewQueue->xRxLock = queueUNLOCKED;
+            pxNewQueue->xTxLock = queueUNLOCKED;
+
+            /* Ensure the event queues start with the correct state. */
+            vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
+            vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
+
+            /* Start with the semaphore in the expected state. */
+            xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );
+
+            traceCREATE_MUTEX( pxNewQueue );
+        }
+        else
+        {
+            traceCREATE_MUTEX_FAILED();
+        }
+
+        return pxNewQueue;
+    }
+
+#endif /* configUSE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_RECURSIVE_MUTEXES == 1
+
+    portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )
+    {
+    portBASE_TYPE xReturn;
+
+        /* If this is the task that holds the mutex then pxMutexHolder will not
+        change outside of this task.  If this task does not hold the mutex then
+        pxMutexHolder can never coincidentally equal the tasks handle, and as
+        this is the only condition we are interested in it does not matter if
+        pxMutexHolder is accessed simultaneously by another task.  Therefore no
+        mutual exclusion is required to test the pxMutexHolder variable. */
+        if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
+        {
+            traceGIVE_MUTEX_RECURSIVE( pxMutex );
+
+            /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
+            the task handle, therefore no underflow check is required.  Also,
+            uxRecursiveCallCount is only modified by the mutex holder, and as
+            there can only be one, no mutual exclusion is required to modify the
+            uxRecursiveCallCount member. */
+            ( pxMutex->uxRecursiveCallCount )--;
+
+            /* Have we unwound the call count? */
+            if( pxMutex->uxRecursiveCallCount == 0 )
+            {
+                /* Return the mutex.  This will automatically unblock any other
+                task that might be waiting to access the mutex. */
+                xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
+            }
+
+            xReturn = pdPASS;
+        }
+        else
+        {
+            /* We cannot give the mutex because we are not the holder. */
+            xReturn = pdFAIL;
+
+            traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );
+        }
+
+        return xReturn;
+    }
+
+#endif /* configUSE_RECURSIVE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_RECURSIVE_MUTEXES == 1
+
+    portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )
+    {
+    portBASE_TYPE xReturn;
+
+        /* Comments regarding mutual exclusion as per those within
+        xQueueGiveMutexRecursive(). */
+
+        traceTAKE_MUTEX_RECURSIVE( pxMutex );
+
+        if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
+        {
+            ( pxMutex->uxRecursiveCallCount )++;
+            xReturn = pdPASS;
+        }
+        else
+        {
+            xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );
+
+            /* pdPASS will only be returned if we successfully obtained the mutex,
+            we may have blocked to reach here. */
+            if( xReturn == pdPASS )
+            {
+                ( pxMutex->uxRecursiveCallCount )++;
+            }
+        }
+
+        return xReturn;
+    }
+
+#endif /* configUSE_RECURSIVE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_COUNTING_SEMAPHORES == 1
+
+    xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
+    {
+    xQueueHandle pxHandle;
+
+        pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );
+
+        if( pxHandle != NULL )
+        {
+            pxHandle->uxMessagesWaiting = uxInitialCount;
+
+            traceCREATE_COUNTING_SEMAPHORE();
+        }
+        else
+        {
+            traceCREATE_COUNTING_SEMAPHORE_FAILED();
+        }
+
+        return pxHandle;
+    }
+
+#endif /* configUSE_COUNTING_SEMAPHORES */
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
+{
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+xTimeOutType xTimeOut;
+
+    /* This function relaxes the coding standard somewhat to allow return
+    statements within the function itself.  This is done in the interest
+    of execution time efficiency. */
+    for( ;; )
+    {
+        taskENTER_CRITICAL();
+        {
+            /* Is there room on the queue now?  To be running we must be
+            the highest priority task wanting to access the queue. */
+            if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+            {
+                traceQUEUE_SEND( pxQueue );
+                prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
+
+                /* If there was a task waiting for data to arrive on the
+                queue then unblock it now. */
+                if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+                {
+                    if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
+                    {
+                        /* The unblocked task has a priority higher than
+                        our own so yield immediately.  Yes it is ok to do
+                        this from within the critical section - the kernel
+                        takes care of that. */
+                        portYIELD_WITHIN_API();
+                    }
+                }
+
+                taskEXIT_CRITICAL();
+
+                /* Return to the original privilege level before exiting the
+                function. */
+                return pdPASS;
+            }
+            else
+            {
+                if( xTicksToWait == ( portTickType ) 0 )
+                {
+                    /* The queue was full and no block time is specified (or
+                    the block time has expired) so leave now. */
+                    taskEXIT_CRITICAL();
+
+                    /* Return to the original privilege level before exiting
+                    the function. */
+                    traceQUEUE_SEND_FAILED( pxQueue );
+                    return errQUEUE_FULL;
+                }
+                else if( xEntryTimeSet == pdFALSE )
+                {
+                    /* The queue was full and a block time was specified so
+                    configure the timeout structure. */
+                    vTaskSetTimeOutState( &xTimeOut );
+                    xEntryTimeSet = pdTRUE;
+                }
+            }
+        }
+        taskEXIT_CRITICAL();
+
+        /* Interrupts and other tasks can send to and receive from the queue
+        now the critical section has been exited. */
+
+        vTaskSuspendAll();
+        prvLockQueue( pxQueue );
+
+        /* Update the timeout state to see if it has expired yet. */
+        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
+        {
+            if( prvIsQueueFull( pxQueue ) )
+            {
+                traceBLOCKING_ON_QUEUE_SEND( pxQueue );
+                vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
+
+                /* Unlocking the queue means queue events can effect the
+                event list.  It is possible    that interrupts occurring now
+                remove this task from the event    list again - but as the
+                scheduler is suspended the task will go onto the pending
+                ready last instead of the actual ready list. */
+                prvUnlockQueue( pxQueue );
+
+                /* Resuming the scheduler will move tasks from the pending
+                ready list into the ready list - so it is feasible that this
+                task is already in a ready list before it yields - in which
+                case the yield will not cause a context switch unless there
+                is also a higher priority task in the pending ready list. */
+                if( !xTaskResumeAll() )
+                {
+                    portYIELD_WITHIN_API();
+                }
+            }
+            else
+            {
+                /* Try again. */
+                prvUnlockQueue( pxQueue );
+                ( void ) xTaskResumeAll();
+            }
+        }
+        else
+        {
+            /* The timeout has expired. */
+            prvUnlockQueue( pxQueue );
+            ( void ) xTaskResumeAll();
+
+            /* Return to the original privilege level before exiting the
+            function. */
+            traceQUEUE_SEND_FAILED( pxQueue );
+            return errQUEUE_FULL;
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_ALTERNATIVE_API == 1
+
+    signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
+    {
+    signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+    xTimeOutType xTimeOut;
+
+        for( ;; )
+        {
+            taskENTER_CRITICAL();
+            {
+                /* Is there room on the queue now?  To be running we must be
+                the highest priority task wanting to access the queue. */
+                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+                {
+                    traceQUEUE_SEND( pxQueue );
+                    prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
+
+                    /* If there was a task waiting for data to arrive on the
+                    queue then unblock it now. */
+                    if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+                    {
+                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
+                        {
+                            /* The unblocked task has a priority higher than
+                            our own so yield immediately. */
+                            portYIELD_WITHIN_API();
+                        }
+                    }
+
+                    taskEXIT_CRITICAL();
+                    return pdPASS;
+                }
+                else
+                {
+                    if( xTicksToWait == ( portTickType ) 0 )
+                    {
+                        taskEXIT_CRITICAL();
+                        return errQUEUE_FULL;
+                    }
+                    else if( xEntryTimeSet == pdFALSE )
+                    {
+                        vTaskSetTimeOutState( &xTimeOut );
+                        xEntryTimeSet = pdTRUE;
+                    }
+                }
+            }
+            taskEXIT_CRITICAL();
+
+            taskENTER_CRITICAL();
+            {
+                if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
+                {
+                    if( prvIsQueueFull( pxQueue ) )
+                    {
+                        traceBLOCKING_ON_QUEUE_SEND( pxQueue );
+                        vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
+                        portYIELD_WITHIN_API();
+                    }
+                }
+                else
+                {
+                    taskEXIT_CRITICAL();
+                    traceQUEUE_SEND_FAILED( pxQueue );
+                    return errQUEUE_FULL;
+                }
+            }
+            taskEXIT_CRITICAL();
+        }
+    }
+
+#endif /* configUSE_ALTERNATIVE_API */
+/*-----------------------------------------------------------*/
+
+#if configUSE_ALTERNATIVE_API == 1
+
+    signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
+    {
+    signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+    xTimeOutType xTimeOut;
+    signed char *pcOriginalReadPosition;
+
+        for( ;; )
+        {
+            taskENTER_CRITICAL();
+            {
+                if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+                {
+                    /* Remember our read position in case we are just peeking. */
+                    pcOriginalReadPosition = pxQueue->pcReadFrom;
+
+                    prvCopyDataFromQueue( pxQueue, pvBuffer );
+
+                    if( xJustPeeking == pdFALSE )
+                    {
+                        traceQUEUE_RECEIVE( pxQueue );
+
+                        /* We are actually removing data. */
+                        --( pxQueue->uxMessagesWaiting );
+
+                        #if ( configUSE_MUTEXES == 1 )
+                        {
+                            if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
+                            {
+                                /* Record the information required to implement
+                                priority inheritance should it become necessary. */
+                                pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
+                            }
+                        }
+                        #endif
+
+                        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
+                        {
+                            if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
+                            {
+                                portYIELD_WITHIN_API();
+                            }
+                        }
+                    }
+                    else
+                    {
+                        traceQUEUE_PEEK( pxQueue );
+
+                        /* We are not removing the data, so reset our read
+                        pointer. */
+                        pxQueue->pcReadFrom = pcOriginalReadPosition;
+
+                        /* The data is being left in the queue, so see if there are
+                        any other tasks waiting for the data. */
+                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+                        {
+                            /* Tasks that are removed from the event list will get added to
+                            the pending ready list as the scheduler is still suspended. */
+                            if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                            {
+                                /* The task waiting has a higher priority than this task. */
+                                portYIELD_WITHIN_API();
+                            }
+                        }
+
+                    }
+
+                    taskEXIT_CRITICAL();
+                    return pdPASS;
+                }
+                else
+                {
+                    if( xTicksToWait == ( portTickType ) 0 )
+                    {
+                        taskEXIT_CRITICAL();
+                        traceQUEUE_RECEIVE_FAILED( pxQueue );
+                        return errQUEUE_EMPTY;
+                    }
+                    else if( xEntryTimeSet == pdFALSE )
+                    {
+                        vTaskSetTimeOutState( &xTimeOut );
+                        xEntryTimeSet = pdTRUE;
+                    }
+                }
+            }
+            taskEXIT_CRITICAL();
+
+            taskENTER_CRITICAL();
+            {
+                if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
+                {
+                    if( prvIsQueueEmpty( pxQueue ) )
+                    {
+                        traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
+
+                        #if ( configUSE_MUTEXES == 1 )
+                        {
+                            if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
+                            {
+                                portENTER_CRITICAL();
+                                    vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
+                                portEXIT_CRITICAL();
+                            }
+                        }
+                        #endif
+
+                        vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
+                        portYIELD_WITHIN_API();
+                    }
+                }
+                else
+                {
+                    taskEXIT_CRITICAL();
+                    traceQUEUE_RECEIVE_FAILED( pxQueue );
+                    return errQUEUE_EMPTY;
+                }
+            }
+            taskEXIT_CRITICAL();
+        }
+    }
+
+
+#endif /* configUSE_ALTERNATIVE_API */
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+// move to port_asm.c
+#if 0
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )
+{
+signed portBASE_TYPE xReturn;
+unsigned portBASE_TYPE uxSavedInterruptStatus;
+
+    /* Similar to xQueueGenericSend, except we don't block if there is no room
+    in the queue.  Also we don't directly wake a task that was blocked on a
+    queue read, instead we return a flag to say whether a context switch is
+    required or not (i.e. has a task with a higher priority than us been woken
+    by this    post). */
+    uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
+    {
+        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+        {
+            traceQUEUE_SEND_FROM_ISR( pxQueue );
+
+            prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
+
+            /* If the queue is locked we do not alter the event list.  This will
+            be done when the queue is unlocked later. */
+            if( pxQueue->xTxLock == queueUNLOCKED )
+            {
+                if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+                {
+                    if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                    {
+                        /* The task waiting has a higher priority so record that a
+                        context    switch is required. */
+                        *pxHigherPriorityTaskWoken = pdTRUE;
+                    }
+                }
+            }
+            else
+            {
+                /* Increment the lock count so the task that unlocks the queue
+                knows that data was posted while it was locked. */
+                ++( pxQueue->xTxLock );
+            }
+
+            xReturn = pdPASS;
+        }
+        else
+        {
+            traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );
+            xReturn = errQUEUE_FULL;
+        }
+    }
+    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+#endif
+
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
+{
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+xTimeOutType xTimeOut;
+signed char *pcOriginalReadPosition;
+
+    /* This function relaxes the coding standard somewhat to allow return
+    statements within the function itself.  This is done in the interest
+    of execution time efficiency. */
+
+    for( ;; )
+    {
+        taskENTER_CRITICAL();
+        {
+            /* Is there data in the queue now?  To be running we must be
+            the highest priority task wanting to access the queue. */
+            if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+            {
+                /* Remember our read position in case we are just peeking. */
+                pcOriginalReadPosition = pxQueue->pcReadFrom;
+
+                prvCopyDataFromQueue( pxQueue, pvBuffer );
+
+                if( xJustPeeking == pdFALSE )
+                {
+                    traceQUEUE_RECEIVE( pxQueue );
+
+                    /* We are actually removing data. */
+                    --( pxQueue->uxMessagesWaiting );
+
+                    #if ( configUSE_MUTEXES == 1 )
+                    {
+                        if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
+                        {
+                            /* Record the information required to implement
+                            priority inheritance should it become necessary. */
+                            // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+                            pxQueue->pxMutexHolder = (signed char *) xTaskGetCurrentTaskHandle();
+                        }
+                    }
+                    #endif
+
+                    if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
+                    {
+                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
+                        {
+                            portYIELD_WITHIN_API();
+                        }
+                    }
+                }
+                else
+                {
+                    traceQUEUE_PEEK( pxQueue );
+
+                    /* We are not removing the data, so reset our read
+                    pointer. */
+                    pxQueue->pcReadFrom = pcOriginalReadPosition;
+
+                    /* The data is being left in the queue, so see if there are
+                    any other tasks waiting for the data. */
+                    if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+                    {
+                        /* Tasks that are removed from the event list will get added to
+                        the pending ready list as the scheduler is still suspended. */
+                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                        {
+                            /* The task waiting has a higher priority than this task. */
+                            portYIELD_WITHIN_API();
+                        }
+                    }
+
+                }
+
+                taskEXIT_CRITICAL();
+                return pdPASS;
+            }
+            else
+            {
+                if( xTicksToWait == ( portTickType ) 0 )
+                {
+                    /* The queue was empty and no block time is specified (or
+                    the block time has expired) so leave now. */
+                    taskEXIT_CRITICAL();
+                    traceQUEUE_RECEIVE_FAILED( pxQueue );
+                    return errQUEUE_EMPTY;
+                }
+                else if( xEntryTimeSet == pdFALSE )
+                {
+                    /* The queue was empty and a block time was specified so
+                    configure the timeout structure. */
+                    vTaskSetTimeOutState( &xTimeOut );
+                    xEntryTimeSet = pdTRUE;
+                }
+            }
+        }
+        taskEXIT_CRITICAL();
+
+        /* Interrupts and other tasks can send to and receive from the queue
+        now the critical section has been exited. */
+
+        vTaskSuspendAll();
+        prvLockQueue( pxQueue );
+
+        /* Update the timeout state to see if it has expired yet. */
+        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
+        {
+            if( prvIsQueueEmpty( pxQueue ) )
+            {
+                traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
+
+                #if ( configUSE_MUTEXES == 1 )
+                {
+                    if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
+                    {
+                        portENTER_CRITICAL();
+                        {
+                            // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+                            //vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
+                            vTaskPriorityInherit( ( xTaskHandle * ) pxQueue->pxMutexHolder );
+                        }
+                        portEXIT_CRITICAL();
+                    }
+                }
+                #endif
+
+                vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
+                prvUnlockQueue( pxQueue );
+                if( !xTaskResumeAll() )
+                {
+                    portYIELD_WITHIN_API();
+                }
+            }
+            else
+            {
+                /* Try again. */
+                prvUnlockQueue( pxQueue );
+                ( void ) xTaskResumeAll();
+            }
+        }
+        else
+        {
+            prvUnlockQueue( pxQueue );
+            ( void ) xTaskResumeAll();
+            traceQUEUE_RECEIVE_FAILED( pxQueue );
+            return errQUEUE_EMPTY;
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+// move to port_asm.c
+#if 0
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )
+{
+signed portBASE_TYPE xReturn;
+unsigned portBASE_TYPE uxSavedInterruptStatus;
+
+    uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
+    {
+        /* We cannot block from an ISR, so check there is data available. */
+        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+        {
+            traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
+
+            prvCopyDataFromQueue( pxQueue, pvBuffer );
+            --( pxQueue->uxMessagesWaiting );
+
+            /* If the queue is locked we will not modify the event list.  Instead
+            we update the lock count so the task that unlocks the queue will know
+            that an ISR has removed data while the queue was locked. */
+            if( pxQueue->xRxLock == queueUNLOCKED )
+            {
+                if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
+                {
+                    if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+                    {
+                        /* The task waiting has a higher priority than us so
+                        force a context switch. */
+                        *pxTaskWoken = pdTRUE;
+                    }
+                }
+            }
+            else
+            {
+                /* Increment the lock count so the task that unlocks the queue
+                knows that data was removed while it was locked. */
+                ++( pxQueue->xRxLock );
+            }
+
+            xReturn = pdPASS;
+        }
+        else
+        {
+            xReturn = pdFAIL;
+            traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );
+        }
+    }
+    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+#endif
+
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
+{
+unsigned portBASE_TYPE uxReturn;
+
+    taskENTER_CRITICAL();
+        uxReturn = pxQueue->uxMessagesWaiting;
+    taskEXIT_CRITICAL();
+
+    return uxReturn;
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )
+{
+unsigned portBASE_TYPE uxReturn;
+
+    uxReturn = pxQueue->uxMessagesWaiting;
+
+    return uxReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vQueueDelete( xQueueHandle pxQueue )
+{
+    traceQUEUE_DELETE( pxQueue );
+    vQueueUnregisterQueue( pxQueue );
+    vPortFree( pxQueue->pcHead );
+    vPortFree( pxQueue );
+}
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 31st,2010
+#if 0
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
+#else
+void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
+#endif
+{
+    if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
+    {
+        #if ( configUSE_MUTEXES == 1 )
+        {
+            if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
+            {
+                /* The mutex is no longer being held. */
+                // Modified by  Kenji Arai / JH1PJL, October 31st,2010
+                //vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
+                vTaskPriorityDisinherit( ( xTaskHandle * ) pxQueue->pxMutexHolder );
+                pxQueue->pxMutexHolder = NULL;
+            }
+        }
+        #endif
+    }
+    else if( xPosition == queueSEND_TO_BACK )
+    {
+        memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
+        pxQueue->pcWriteTo += pxQueue->uxItemSize;
+        if( pxQueue->pcWriteTo >= pxQueue->pcTail )
+        {
+            pxQueue->pcWriteTo = pxQueue->pcHead;
+        }
+    }
+    else
+    {
+        memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
+        pxQueue->pcReadFrom -= pxQueue->uxItemSize;
+        if( pxQueue->pcReadFrom < pxQueue->pcHead )
+        {
+            pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
+        }
+    }
+
+    ++( pxQueue->uxMessagesWaiting );
+}
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 31st,2010
+#if 0
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
+#else
+void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
+#endif
+{
+    if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
+    {
+        pxQueue->pcReadFrom += pxQueue->uxItemSize;
+        if( pxQueue->pcReadFrom >= pxQueue->pcTail )
+        {
+            pxQueue->pcReadFrom = pxQueue->pcHead;
+        }
+        memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+    }
+}
+/*-----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 31st,2010
+#if 0
+static void prvUnlockQueue( xQueueHandle pxQueue )
+#else
+void prvUnlockQueue( xQueueHandle pxQueue )
+#endif
+{
+    /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
+
+    /* The lock counts contains the number of extra data items placed or
+    removed from the queue while the queue was locked.  When a queue is
+    locked items can be added or removed, but the event lists cannot be
+    updated. */
+    taskENTER_CRITICAL();
+    {
+        /* See if data was added to the queue while it was locked. */
+        while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
+        {
+            /* Data was posted while the queue was locked.  Are any tasks
+            blocked waiting for data to become available? */
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+            {
+                /* Tasks that are removed from the event list will get added to
+                the pending ready list as the scheduler is still suspended. */
+                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                {
+                    /* The task waiting has a higher priority so record that a
+                    context    switch is required. */
+                    vTaskMissedYield();
+                }
+
+                --( pxQueue->xTxLock );
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        pxQueue->xTxLock = queueUNLOCKED;
+    }
+    taskEXIT_CRITICAL();
+
+    /* Do the same for the Rx lock. */
+    taskENTER_CRITICAL();
+    {
+        while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
+        {
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
+            {
+                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+                {
+                    vTaskMissedYield();
+                }
+
+                --( pxQueue->xRxLock );
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        pxQueue->xRxLock = queueUNLOCKED;
+    }
+    taskEXIT_CRITICAL();
+}
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )
+{
+signed portBASE_TYPE xReturn;
+
+    taskENTER_CRITICAL();
+        xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
+    taskEXIT_CRITICAL();
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )
+{
+signed portBASE_TYPE xReturn;
+
+    xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )
+{
+signed portBASE_TYPE xReturn;
+
+    taskENTER_CRITICAL();
+        xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
+    taskEXIT_CRITICAL();
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )
+{
+signed portBASE_TYPE xReturn;
+
+    xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
+{
+signed portBASE_TYPE xReturn;
+
+    /* If the queue is already full we may have to block.  A critical section
+    is required to prevent an interrupt removing something from the queue
+    between the check to see if the queue is full and blocking on the queue. */
+    portDISABLE_INTERRUPTS();
+    {
+        if( prvIsQueueFull( pxQueue ) )
+        {
+            /* The queue is full - do we want to block or just leave without
+            posting? */
+            if( xTicksToWait > ( portTickType ) 0 )
+            {
+                /* As this is called from a coroutine we cannot block directly, but
+                return indicating that we need to block. */
+                vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
+                portENABLE_INTERRUPTS();
+                return errQUEUE_BLOCKED;
+            }
+            else
+            {
+                portENABLE_INTERRUPTS();
+                return errQUEUE_FULL;
+            }
+        }
+    }
+    portENABLE_INTERRUPTS();
+
+    portNOP();
+
+    portDISABLE_INTERRUPTS();
+    {
+        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+        {
+            /* There is room in the queue, copy the data into the queue. */
+            prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
+            xReturn = pdPASS;
+
+            /* Were any co-routines waiting for data to become available? */
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+            {
+                /* In this instance the co-routine could be placed directly
+                into the ready list as we are within a critical section.
+                Instead the same pending ready list mechanism is used as if
+                the event were caused from within an interrupt. */
+                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                {
+                    /* The co-routine waiting has a higher priority so record
+                    that a yield might be appropriate. */
+                    xReturn = errQUEUE_YIELD;
+                }
+            }
+        }
+        else
+        {
+            xReturn = errQUEUE_FULL;
+        }
+    }
+    portENABLE_INTERRUPTS();
+
+    return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
+{
+signed portBASE_TYPE xReturn;
+
+    /* If the queue is already empty we may have to block.  A critical section
+    is required to prevent an interrupt adding something to the queue
+    between the check to see if the queue is empty and blocking on the queue. */
+    portDISABLE_INTERRUPTS();
+    {
+        if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
+        {
+            /* There are no messages in the queue, do we want to block or just
+            leave with nothing? */
+            if( xTicksToWait > ( portTickType ) 0 )
+            {
+                /* As this is a co-routine we cannot block directly, but return
+                indicating that we need to block. */
+                vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
+                portENABLE_INTERRUPTS();
+                return errQUEUE_BLOCKED;
+            }
+            else
+            {
+                portENABLE_INTERRUPTS();
+                return errQUEUE_FULL;
+            }
+        }
+    }
+    portENABLE_INTERRUPTS();
+
+    portNOP();
+
+    portDISABLE_INTERRUPTS();
+    {
+        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+        {
+            /* Data is available from the queue. */
+            pxQueue->pcReadFrom += pxQueue->uxItemSize;
+            if( pxQueue->pcReadFrom >= pxQueue->pcTail )
+            {
+                pxQueue->pcReadFrom = pxQueue->pcHead;
+            }
+            --( pxQueue->uxMessagesWaiting );
+            memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+
+            xReturn = pdPASS;
+
+            /* Were any co-routines waiting for space to become available? */
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
+            {
+                /* In this instance the co-routine could be placed directly
+                into the ready list as we are within a critical section.
+                Instead the same pending ready list mechanism is used as if
+                the event were caused from within an interrupt. */
+                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+                {
+                    xReturn = errQUEUE_YIELD;
+                }
+            }
+        }
+        else
+        {
+            xReturn = pdFAIL;
+        }
+    }
+    portENABLE_INTERRUPTS();
+
+    return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
+{
+    /* Cannot block within an ISR so if there is no space on the queue then
+    exit without doing anything. */
+    if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+    {
+        prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
+
+        /* We only want to wake one co-routine per ISR, so check that a
+        co-routine has not already been woken. */
+        if( !xCoRoutinePreviouslyWoken )
+        {
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
+            {
+                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+                {
+                    return pdTRUE;
+                }
+            }
+        }
+    }
+
+    return xCoRoutinePreviouslyWoken;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
+{
+signed portBASE_TYPE xReturn;
+
+    /* We cannot block from an ISR, so check there is data available. If
+    not then just leave without doing anything. */
+    if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+    {
+        /* Copy the data from the queue. */
+        pxQueue->pcReadFrom += pxQueue->uxItemSize;
+        if( pxQueue->pcReadFrom >= pxQueue->pcTail )
+        {
+            pxQueue->pcReadFrom = pxQueue->pcHead;
+        }
+        --( pxQueue->uxMessagesWaiting );
+        memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+
+        if( !( *pxCoRoutineWoken ) )
+        {
+            if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
+            {
+                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+                {
+                    *pxCoRoutineWoken = pdTRUE;
+                }
+            }
+        }
+
+        xReturn = pdPASS;
+    }
+    else
+    {
+        xReturn = pdFAIL;
+    }
+
+    return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+//#if configQUEUE_REGISTRY_SIZE > 0
+
+    void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
+    {
+    unsigned portBASE_TYPE ux;
+
+        /* See if there is an empty space in the registry.  A NULL name denotes
+        a free slot. */
+        for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
+        {
+            if( xQueueRegistry[ ux ].pcQueueName == NULL )
+            {
+                /* Store the information on this queue. */
+                xQueueRegistry[ ux ].pcQueueName = pcQueueName;
+                xQueueRegistry[ ux ].xHandle = xQueue;
+                break;
+            }
+        }
+    }
+
+//#endif
+    /*-----------------------------------------------------------*/
+
+#if configQUEUE_REGISTRY_SIZE > 0
+
+    static void vQueueUnregisterQueue( xQueueHandle xQueue )
+    {
+    unsigned portBASE_TYPE ux;
+
+        /* See if the handle of the queue being unregistered in actually in the
+        registry. */
+        for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
+        {
+            if( xQueueRegistry[ ux ].xHandle == xQueue )
+            {
+                /* Set the name to NULL to show that this slot if free again. */
+                xQueueRegistry[ ux ].pcQueueName = NULL;
+                break;
+            }
+        }
+
+    }
+
+#endif
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOS/Source/tasks.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOS/Source/tasks.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,2340 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers.  That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "StackMacros.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#if 0
+/*
+ * Macro to define the amount of stack available to the idle task.
+ */
+#define tskIDLE_STACK_SIZE    configMINIMAL_STACK_SIZE
+#endif
+
+/*
+ * Task control block.  A task control block (TCB) is allocated to each task,
+ * and stores the context of the task.
+ */
+typedef struct tskTaskControlBlock
+{
+    volatile portSTACK_TYPE    *pxTopOfStack;        /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
+
+    #if ( portUSING_MPU_WRAPPERS == 1 )
+        xMPU_SETTINGS xMPUSettings;                /*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */
+    #endif    
+    
+    xListItem                xGenericListItem;    /*< List item used to place the TCB in ready and blocked queues. */
+    xListItem                xEventListItem;        /*< List item used to place the TCB in event lists. */
+    unsigned portBASE_TYPE    uxPriority;            /*< The priority of the task where 0 is the lowest priority. */
+    portSTACK_TYPE            *pxStack;            /*< Points to the start of the stack. */
+    signed char                pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */
+
+    #if ( portSTACK_GROWTH > 0 )
+        portSTACK_TYPE *pxEndOfStack;            /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */
+    #endif
+
+    #if ( portCRITICAL_NESTING_IN_TCB == 1 )
+        unsigned portBASE_TYPE uxCriticalNesting;
+    #endif
+
+    #if ( configUSE_TRACE_FACILITY == 1 )
+        unsigned portBASE_TYPE    uxTCBNumber;    /*< This is used for tracing the scheduler and making debugging easier only. */
+    #endif
+
+    #if ( configUSE_MUTEXES == 1 )
+        unsigned portBASE_TYPE uxBasePriority;    /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
+    #endif
+
+    #if ( configUSE_APPLICATION_TASK_TAG == 1 )
+        pdTASK_HOOK_CODE pxTaskTag;
+    #endif
+
+    #if ( configGENERATE_RUN_TIME_STATS == 1 )
+        unsigned long ulRunTimeCounter;        /*< Used for calculating how much CPU time each task is utilising. */
+    #endif
+
+} tskTCB;
+
+
+/*
+ * Some kernel aware debuggers require data to be viewed to be global, rather
+ * than file scope.
+ */
+#ifdef portREMOVE_STATIC_QUALIFIER
+    #define static
+#endif
+
+/*lint -e956 */
+PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;
+
+/* Lists for ready and blocked tasks. --------------------*/
+
+PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ];    /*< Prioritised ready tasks. */
+PRIVILEGED_DATA static xList xDelayedTaskList1;                            /*< Delayed tasks. */
+PRIVILEGED_DATA static xList xDelayedTaskList2;                            /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
+PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ;                /*< Points to the delayed task list currently being used. */
+PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList;        /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
+PRIVILEGED_DATA static xList xPendingReadyList;                            /*< Tasks that have been readied while the scheduler was suspended.  They will be moved to the ready queue when the scheduler is resumed. */
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+    PRIVILEGED_DATA static volatile xList xTasksWaitingTermination;        /*< Tasks that have been deleted - but the their memory not yet freed. */
+    PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0;
+
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+    PRIVILEGED_DATA static xList xSuspendedTaskList;                    /*< Tasks that are currently suspended. */
+
+#endif
+
+/* File private variables. --------------------------------*/
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks     = ( unsigned portBASE_TYPE ) 0;
+PRIVILEGED_DATA static volatile portTickType xTickCount                         = ( portTickType ) 0;
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority                     = tskIDLE_PRIORITY;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority         = tskIDLE_PRIORITY;
+PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning             = pdFALSE;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended         = ( unsigned portBASE_TYPE ) pdFALSE;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks             = ( unsigned portBASE_TYPE ) 0;
+PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield                         = ( portBASE_TYPE ) pdFALSE;
+PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows                     = ( portBASE_TYPE ) 0;
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber                         = ( unsigned portBASE_TYPE ) 0;
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+    PRIVILEGED_DATA static char pcStatsString[ 50 ] ;
+    PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL;    /*< Holds the value of a timer/counter the last time a task was switched in. */
+    static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION;
+
+#endif
+
+/* Debugging and trace facilities private variables and macros. ------------*/
+
+/*
+ * The value used to fill the stack of a task when the task is created.  This
+ * is used purely for checking the high water mark for tasks.
+ */
+#define tskSTACK_FILL_BYTE    ( 0xa5 )
+
+/*
+ * Macros used by vListTask to indicate which state a task is in.
+ */
+#define tskBLOCKED_CHAR        ( ( signed char ) 'B' )
+#define tskREADY_CHAR        ( ( signed char ) 'R' )
+#define tskDELETED_CHAR        ( ( signed char ) 'D' )
+#define tskSUSPENDED_CHAR    ( ( signed char ) 'S' )
+
+/*
+ * Macros and private variables used by the trace facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    #define tskSIZE_OF_EACH_TRACE_LINE            ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) )
+    PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer;
+    PRIVILEGED_DATA static signed char *pcTraceBufferStart;
+    PRIVILEGED_DATA static signed char *pcTraceBufferEnd;
+    PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;
+    static unsigned portBASE_TYPE uxPreviousTask = 255;
+    PRIVILEGED_DATA static char pcStatusString[ 50 ];
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro that writes a trace of scheduler activity to a buffer.  This trace
+ * shows which task is running when and is very useful as a debugging tool.
+ * As this macro is called each context switch it is a good idea to undefine
+ * it if not using the facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    #define vWriteTraceToBuffer()                                                                    \
+    {                                                                                                \
+        if( xTracing )                                                                                \
+        {                                                                                            \
+            if( uxPreviousTask != pxCurrentTCB->uxTCBNumber )                                        \
+            {                                                                                        \
+                if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd )                \
+                {                                                                                    \
+                    uxPreviousTask = pxCurrentTCB->uxTCBNumber;                                        \
+                    *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount;        \
+                    pcTraceBuffer += sizeof( unsigned long );                                    \
+                    *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask;    \
+                    pcTraceBuffer += sizeof( unsigned long );                                    \
+                }                                                                                    \
+                else                                                                                \
+                {                                                                                    \
+                    xTracing = pdFALSE;                                                                \
+                }                                                                                    \
+            }                                                                                        \
+        }                                                                                            \
+    }
+
+#else
+
+    #define vWriteTraceToBuffer()
+
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * Place the task represented by pxTCB into the appropriate ready queue for
+ * the task.  It is inserted at the end of the list.  One quirk of this is
+ * that if the task being inserted is at the same priority as the currently
+ * executing task, then it will only be rescheduled after the currently
+ * executing task has been rescheduled.
+ */
+#define prvAddTaskToReadyQueue( pxTCB )                                                                            \
+{                                                                                                                \
+    if( pxTCB->uxPriority > uxTopReadyPriority )                                                                \
+    {                                                                                                            \
+        uxTopReadyPriority = pxTCB->uxPriority;                                                                    \
+    }                                                                                                            \
+    vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) );    \
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro that looks at the list of tasks that are currently delayed to see if
+ * any require waking.
+ *
+ * Tasks are stored in the queue in the order of their wake time - meaning
+ * once one tasks has been found whose timer has not expired we need not look
+ * any further down the list.
+ */
+#define prvCheckDelayedTasks()                                                                                        \
+{                                                                                                                    \
+register tskTCB *pxTCB;                                                                                                \
+                                                                                                                    \
+    while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL )                        \
+    {                                                                                                                \
+        if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) )                                    \
+        {                                                                                                            \
+            break;                                                                                                    \
+        }                                                                                                            \
+        vListRemove( &( pxTCB->xGenericListItem ) );                                                                \
+        /* Is the task waiting on an event also? */                                                                    \
+        if( pxTCB->xEventListItem.pvContainer )                                                                        \
+        {                                                                                                            \
+            vListRemove( &( pxTCB->xEventListItem ) );                                                                \
+        }                                                                                                            \
+        prvAddTaskToReadyQueue( pxTCB );                                                                            \
+    }                                                                                                                \
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Several functions take an xTaskHandle parameter that can optionally be NULL,
+ * where NULL is used to indicate that the handle of the currently executing
+ * task should be used in place of the parameter.  This macro simply checks to
+ * see if the parameter is NULL and returns a pointer to the appropriate TCB.
+ */
+#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle )
+
+
+/* File private functions. --------------------------------*/
+
+/*
+ * Utility to ready a TCB for a given task.  Mainly just copies the parameters
+ * into the TCB structure.
+ */
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
+
+/*
+ * Utility to ready all the lists used by the scheduler.  This is called
+ * automatically upon the creation of the first task.
+ */
+static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * The idle task, which as all tasks is implemented as a never ending loop.
+ * The idle task is automatically created and added to the ready lists upon
+ * creation of the first user task.
+ *
+ * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
+ * language extensions.  The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+//static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
+#ifdef __cplusplus
+extern "C" {
+#endif
+    static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
+#ifdef __cplusplus
+}
+#endif
+/*
+ * Utility to free all memory allocated by the scheduler to hold a TCB,
+ * including the stack pointed to by the TCB.
+ *
+ * This does not free memory allocated by the task itself (i.e. memory
+ * allocated by calls to pvPortMalloc from within the tasks application code).
+ */
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+
+    static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION;
+
+#endif
+
+/*
+ * Used only by the idle task.  This checks to see if anything has been placed
+ * in the list of tasks waiting to be deleted.  If so the task is cleaned up
+ * and its TCB deleted.
+ */
+static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
+
+/*
+ * Allocates memory from the heap for a TCB and associated stack.  Checks the
+ * allocation was successful.
+ */
+static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION;
+
+/*
+ * Called from vTaskList.  vListTasks details all the tasks currently under
+ * control of the scheduler.  The tasks may be in one of a number of lists.
+ * prvListTaskWithinSingleList accepts a list and details the tasks from
+ * within just that list.
+ *
+ * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
+ * NORMAL APPLICATION CODE.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION;
+
+#endif
+
+/*
+ * When a task is created, the stack of the task is filled with a known value.
+ * This function determines the 'high water mark' of the task stack by
+ * determining how much of the stack remains at the original preset value.
+ */
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
+
+    static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION;
+
+#endif
+
+
+/*lint +e956 */
+
+
+
+/*-----------------------------------------------------------
+ * TASK CREATION API documented in task.h
+ *----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )
+{
+signed portBASE_TYPE xReturn;
+tskTCB * pxNewTCB;
+
+    /* Allocate the memory required by the TCB and stack for the new task,
+    checking that the allocation was successful. */
+    pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
+
+    if( pxNewTCB != NULL )
+    {
+        portSTACK_TYPE *pxTopOfStack;
+
+        #if( portUSING_MPU_WRAPPERS == 1 )
+            /* Should the task be created in privileged mode? */
+            portBASE_TYPE xRunPrivileged;
+            if( ( uxPriority & portPRIVILEGE_BIT ) != 0x00 )
+            {
+                xRunPrivileged = pdTRUE;
+            }
+            else
+            {
+                xRunPrivileged = pdFALSE;
+            }
+            uxPriority &= ~portPRIVILEGE_BIT;
+        #endif /* portUSING_MPU_WRAPPERS == 1 */
+
+        /* Calculate the top of stack address.  This depends on whether the
+        stack grows from high memory to low (as per the 80x86) or visa versa.
+        portSTACK_GROWTH is used to make the result positive or negative as
+        required by the port. */
+        #if( portSTACK_GROWTH < 0 )
+        {
+            pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
+            pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK  ) );
+        }
+        #else
+        {
+            pxTopOfStack = pxNewTCB->pxStack;
+
+            /* If we want to use stack checking on architectures that use
+            a positive stack growth direction then we also need to store the
+            other extreme of the stack space. */
+            pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
+        }
+        #endif
+
+        /* Setup the newly allocated TCB with the initial state of the task. */
+        prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
+
+        /* Initialize the TCB stack to look as if the task was already running,
+        but had been interrupted by the scheduler.  The return address is set
+        to the start of the task function. Once the stack has been initialised
+        the    top of stack variable is updated. */
+        #if( portUSING_MPU_WRAPPERS == 1 )
+        {
+            pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
+        }
+        #else
+        {
+            pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
+        }
+        #endif
+
+        /* We are going to manipulate the task queues to add this task to a
+        ready list, so must make sure no interrupts occur. */
+        portENTER_CRITICAL();
+        {
+            uxCurrentNumberOfTasks++;
+            if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )
+            {
+                /* As this is the first task it must also be the current task. */
+                pxCurrentTCB =  pxNewTCB;
+
+                /* This is the first task to be created so do the preliminary
+                initialisation required.  We will not recover if this call
+                fails, but we will report the failure. */
+                prvInitialiseTaskLists();
+            }
+            else
+            {
+                /* If the scheduler is not already running, make this task the
+                current task if it is the highest priority task to be created
+                so far. */
+                if( xSchedulerRunning == pdFALSE )
+                {
+                    if( pxCurrentTCB->uxPriority <= uxPriority )
+                    {
+                        pxCurrentTCB = pxNewTCB;
+                    }
+                }
+            }
+
+            /* Remember the top priority to make context switching faster.  Use
+            the priority in pxNewTCB as this has been capped to a valid value. */
+            if( pxNewTCB->uxPriority > uxTopUsedPriority )
+            {
+                uxTopUsedPriority = pxNewTCB->uxPriority;
+            }
+
+            #if ( configUSE_TRACE_FACILITY == 1 )
+            {
+                /* Add a counter into the TCB for tracing only. */
+                pxNewTCB->uxTCBNumber = uxTaskNumber;
+            }
+            #endif
+            uxTaskNumber++;
+
+            prvAddTaskToReadyQueue( pxNewTCB );
+
+            xReturn = pdPASS;
+            traceTASK_CREATE( pxNewTCB );
+        }
+        portEXIT_CRITICAL();
+    }
+    else
+    {
+        xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+        traceTASK_CREATE_FAILED( pxNewTCB );
+    }
+
+    if( xReturn == pdPASS )
+    {
+        if( ( void * ) pxCreatedTask != NULL )
+        {
+            /* Pass the TCB out - in an anonymous way.  The calling function/
+            task can use this as a handle to delete the task later if
+            required.*/
+            *pxCreatedTask = ( xTaskHandle ) pxNewTCB;
+        }
+
+        if( xSchedulerRunning != pdFALSE )
+        {
+            /* If the created task is of a higher priority than the current task
+            then it should run now. */
+            if( pxCurrentTCB->uxPriority < uxPriority )
+            {
+                portYIELD_WITHIN_API();
+            }
+        }
+    }
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+    void vTaskDelete( xTaskHandle pxTaskToDelete )
+    {
+    tskTCB *pxTCB;
+
+        portENTER_CRITICAL();
+        {
+            /* Ensure a yield is performed if the current task is being
+            deleted. */
+            if( pxTaskToDelete == pxCurrentTCB )
+            {
+                pxTaskToDelete = NULL;
+            }
+
+            /* If null is passed in here then we are deleting ourselves. */
+            pxTCB = prvGetTCBFromHandle( pxTaskToDelete );
+
+            /* Remove task from the ready list and place in the    termination list.
+            This will stop the task from be scheduled.  The idle task will check
+            the termination list and free up any memory allocated by the
+            scheduler for the TCB and stack. */
+            vListRemove( &( pxTCB->xGenericListItem ) );
+
+            /* Is the task waiting on an event also? */
+            if( pxTCB->xEventListItem.pvContainer )
+            {
+                vListRemove( &( pxTCB->xEventListItem ) );
+            }
+
+            vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
+
+            /* Increment the ucTasksDeleted variable so the idle task knows
+            there is a task that has been deleted and that it should therefore
+            check the xTasksWaitingTermination list. */
+            ++uxTasksDeleted;
+
+            /* Increment the uxTaskNumberVariable also so kernel aware debuggers
+            can detect that the task lists need re-generating. */
+            uxTaskNumber++;
+
+            traceTASK_DELETE( pxTCB );
+        }
+        portEXIT_CRITICAL();
+
+        /* Force a reschedule if we have just deleted the current task. */
+        if( xSchedulerRunning != pdFALSE )
+        {
+            if( ( void * ) pxTaskToDelete == NULL )
+            {
+                portYIELD_WITHIN_API();
+            }
+        }
+    }
+
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API documented in task.h
+ *----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelayUntil == 1 )
+
+    void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )
+    {
+    portTickType xTimeToWake;
+    portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;
+
+        vTaskSuspendAll();
+        {
+            /* Generate the tick time at which the task wants to wake. */
+            xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
+
+            if( xTickCount < *pxPreviousWakeTime )
+            {
+                /* The tick count has overflowed since this function was
+                lasted called.  In this case the only time we should ever
+                actually delay is if the wake time has also    overflowed,
+                and the wake time is greater than the tick time.  When this
+                is the case it is as if neither time had overflowed. */
+                if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) )
+                {
+                    xShouldDelay = pdTRUE;
+                }
+            }
+            else
+            {
+                /* The tick time has not overflowed.  In this case we will
+                delay if either the wake time has overflowed, and/or the
+                tick time is less than the wake time. */
+                if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) )
+                {
+                    xShouldDelay = pdTRUE;
+                }
+            }
+
+            /* Update the wake time ready for the next call. */
+            *pxPreviousWakeTime = xTimeToWake;
+
+            if( xShouldDelay )
+            {
+                traceTASK_DELAY_UNTIL();
+
+                /* We must remove ourselves from the ready list before adding
+                ourselves to the blocked list as the same list item is used for
+                both lists. */
+                vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+
+                /* The list item will be inserted in wake time order. */
+                listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
+
+                if( xTimeToWake < xTickCount )
+                {
+                    /* Wake time has overflowed.  Place this item in the
+                    overflow list. */
+                    vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+                }
+                else
+                {
+                    /* The wake time has not overflowed, so we can use the
+                    current block list. */
+                    vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+                }
+            }
+        }
+        xAlreadyYielded = xTaskResumeAll();
+
+        /* Force a reschedule if xTaskResumeAll has not already done so, we may
+        have put ourselves to sleep. */
+        if( !xAlreadyYielded )
+        {
+            portYIELD_WITHIN_API();
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelay == 1 )
+
+    void vTaskDelay( portTickType xTicksToDelay )
+    {
+    portTickType xTimeToWake;
+    signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+        /* A delay time of zero just forces a reschedule. */
+        if( xTicksToDelay > ( portTickType ) 0 )
+        {
+            vTaskSuspendAll();
+            {
+                traceTASK_DELAY();
+
+                /* A task that is removed from the event list while the
+                scheduler is suspended will not get placed in the ready
+                list or removed from the blocked list until the scheduler
+                is resumed.
+
+                This task cannot be in an event list as it is the currently
+                executing task. */
+
+                /* Calculate the time to wake - this may overflow but this is
+                not a problem. */
+                xTimeToWake = xTickCount + xTicksToDelay;
+
+                /* We must remove ourselves from the ready list before adding
+                ourselves to the blocked list as the same list item is used for
+                both lists. */
+                vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+
+                /* The list item will be inserted in wake time order. */
+                listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
+
+                if( xTimeToWake < xTickCount )
+                {
+                    /* Wake time has overflowed.  Place this item in the
+                    overflow list. */
+                    vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+                }
+                else
+                {
+                    /* The wake time has not overflowed, so we can use the
+                    current block list. */
+                    vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+                }
+            }
+            xAlreadyYielded = xTaskResumeAll();
+        }
+
+        /* Force a reschedule if xTaskResumeAll has not already done so, we may
+        have put ourselves to sleep. */
+        if( !xAlreadyYielded )
+        {
+            portYIELD_WITHIN_API();
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_uxTaskPriorityGet == 1 )
+
+    unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )
+    {
+    tskTCB *pxTCB;
+    unsigned portBASE_TYPE uxReturn;
+
+        portENTER_CRITICAL();
+        {
+            /* If null is passed in here then we are changing the
+            priority of the calling function. */
+            pxTCB = prvGetTCBFromHandle( pxTask );
+            uxReturn = pxTCB->uxPriority;
+        }
+        portEXIT_CRITICAL();
+
+        return uxReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskPrioritySet == 1 )
+
+    void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )
+    {
+    tskTCB *pxTCB;
+    unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE;
+
+        /* Ensure the new priority is valid. */
+        if( uxNewPriority >= configMAX_PRIORITIES )
+        {
+            uxNewPriority = configMAX_PRIORITIES - 1;
+        }
+
+        portENTER_CRITICAL();
+        {
+            if( pxTask == pxCurrentTCB )
+            {
+                pxTask = NULL;
+            }
+
+            /* If null is passed in here then we are changing the
+            priority of the calling function. */
+            pxTCB = prvGetTCBFromHandle( pxTask );
+
+            traceTASK_PRIORITY_SET( pxTask, uxNewPriority );
+
+            #if ( configUSE_MUTEXES == 1 )
+            {
+                uxCurrentPriority = pxTCB->uxBasePriority;
+            }
+            #else
+            {
+                uxCurrentPriority = pxTCB->uxPriority;
+            }
+            #endif
+
+            if( uxCurrentPriority != uxNewPriority )
+            {
+                /* The priority change may have readied a task of higher
+                priority than the calling task. */
+                if( uxNewPriority > uxCurrentPriority )
+                {
+                    if( pxTask != NULL )
+                    {
+                        /* The priority of another task is being raised.  If we
+                        were raising the priority of the currently running task
+                        there would be no need to switch as it must have already
+                        been the highest priority task. */
+                        xYieldRequired = pdTRUE;
+                    }
+                }
+                else if( pxTask == NULL )
+                {
+                    /* Setting our own priority down means there may now be another
+                    task of higher priority that is ready to execute. */
+                    xYieldRequired = pdTRUE;
+                }
+
+
+
+                #if ( configUSE_MUTEXES == 1 )
+                {
+                    /* Only change the priority being used if the task is not
+                    currently using an inherited priority. */
+                    if( pxTCB->uxBasePriority == pxTCB->uxPriority )
+                    {
+                        pxTCB->uxPriority = uxNewPriority;
+                    }
+
+                    /* The base priority gets set whatever. */
+                    pxTCB->uxBasePriority = uxNewPriority;
+                }
+                #else
+                {
+                    pxTCB->uxPriority = uxNewPriority;
+                }
+                #endif
+
+                listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );
+
+                /* If the task is in the blocked or suspended list we need do
+                nothing more than change it's priority variable. However, if
+                the task is in a ready list it needs to be removed and placed
+                in the queue appropriate to its new priority. */
+                if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) )
+                {
+                    /* The task is currently in its ready list - remove before adding
+                    it to it's new ready list.  As we are in a critical section we
+                    can do this even if the scheduler is suspended. */
+                    vListRemove( &( pxTCB->xGenericListItem ) );
+                    prvAddTaskToReadyQueue( pxTCB );
+                }
+
+                if( xYieldRequired == pdTRUE )
+                {
+                    portYIELD_WITHIN_API();
+                }
+            }
+        }
+        portEXIT_CRITICAL();
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+    void vTaskSuspend( xTaskHandle pxTaskToSuspend )
+    {
+    tskTCB *pxTCB;
+
+        portENTER_CRITICAL();
+        {
+            /* Ensure a yield is performed if the current task is being
+            suspended. */
+            if( pxTaskToSuspend == pxCurrentTCB )
+            {
+                pxTaskToSuspend = NULL;
+            }
+
+            /* If null is passed in here then we are suspending ourselves. */
+            pxTCB = prvGetTCBFromHandle( pxTaskToSuspend );
+
+            traceTASK_SUSPEND( pxTCB );
+
+            /* Remove task from the ready/delayed list and place in the    suspended list. */
+            vListRemove( &( pxTCB->xGenericListItem ) );
+
+            /* Is the task waiting on an event also? */
+            if( pxTCB->xEventListItem.pvContainer )
+            {
+                vListRemove( &( pxTCB->xEventListItem ) );
+            }
+
+            vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
+        }
+        portEXIT_CRITICAL();
+
+        /* We may have just suspended the current task. */
+        if( ( void * ) pxTaskToSuspend == NULL )
+        {
+            portYIELD_WITHIN_API();
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+    signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask )
+    {
+    portBASE_TYPE xReturn = pdFALSE;
+    const tskTCB * const pxTCB = ( tskTCB * ) xTask;
+
+        /* Is the task we are attempting to resume actually in the
+        suspended list? */
+        if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
+        {
+            /* Has the task already been resumed from within an ISR? */
+            if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
+            {
+                /* Is it in the suspended list because it is in the
+                Suspended state?  It is possible to be in the suspended
+                list because it is blocked on a task with no timeout
+                specified. */
+                if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )
+                {
+                    xReturn = pdTRUE;
+                }
+            }
+        }
+
+        return xReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+    void vTaskResume( xTaskHandle pxTaskToResume )
+    {
+    tskTCB *pxTCB;
+
+        /* Remove the task from whichever list it is currently in, and place
+        it in the ready list. */
+        pxTCB = ( tskTCB * ) pxTaskToResume;
+
+        /* The parameter cannot be NULL as it is impossible to resume the
+        currently executing task. */
+        if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
+        {
+            portENTER_CRITICAL();
+            {
+                if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
+                {
+                    traceTASK_RESUME( pxTCB );
+
+                    /* As we are in a critical section we can access the ready
+                    lists even if the scheduler is suspended. */
+                    vListRemove(  &( pxTCB->xGenericListItem ) );
+                    prvAddTaskToReadyQueue( pxTCB );
+
+                    /* We may have just resumed a higher priority task. */
+                    if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
+                    {
+                        /* This yield may not cause the task just resumed to run, but
+                        will leave the lists in the correct state for the next yield. */
+                        portYIELD_WITHIN_API();
+                    }
+                }
+            }
+            portEXIT_CRITICAL();
+        }
+    }
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+    portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )
+    {
+    portBASE_TYPE xYieldRequired = pdFALSE;
+    tskTCB *pxTCB;
+
+        pxTCB = ( tskTCB * ) pxTaskToResume;
+
+        if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
+        {
+            traceTASK_RESUME_FROM_ISR( pxTCB );
+
+            if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
+            {
+                xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );
+                vListRemove(  &( pxTCB->xGenericListItem ) );
+                prvAddTaskToReadyQueue( pxTCB );
+            }
+            else
+            {
+                /* We cannot access the delayed or ready lists, so will hold this
+                task pending until the scheduler is resumed, at which point a
+                yield will be performed if necessary. */
+                vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
+            }
+        }
+
+        return xYieldRequired;
+    }
+
+#endif
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC SCHEDULER CONTROL documented in task.h
+ *----------------------------------------------------------*/
+
+// Modified by  Kenji Arai / JH1PJL, October 30th,2010
+// move to port_asm.c
+#if 0
+void vTaskStartScheduler( void )
+{
+portBASE_TYPE xReturn;
+
+    /* Add the idle task at the lowest priority. */
+    xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL );
+
+    if( xReturn == pdPASS )
+    {
+        /* Interrupts are turned off here, to ensure a tick does not occur
+        before or during the call to xPortStartScheduler().  The stacks of
+        the created tasks contain a status word with interrupts switched on
+        so interrupts will automatically get re-enabled when the first task
+        starts to run.
+
+        STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE
+        DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */
+        portDISABLE_INTERRUPTS();
+
+        xSchedulerRunning = pdTRUE;
+        xTickCount = ( portTickType ) 0;
+
+        /* If configGENERATE_RUN_TIME_STATS is defined then the following
+        macro must be defined to configure the timer/counter used to generate
+        the run time counter time base. */
+        portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
+
+        /* Setting up the timer tick is hardware specific and thus in the
+        portable interface. */
+        if( xPortStartScheduler() )
+        {
+            /* Should not reach here as if the scheduler is running the
+            function will not return. */
+        }
+        else
+        {
+            /* Should only reach here if a task calls xTaskEndScheduler(). */
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+void vTaskEndScheduler( void )
+{
+    /* Stop the scheduler interrupts and call the portable scheduler end
+    routine so the original ISRs can be restored if necessary.  The port
+    layer must ensure interrupts enable    bit is left in the correct state. */
+    portDISABLE_INTERRUPTS();
+    xSchedulerRunning = pdFALSE;
+    vPortEndScheduler();
+}
+/*----------------------------------------------------------*/
+#endif
+
+void vTaskSuspendAll( void )
+{
+    /* A critical section is not required as the variable is of type
+    portBASE_TYPE. */
+    ++uxSchedulerSuspended;
+}
+/*----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskResumeAll( void )
+{
+register tskTCB *pxTCB;
+signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+    /* It is possible that an ISR caused a task to be removed from an event
+    list while the scheduler was suspended.  If this was the case then the
+    removed task will have been added to the xPendingReadyList.  Once the
+    scheduler has been resumed it is safe to move all the pending ready
+    tasks from this list into their appropriate ready list. */
+    portENTER_CRITICAL();
+    {
+        --uxSchedulerSuspended;
+
+        if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
+        {
+            if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 )
+            {
+                portBASE_TYPE xYieldRequired = pdFALSE;
+
+                /* Move any readied tasks from the pending list into the
+                appropriate ready list. */
+                while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY(  ( ( xList * ) &xPendingReadyList ) ) ) != NULL )
+                {
+                    vListRemove( &( pxTCB->xEventListItem ) );
+                    vListRemove( &( pxTCB->xGenericListItem ) );
+                    prvAddTaskToReadyQueue( pxTCB );
+
+                    /* If we have moved a task that has a priority higher than
+                    the current task then we should yield. */
+                    if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
+                    {
+                        xYieldRequired = pdTRUE;
+                    }
+                }
+
+                /* If any ticks occurred while the scheduler was suspended then
+                they should be processed now.  This ensures the tick count does not
+                slip, and that any delayed tasks are resumed at the correct time. */
+                if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
+                {
+                    while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
+                    {
+                        vTaskIncrementTick();
+                        --uxMissedTicks;
+                    }
+
+                    /* As we have processed some ticks it is appropriate to yield
+                    to ensure the highest priority task that is ready to run is
+                    the task actually running. */
+                    #if configUSE_PREEMPTION == 1
+                    {
+                        xYieldRequired = pdTRUE;
+                    }
+                    #endif
+                }
+
+                if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )
+                {
+                    xAlreadyYielded = pdTRUE;
+                    xMissedYield = pdFALSE;
+                    portYIELD_WITHIN_API();
+                }
+            }
+        }
+    }
+    portEXIT_CRITICAL();
+
+    return xAlreadyYielded;
+}
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC TASK UTILITIES documented in task.h
+ *----------------------------------------------------------*/
+
+
+
+portTickType xTaskGetTickCount( void )
+{
+portTickType xTicks;
+
+    /* Critical section required if running on a 16 bit processor. */
+    portENTER_CRITICAL();
+    {
+        xTicks = xTickCount;
+    }
+    portEXIT_CRITICAL();
+
+    return xTicks;
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
+{
+    /* A critical section is not required because the variables are of type
+    portBASE_TYPE. */
+    return uxCurrentNumberOfTasks;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    void vTaskList( signed char *pcWriteBuffer )
+    {
+    unsigned portBASE_TYPE uxQueue;
+
+        /* This is a VERY costly function that should be used for debug only.
+        It leaves interrupts disabled for a LONG time. */
+
+        vTaskSuspendAll();
+        {
+            /* Run through all the lists that could potentially contain a TCB and
+            report the task name, state and stack high water mark. */
+
+            pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
+            strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
+
+            uxQueue = uxTopUsedPriority + 1;
+
+            do
+            {
+                uxQueue--;
+
+                if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
+                {
+                    prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );
+                }
+            }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
+
+            if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
+            {
+                prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );
+            }
+
+            if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
+            {
+                prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );
+            }
+
+            #if( INCLUDE_vTaskDelete == 1 )
+            {
+                if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
+                {
+                    prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR );
+                }
+            }
+            #endif
+
+            #if ( INCLUDE_vTaskSuspend == 1 )
+            {
+                if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
+                {
+                    prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR );
+                }
+            }
+            #endif
+        }
+        xTaskResumeAll();
+    }
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+    void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
+    {
+    unsigned portBASE_TYPE uxQueue;
+    unsigned long ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
+
+        /* This is a VERY costly function that should be used for debug only.
+        It leaves interrupts disabled for a LONG time. */
+
+        vTaskSuspendAll();
+        {
+            /* Run through all the lists that could potentially contain a TCB,
+            generating a table of run timer percentages in the provided
+            buffer. */
+
+            pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
+            strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
+
+            uxQueue = uxTopUsedPriority + 1;
+
+            do
+            {
+                uxQueue--;
+
+                if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
+                {
+                    prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime );
+                }
+            }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
+
+            if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
+            {
+                prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime );
+            }
+
+            if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
+            {
+                prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime );
+            }
+
+            #if ( INCLUDE_vTaskDelete == 1 )
+            {
+                if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
+                {
+                    prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime );
+                }
+            }
+            #endif
+
+            #if ( INCLUDE_vTaskSuspend == 1 )
+            {
+                if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
+                {
+                    prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime );
+                }
+            }
+            #endif
+        }
+        xTaskResumeAll();
+    }
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )
+    {
+        portENTER_CRITICAL();
+        {
+            pcTraceBuffer = ( signed char * )pcBuffer;
+            pcTraceBufferStart = pcBuffer;
+            pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );
+            xTracing = pdTRUE;
+        }
+        portEXIT_CRITICAL();
+    }
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    unsigned long ulTaskEndTrace( void )
+    {
+    unsigned long ulBufferLength;
+
+        portENTER_CRITICAL();
+            xTracing = pdFALSE;
+        portEXIT_CRITICAL();
+
+        ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart );
+
+        return ulBufferLength;
+    }
+
+#endif
+
+
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ * documented in task.h
+ *----------------------------------------------------------*/
+
+
+void vTaskIncrementTick( void )
+{
+    /* Called by the portable layer each time a tick interrupt occurs.
+    Increments the tick then checks to see if the new tick value will cause any
+    tasks to be unblocked. */
+    if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
+    {
+        ++xTickCount;
+        if( xTickCount == ( portTickType ) 0 )
+        {
+            xList *pxTemp;
+
+            /* Tick count has overflowed so we need to swap the delay lists.
+            If there are any items in pxDelayedTaskList here then there is
+            an error! */
+            pxTemp = pxDelayedTaskList;
+            pxDelayedTaskList = pxOverflowDelayedTaskList;
+            pxOverflowDelayedTaskList = pxTemp;
+            xNumOfOverflows++;
+        }
+
+        /* See if this tick has made a timeout expire. */
+        prvCheckDelayedTasks();
+    }
+    else
+    {
+        ++uxMissedTicks;
+
+        /* The tick hook gets called at regular intervals, even if the
+        scheduler is locked. */
+        #if ( configUSE_TICK_HOOK == 1 )
+        {
+            extern void vApplicationTickHook( void );
+
+            vApplicationTickHook();
+        }
+        #endif
+    }
+
+    #if ( configUSE_TICK_HOOK == 1 )
+    {
+        extern void vApplicationTickHook( void );
+
+        /* Guard against the tick hook being called when the missed tick
+        count is being unwound (when the scheduler is being unlocked. */
+        if( uxMissedTicks == 0 )
+        {
+            vApplicationTickHook();
+        }
+    }
+    #endif
+
+    traceTASK_INCREMENT_TICK( xTickCount );
+}
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+    void vTaskCleanUpResources( void )
+    {
+    unsigned short usQueue;
+    volatile tskTCB *pxTCB;
+
+        usQueue = ( unsigned short ) uxTopUsedPriority + ( unsigned short ) 1;
+
+        /* Remove any TCB's from the ready queues. */
+        do
+        {
+            usQueue--;
+
+            while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) )
+            {
+                listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) );
+                vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
+
+                prvDeleteTCB( ( tskTCB * ) pxTCB );
+            }
+        }while( usQueue > ( unsigned short ) tskIDLE_PRIORITY );
+
+        /* Remove any TCB's from the delayed queue. */
+        while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) )
+        {
+            listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 );
+            vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
+
+            prvDeleteTCB( ( tskTCB * ) pxTCB );
+        }
+
+        /* Remove any TCB's from the overflow delayed queue. */
+        while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) )
+        {
+            listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 );
+            vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
+
+            prvDeleteTCB( ( tskTCB * ) pxTCB );
+        }
+
+        while( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
+        {
+            listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xSuspendedTaskList );
+            vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
+
+            prvDeleteTCB( ( tskTCB * ) pxTCB );
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+    void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue )
+    {
+    tskTCB *xTCB;
+
+        /* If xTask is NULL then we are setting our own task hook. */
+        if( xTask == NULL )
+        {
+            xTCB = ( tskTCB * ) pxCurrentTCB;
+        }
+        else
+        {
+            xTCB = ( tskTCB * ) xTask;
+        }
+
+        /* Save the hook function in the TCB.  A critical section is required as
+        the value can be accessed from an interrupt. */
+        portENTER_CRITICAL();
+            xTCB->pxTaskTag = pxTagValue;
+        portEXIT_CRITICAL();
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+    pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )
+    {
+    tskTCB *xTCB;
+    pdTASK_HOOK_CODE xReturn;
+
+        /* If xTask is NULL then we are setting our own task hook. */
+        if( xTask == NULL )
+        {
+            xTCB = ( tskTCB * ) pxCurrentTCB;
+        }
+        else
+        {
+            xTCB = ( tskTCB * ) xTask;
+        }
+
+        /* Save the hook function in the TCB.  A critical section is required as
+        the value can be accessed from an interrupt. */
+        portENTER_CRITICAL();
+            xReturn = xTCB->pxTaskTag;
+        portEXIT_CRITICAL();
+
+        return xReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+    portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )
+    {
+    tskTCB *xTCB;
+    portBASE_TYPE xReturn;
+
+        /* If xTask is NULL then we are calling our own task hook. */
+        if( xTask == NULL )
+        {
+            xTCB = ( tskTCB * ) pxCurrentTCB;
+        }
+        else
+        {
+            xTCB = ( tskTCB * ) xTask;
+        }
+
+        if( xTCB->pxTaskTag != NULL )
+        {
+            xReturn = xTCB->pxTaskTag( pvParameter );
+        }
+        else
+        {
+            xReturn = pdFAIL;
+        }
+
+        return xReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+void vTaskSwitchContext( void )
+{
+    if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )
+    {
+        /* The scheduler is currently suspended - do not allow a context
+        switch. */
+        xMissedYield = pdTRUE;
+        return;
+    }
+
+    traceTASK_SWITCHED_OUT();
+
+    #if ( configGENERATE_RUN_TIME_STATS == 1 )
+    {
+        unsigned long ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();
+
+            /* Add the amount of time the task has been running to the accumulated
+            time so far.  The time the task started running was stored in
+            ulTaskSwitchedInTime.  Note that there is no overflow protection here
+            so count values are only valid until the timer overflows.  Generally
+            this will be about 1 hour assuming a 1uS timer increment. */
+            pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );
+            ulTaskSwitchedInTime = ulTempCounter;
+    }
+    #endif
+
+    taskFIRST_CHECK_FOR_STACK_OVERFLOW();
+    taskSECOND_CHECK_FOR_STACK_OVERFLOW();
+
+    /* Find the highest priority queue that contains ready tasks. */
+    while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
+    {
+        --uxTopReadyPriority;
+    }
+
+    /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
+    same priority get an equal share of the processor time. */
+    listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
+    #if 0
+    //#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
+    {
+        xList * const pxConstList = &( pxReadyTasksLists[ uxTopReadyPriority ] );
+        /* Increment the index to the next item and return the item, ensuring */
+        /* we don't return the marker used at the end of the list.  */
+        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
+        if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) )
+        {
+            ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
+        }
+        pxCurrentTCB = (tskTCB *) (( pxConstList )->pxIndex->pvOwner);      // Error then added (tskTCB *)()
+    }
+    #endif
+
+    traceTASK_SWITCHED_IN();
+    vWriteTraceToBuffer();
+}
+/*-----------------------------------------------------------*/
+
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )
+{
+portTickType xTimeToWake;
+
+    /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+    SCHEDULER SUSPENDED. */
+
+    /* Place the event list item of the TCB in the appropriate event list.
+    This is placed in the list in priority order so the highest priority task
+    is the first to be woken by the event. */
+    vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );
+
+    /* We must remove ourselves from the ready list before adding ourselves
+    to the blocked list as the same list item is used for both lists.  We have
+    exclusive access to the ready lists as the scheduler is locked. */
+    vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+
+
+    #if ( INCLUDE_vTaskSuspend == 1 )
+    {
+        if( xTicksToWait == portMAX_DELAY )
+        {
+            /* Add ourselves to the suspended task list instead of a delayed task
+            list to ensure we are not woken by a timing event.  We will block
+            indefinitely. */
+            vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+        }
+        else
+        {
+            /* Calculate the time at which the task should be woken if the event does
+            not occur.  This may overflow but this doesn't matter. */
+            xTimeToWake = xTickCount + xTicksToWait;
+
+            listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
+
+            if( xTimeToWake < xTickCount )
+            {
+                /* Wake time has overflowed.  Place this item in the overflow list. */
+                vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+            }
+            else
+            {
+                /* The wake time has not overflowed, so we can use the current block list. */
+                vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+            }
+        }
+    }
+    #else
+    {
+            /* Calculate the time at which the task should be woken if the event does
+            not occur.  This may overflow but this doesn't matter. */
+            xTimeToWake = xTickCount + xTicksToWait;
+
+            listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
+
+            if( xTimeToWake < xTickCount )
+            {
+                /* Wake time has overflowed.  Place this item in the overflow list. */
+                vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+            }
+            else
+            {
+                /* The wake time has not overflowed, so we can use the current block list. */
+                vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
+            }
+    }
+    #endif
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
+{
+tskTCB *pxUnblockedTCB;
+portBASE_TYPE xReturn;
+
+    /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+    SCHEDULER SUSPENDED.  It can also be called from within an ISR. */
+
+    /* The event list is sorted in priority order, so we can remove the
+    first in the list, remove the TCB from the delayed list, and add
+    it to the ready list.
+
+    If an event is for a queue that is locked then this function will never
+    get called - the lock count on the queue will get modified instead.  This
+    means we can always expect exclusive access to the event list here. */
+    pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
+    vListRemove( &( pxUnblockedTCB->xEventListItem ) );
+
+    if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
+    {
+        vListRemove( &( pxUnblockedTCB->xGenericListItem ) );
+        prvAddTaskToReadyQueue( pxUnblockedTCB );
+    }
+    else
+    {
+        /* We cannot access the delayed or ready lists, so will hold this
+        task pending until the scheduler is resumed. */
+        vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
+    }
+
+    if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )
+    {
+        /* Return true if the task removed from the event list has
+        a higher priority than the calling task.  This allows
+        the calling task to know if it should force a context
+        switch now. */
+        xReturn = pdTRUE;
+    }
+    else
+    {
+        xReturn = pdFALSE;
+    }
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )
+{
+    pxTimeOut->xOverflowCount = xNumOfOverflows;
+    pxTimeOut->xTimeOnEntering = xTickCount;
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )
+{
+portBASE_TYPE xReturn;
+
+    portENTER_CRITICAL();
+    {
+        #if ( INCLUDE_vTaskSuspend == 1 )
+            /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
+            the maximum block time then the task should block indefinitely, and
+            therefore never time out. */
+            if( *pxTicksToWait == portMAX_DELAY )
+            {
+                xReturn = pdFALSE;
+            }
+            else /* We are not blocking indefinitely, perform the checks below. */
+        #endif
+
+        if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )
+        {
+            /* The tick count is greater than the time at which vTaskSetTimeout()
+            was called, but has also overflowed since vTaskSetTimeOut() was called.
+            It must have wrapped all the way around and gone past us again. This
+            passed since vTaskSetTimeout() was called. */
+            xReturn = pdTRUE;
+        }
+        else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )
+        {
+            /* Not a genuine timeout. Adjust parameters for time remaining. */
+            *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );
+            vTaskSetTimeOutState( pxTimeOut );
+            xReturn = pdFALSE;
+        }
+        else
+        {
+            xReturn = pdTRUE;
+        }
+    }
+    portEXIT_CRITICAL();
+
+    return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vTaskMissedYield( void )
+{
+    xMissedYield = pdTRUE;
+}
+
+/*
+ * -----------------------------------------------------------
+ * The Idle task.
+ * ----------------------------------------------------------
+ *
+ * The portTASK_FUNCTION() macro is used to allow port/compiler specific
+ * language extensions.  The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+static portTASK_FUNCTION( prvIdleTask, pvParameters )
+{
+    /* Stop warnings. */
+    ( void ) pvParameters;
+
+    for( ;; )
+    {
+        /* See if any tasks have been deleted. */
+        prvCheckTasksWaitingTermination();
+
+        #if ( configUSE_PREEMPTION == 0 )
+        {
+            /* If we are not using preemption we keep forcing a task switch to
+            see if any other task has become available.  If we are using
+            preemption we don't need to do this as any task becoming available
+            will automatically get the processor anyway. */
+            taskYIELD();
+        }
+        #endif
+
+        #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
+        {
+            /* When using preemption tasks of equal priority will be
+            timesliced.  If a task that is sharing the idle priority is ready
+            to run then the idle task should yield before the end of the
+            timeslice.
+
+            A critical region is not required here as we are just reading from
+            the list, and an occasional incorrect value will not matter.  If
+            the ready list at the idle priority contains more than one task
+            then a task other than the idle task is ready to execute. */
+            if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )
+            {
+                taskYIELD();
+            }
+        }
+        #endif
+
+        #if ( configUSE_IDLE_HOOK == 1 )
+        {
+            extern void vApplicationIdleHook( void );
+
+            /* Call the user defined function from within the idle task.  This
+            allows the application designer to add background functionality
+            without the overhead of a separate task.
+            NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
+            CALL A FUNCTION THAT MIGHT BLOCK. */
+            vApplicationIdleHook();
+        }
+        #endif
+    }
+} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
+
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * File private functions documented at the top of the file.
+ *----------------------------------------------------------*/
+
+
+
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )
+{
+    /* Store the function name in the TCB. */
+    #if configMAX_TASK_NAME_LEN > 1
+    {
+        /* Don't bring strncpy into the build unnecessarily. */
+        strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );
+    }
+    #endif
+    pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0';
+
+    /* This is used as an array index so must ensure it's not too large.  First
+    remove the privilege bit if one is present. */
+    if( uxPriority >= configMAX_PRIORITIES )
+    {
+        uxPriority = configMAX_PRIORITIES - 1;
+    }
+
+    pxTCB->uxPriority = uxPriority;
+    #if ( configUSE_MUTEXES == 1 )
+    {
+        pxTCB->uxBasePriority = uxPriority;
+    }
+    #endif
+
+    vListInitialiseItem( &( pxTCB->xGenericListItem ) );
+    vListInitialiseItem( &( pxTCB->xEventListItem ) );
+
+    /* Set the pxTCB as a link back from the xListItem.  This is so we can get
+    back to    the containing TCB from a generic item in a list. */
+    listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
+
+    /* Event lists are always in priority order. */
+    listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
+    listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
+
+    #if ( portCRITICAL_NESTING_IN_TCB == 1 )
+    {
+        pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0;
+    }
+    #endif
+
+    #if ( configUSE_APPLICATION_TASK_TAG == 1 )
+    {
+        pxTCB->pxTaskTag = NULL;
+    }
+    #endif
+
+    #if ( configGENERATE_RUN_TIME_STATS == 1 )
+    {
+        pxTCB->ulRunTimeCounter = 0UL;
+    }
+    #endif
+
+    #if ( portUSING_MPU_WRAPPERS == 1 )
+    {
+        vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
+    }
+    #else
+    {
+        ( void ) xRegions;
+        ( void ) usStackDepth;
+    }
+    #endif
+}
+/*-----------------------------------------------------------*/
+
+#if ( portUSING_MPU_WRAPPERS == 1 )
+
+    void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions )
+    {
+    tskTCB *pxTCB;
+    
+        if( xTaskToModify == pxCurrentTCB )
+        {
+            xTaskToModify = NULL;
+        }
+
+        /* If null is passed in here then we are deleting ourselves. */
+        pxTCB = prvGetTCBFromHandle( xTaskToModify );
+
+        vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
+    }
+    /*-----------------------------------------------------------*/
+#endif
+
+static void prvInitialiseTaskLists( void )
+{
+unsigned portBASE_TYPE uxPriority;
+
+    for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ )
+    {
+        vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) );
+    }
+
+    vListInitialise( ( xList * ) &xDelayedTaskList1 );
+    vListInitialise( ( xList * ) &xDelayedTaskList2 );
+    vListInitialise( ( xList * ) &xPendingReadyList );
+
+    #if ( INCLUDE_vTaskDelete == 1 )
+    {
+        vListInitialise( ( xList * ) &xTasksWaitingTermination );
+    }
+    #endif
+
+    #if ( INCLUDE_vTaskSuspend == 1 )
+    {
+        vListInitialise( ( xList * ) &xSuspendedTaskList );
+    }
+    #endif
+
+    /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
+    using list2. */
+    pxDelayedTaskList = &xDelayedTaskList1;
+    pxOverflowDelayedTaskList = &xDelayedTaskList2;
+}
+/*-----------------------------------------------------------*/
+
+static void prvCheckTasksWaitingTermination( void )
+{
+    #if ( INCLUDE_vTaskDelete == 1 )
+    {
+        portBASE_TYPE xListIsEmpty;
+
+        /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
+        too often in the idle task. */
+        if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0 )
+        {
+            vTaskSuspendAll();
+                xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
+            xTaskResumeAll();
+
+            if( !xListIsEmpty )
+            {
+                tskTCB *pxTCB;
+
+                portENTER_CRITICAL();
+                {
+                    pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );
+                    vListRemove( &( pxTCB->xGenericListItem ) );
+                    --uxCurrentNumberOfTasks;
+                    --uxTasksDeleted;
+                }
+                portEXIT_CRITICAL();
+
+                prvDeleteTCB( pxTCB );
+            }
+        }
+    }
+    #endif
+}
+/*-----------------------------------------------------------*/
+
+static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )
+{
+tskTCB *pxNewTCB;
+
+    /* Allocate space for the TCB.  Where the memory comes from depends on
+    the implementation of the port malloc function. */
+    pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) );
+
+    if( pxNewTCB != NULL )
+    {
+        /* Allocate space for the stack used by the task being created.
+        The base of the stack memory stored in the TCB so the task can
+        be deleted later if required. */
+        pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer );
+
+        if( pxNewTCB->pxStack == NULL )
+        {
+            /* Could not allocate the stack.  Delete the allocated TCB. */
+            vPortFree( pxNewTCB );
+            pxNewTCB = NULL;
+        }
+        else
+        {
+            /* Just to help debugging. */
+            memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) );
+        }
+    }
+
+    return pxNewTCB;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+    static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus )
+    {
+    volatile tskTCB *pxNextTCB, *pxFirstTCB;
+    unsigned short usStackRemaining;
+
+        /* Write the details of all the TCB's in pxList into the buffer. */
+        listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
+        do
+        {
+            listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
+            #if ( portSTACK_GROWTH > 0 )
+            {
+                usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack );
+            }
+            #else
+            {
+                usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );
+            }
+            #endif            
+            
+            sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber );
+            strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString );
+
+        } while( pxNextTCB != pxFirstTCB );
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+    static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )
+    {
+    volatile tskTCB *pxNextTCB, *pxFirstTCB;
+    unsigned long ulStatsAsPercentage;
+
+        /* Write the run time stats of all the TCB's in pxList into the buffer. */
+        listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
+        do
+        {
+            /* Get next TCB in from the list. */
+            listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
+
+            /* Divide by zero check. */
+            if( ulTotalRunTime > 0UL )
+            {
+                /* Has the task run at all? */
+                if( pxNextTCB->ulRunTimeCounter == 0 )
+                {
+                    /* The task has used no CPU time at all. */
+                    sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );
+                }
+                else
+                {
+                    /* What percentage of the total run time as the task used?
+                    This will always be rounded down to the nearest integer. */
+                    ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime;
+
+                    if( ulStatsAsPercentage > 0UL )
+                    {
+                        sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
+                    }
+                    else
+                    {
+                        /* If the percentage is zero here then the task has
+                        consumed less than 1% of the total run time. */
+                        sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter );
+                    }
+                }
+
+                strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );
+            }
+
+        } while( pxNextTCB != pxFirstTCB );
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
+
+    static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte )
+    {
+    register unsigned short usCount = 0;
+
+        while( *pucStackByte == tskSTACK_FILL_BYTE )
+        {
+            pucStackByte -= portSTACK_GROWTH;
+            usCount++;
+        }
+
+        usCount /= sizeof( portSTACK_TYPE );
+
+        return usCount;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
+
+    unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )
+    {
+    tskTCB *pxTCB;
+    unsigned char *pcEndOfStack;
+    unsigned portBASE_TYPE uxReturn;
+
+        pxTCB = prvGetTCBFromHandle( xTask );
+
+        #if portSTACK_GROWTH < 0
+        {
+            pcEndOfStack = ( unsigned char * ) pxTCB->pxStack;
+        }
+        #else
+        {
+            pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack;
+        }
+        #endif
+
+        uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack );
+
+        return uxReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+
+    static void prvDeleteTCB( tskTCB *pxTCB )
+    {
+        /* Free up the memory allocated by the scheduler for the task.  It is up to
+        the task to free any memory allocated at the application level. */
+        vPortFreeAligned( pxTCB->pxStack );
+        vPortFree( pxTCB );
+    }
+
+#endif
+
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
+
+    xTaskHandle xTaskGetCurrentTaskHandle( void )
+    {
+    xTaskHandle xReturn;
+
+        /* A critical section is not required as this is not called from
+        an interrupt and the current TCB will always be the same for any
+        individual execution thread. */
+        xReturn = pxCurrentTCB;
+
+        return xReturn;
+    }
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskGetSchedulerState == 1 )
+
+    portBASE_TYPE xTaskGetSchedulerState( void )
+    {
+    portBASE_TYPE xReturn;
+
+        if( xSchedulerRunning == pdFALSE )
+        {
+            xReturn = taskSCHEDULER_NOT_STARTED;
+        }
+        else
+        {
+            if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
+            {
+                xReturn = taskSCHEDULER_RUNNING;
+            }
+            else
+            {
+                xReturn = taskSCHEDULER_SUSPENDED;
+            }
+        }
+
+        return xReturn;
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+    void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )
+    {
+    tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
+
+        if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
+        {
+            /* Adjust the mutex holder state to account for its new priority. */
+            listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );
+
+            /* If the task being modified is in the ready state it will need to
+            be moved in to a new list. */
+            if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) )
+            {
+                vListRemove( &( pxTCB->xGenericListItem ) );
+
+                /* Inherit the priority before being moved into the new list. */
+                pxTCB->uxPriority = pxCurrentTCB->uxPriority;
+                prvAddTaskToReadyQueue( pxTCB );
+            }
+            else
+            {
+                /* Just inherit the priority. */
+                pxTCB->uxPriority = pxCurrentTCB->uxPriority;
+            }
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+    void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )
+    {
+    tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
+
+        if( pxMutexHolder != NULL )
+        {
+            if( pxTCB->uxPriority != pxTCB->uxBasePriority )
+            {
+                /* We must be the running task to be able to give the mutex back.
+                Remove ourselves from the ready list we currently appear in. */
+                vListRemove( &( pxTCB->xGenericListItem ) );
+
+                /* Disinherit the priority before adding ourselves into the new
+                ready list. */
+                pxTCB->uxPriority = pxTCB->uxBasePriority;
+                listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );
+                prvAddTaskToReadyQueue( pxTCB );
+            }
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+
+    void vTaskEnterCritical( void )
+    {
+        portDISABLE_INTERRUPTS();
+
+        if( xSchedulerRunning != pdFALSE )
+        {
+            pxCurrentTCB->uxCriticalNesting++;
+        }
+    }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+
+void vTaskExitCritical( void )
+{
+    if( xSchedulerRunning != pdFALSE )
+    {
+        if( pxCurrentTCB->uxCriticalNesting > 0 )
+        {
+            pxCurrentTCB->uxCriticalNesting--;
+
+            if( pxCurrentTCB->uxCriticalNesting == 0 )
+            {
+                portENABLE_INTERRUPTS();
+            }
+        }
+    }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+
diff -r 000000000000 -r d4960fcea8ff FreeRTOSConfig.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreeRTOSConfig.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,215 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ *  Modified for mbed & Xpresso NXP LPC1768 board
+ *  By Kenji Arai / JH1PJL on March 9th,2010
+ *      August 1st,2010
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC17xx.h"
+
+#define portREMOVE_STATIC_QUALIFIER
+
+// Modified by  Kenji Arai / JH1PJL, August 28th,2010
+/*-----------------------------------------------------------
+ * Board Selection
+ *-----------------------------------------------------------*/
+#define USE_XPRESSO 0
+#define USE_MBED    1
+
+// Modified by  Kenji Arai / JH1PJL, September 10th,2010
+/*-----------------------------------------------------------
+ * ADC mode selection
+ *-----------------------------------------------------------*/
+#define CH_GSEN_ONLY 1
+
+// Modified by  Kenji Arai / JH1PJL, August 22nd,2010
+/*-----------------------------------------------------------
+ * AHB Memory usage
+ *-----------------------------------------------------------*/
+#define USE_AHB_RAM 1
+
+// Modified by  Kenji Arai / JH1PJL, September 18th,2010
+/*-----------------------------------------------------------
+ * Monitor interface
+ *-----------------------------------------------------------*/
+#define MON_VIA_USB    0
+#define MON_VIA_UART 1
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION        1
+#define configUSE_IDLE_HOOK            0
+#define configMAX_PRIORITIES        ( ( unsigned portBASE_TYPE ) 5 )
+#define configUSE_TICK_HOOK            1
+// Modified by  Kenji Arai / JH1PJL, May 2nd,2010
+#define configCPU_CLOCK_HZ            ( ( unsigned long ) 99000000 )
+//#define configCPU_CLOCK_HZ        ( ( unsigned long ) 100000000 )
+#define configTICK_RATE_HZ            ( ( portTickType ) 1000 )
+#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 64 )
+// Modified by  Kenji Arai / JH1PJL, August 13th,2010
+#define configMIN_STACK_SIZE        ( ( unsigned short ) 80 )
+#define configMID_STACK_SIZE        ( ( unsigned short ) 120 )
+#define configMAX_STACK_SIZE        ( ( unsigned short ) 180 )
+
+// Modified by  Kenji Arai / JH1PJL, May 8th,2010
+//#define configTOTAL_HEAP_SIZE        ( ( size_t ) ( 17 * 1024 ) )
+//    back to original August 18th, 2010
+//#define configTOTAL_HEAP_SIZE        ( ( size_t ) ( 19 * 1024 ) )
+//    more bigger August 18th, 2010
+#define configTOTAL_HEAP_SIZE        ( ( size_t ) ( 22 * 1024 ) )
+#define configMAX_TASK_NAME_LEN        ( 12 )
+#define configUSE_TRACE_FACILITY    1
+#define configUSE_16_BIT_TICKS        0
+#define configIDLE_SHOULD_YIELD        0
+#define configUSE_CO_ROUTINES         0
+#define configUSE_MUTEXES            1
+
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+#define configUSE_COUNTING_SEMAPHORES     0
+#define configUSE_ALTERNATIVE_API         0
+#define configCHECK_FOR_STACK_OVERFLOW    2
+#define configUSE_RECURSIVE_MUTEXES        1
+#define configQUEUE_REGISTRY_SIZE        10
+#define configGENERATE_RUN_TIME_STATS    1
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+
+#define INCLUDE_vTaskPrioritySet            1
+#define INCLUDE_uxTaskPriorityGet            1
+#define INCLUDE_vTaskDelete                    1
+#define INCLUDE_vTaskCleanUpResources        0
+#define INCLUDE_vTaskSuspend                1
+#define INCLUDE_vTaskDelayUntil                1
+#define INCLUDE_vTaskDelay                    1
+#define INCLUDE_uxTaskGetStackHighWaterMark    1
+
+/*-----------------------------------------------------------
+ * Ethernet configuration.
+ *-----------------------------------------------------------*/
+
+/* MAC address configuration. */
+#define configMAC_ADDR0    0x00
+#define configMAC_ADDR1    0x12
+#define configMAC_ADDR2    0x13
+#define configMAC_ADDR3    0x10
+#define configMAC_ADDR4    0x15
+#define configMAC_ADDR5    0x11
+
+/* IP address configuration. */
+#define configIP_ADDR0        192
+#define configIP_ADDR1        168
+// Modified by  Kenji Arai / JH1PJL, March 9th,2010
+//#define configIP_ADDR2    0
+#define configIP_ADDR2        1
+//#define configIP_ADDR3    201
+#define configIP_ADDR3        22
+
+/* Netmask configuration. */
+#define configNET_MASK0        255
+#define configNET_MASK1        255
+#define configNET_MASK2        255
+#define configNET_MASK3        0
+
+/* Use the system definition, if there is one */
+#ifdef __NVIC_PRIO_BITS
+    #define configPRIO_BITS       __NVIC_PRIO_BITS
+#else
+    #define configPRIO_BITS       5        /* 32 priority levels */
+#endif
+
+/* The lowest priority. */
+#define configKERNEL_INTERRUPT_PRIORITY     ( 31 << (8 - configPRIO_BITS) )
+/* Priority 5, or 160 as only the top three bits are implemented. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( 5 << (8 - configPRIO_BITS) )
+
+/* Priorities passed to NVIC_SetPriority() do not require shifting as the
+function does the shifting itself.  Note these priorities need to be equal to
+or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric
+value needs to be equal to or greater than 5 (on the Cortex M3 the lower the
+numeric value the higher the interrupt priority). */
+#define configEMAC_INTERRUPT_PRIORITY        5
+#define configUSB_INTERRUPT_PRIORITY        6
+
+
+/*-----------------------------------------------------------
+ * Macros required to setup the timer for the run time status.
+ *-----------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void vConfigureTimerForRunTimeStats( void );
+#ifdef __cplusplus
+}
+#endif
+//extern void vConfigureTimerForRunTimeStats( void );
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
+// Modified by K.Arai April 11th, 2010
+#define portGET_RUN_TIME_COUNTER_VALUE() LPC_TIM0->TC
+
+
+#endif /* FREERTOS_CONFIG_H */
diff -r 000000000000 -r d4960fcea8ff LPC17xx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LPC17xx.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,1103 @@
+/******************************************************************************
+ * @file:    LPC17xx.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for 
+ *           NXP LPC17xx Device Series 
+ * @version: V1.04
+ * @date:    2. July 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2008 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __LPC17xx_H__
+#define __LPC17xx_H__
+/////////////////////////////////////////////////////////////////////////////
+/* System Control Block (SCB) includes:
+   Flash Accelerator Module, Clocking and Power Control, External Interrupts,
+   Reset, System Control and Status
+*/
+/*
+ *  Modified by following information
+ *      http://www.onarm.com/download/download395.asp
+ *
+ *  By Kenji Arai / JH1PJL on April 11th,2010
+ *      April 11th,2010
+ */
+
+#define SCB_BASE_ADDR   0x400FC000
+#define PCONP_PCTIM0    0x00000002
+#define PCONP_PCTIM1    0x00000004
+#define PCONP_PCUART0   0x00000008
+#define PCONP_PCUART1   0x00000010
+#define PCONP_PCPWM1    0x00000040
+#define PCONP_PCI2C0    0x00000080
+#define PCONP_PCSPI     0x00000100
+#define PCONP_PCRTC     0x00000200
+#define PCONP_PCSSP1    0x00000400
+#define PCONP_PCAD      0x00001000
+#define PCONP_PCCAN1    0x00002000
+#define PCONP_PCCAN2    0x00004000
+#define PCONP_PCGPIO    0x00008000
+#define PCONP_PCRIT     0x00010000
+#define PCONP_PCMCPWM   0x00020000
+#define PCONP_PCQEI     0x00040000
+#define PCONP_PCI2C1    0x00080000
+#define PCONP_PCSSP0    0x00200000
+#define PCONP_PCTIM2    0x00400000
+#define PCONP_PCTIM3    0x00800000
+#define PCONP_PCUART2   0x01000000
+#define PCONP_PCUART3   0x02000000
+#define PCONP_PCI2C2    0x04000000
+#define PCONP_PCI2S     0x08000000
+#define PCONP_PCGPDMA   0x20000000
+#define PCONP_PCENET    0x40000000
+#define PCONP_PCUSB     0x80000000
+
+#define PLLCON_PLLE     0x00000001
+#define PLLCON_PLLC     0x00000002
+#define PLLCON_MASK     0x00000003
+
+#define PLLCFG_MUL1     0x00000000
+#define PLLCFG_MUL2     0x00000001
+#define PLLCFG_MUL3     0x00000002
+#define PLLCFG_MUL4     0x00000003
+#define PLLCFG_MUL5     0x00000004
+#define PLLCFG_MUL6     0x00000005
+#define PLLCFG_MUL7     0x00000006
+#define PLLCFG_MUL8     0x00000007
+#define PLLCFG_MUL9     0x00000008
+#define PLLCFG_MUL10    0x00000009
+#define PLLCFG_MUL11    0x0000000A
+#define PLLCFG_MUL12    0x0000000B
+#define PLLCFG_MUL13    0x0000000C
+#define PLLCFG_MUL14    0x0000000D
+#define PLLCFG_MUL15    0x0000000E
+#define PLLCFG_MUL16    0x0000000F
+#define PLLCFG_MUL17    0x00000010
+#define PLLCFG_MUL18    0x00000011
+#define PLLCFG_MUL19    0x00000012
+#define PLLCFG_MUL20    0x00000013
+#define PLLCFG_MUL21    0x00000014
+#define PLLCFG_MUL22    0x00000015
+#define PLLCFG_MUL23    0x00000016
+#define PLLCFG_MUL24    0x00000017
+#define PLLCFG_MUL25    0x00000018
+#define PLLCFG_MUL26    0x00000019
+#define PLLCFG_MUL27    0x0000001A
+#define PLLCFG_MUL28    0x0000001B
+#define PLLCFG_MUL29    0x0000001C
+#define PLLCFG_MUL30    0x0000001D
+#define PLLCFG_MUL31    0x0000001E
+#define PLLCFG_MUL32    0x0000001F
+#define PLLCFG_MUL33    0x00000020
+#define PLLCFG_MUL34    0x00000021
+#define PLLCFG_MUL35    0x00000022
+#define PLLCFG_MUL36    0x00000023
+
+#define PLLCFG_DIV1     0x00000000
+#define PLLCFG_DIV2     0x00010000
+#define PLLCFG_DIV3     0x00020000
+#define PLLCFG_DIV4     0x00030000
+#define PLLCFG_DIV5     0x00040000
+#define PLLCFG_DIV6     0x00050000
+#define PLLCFG_DIV7     0x00060000
+#define PLLCFG_DIV8     0x00070000
+#define PLLCFG_DIV9     0x00080000
+#define PLLCFG_DIV10    0x00090000
+#define PLLCFG_MASK        0x00FF7FFF
+
+#define PLLSTAT_MSEL_MASK    0x00007FFF
+#define PLLSTAT_NSEL_MASK    0x00FF0000
+
+#define PLLSTAT_PLLE    (1 << 24)
+#define PLLSTAT_PLLC    (1 << 25)
+#define PLLSTAT_PLOCK    (1 << 26)
+
+#define PLLFEED_FEED1   0x000000AA
+#define PLLFEED_FEED2   0x00000055
+
+#define NVIC_IRQ_WDT         0u         // IRQ0,  exception number 16
+#define NVIC_IRQ_TIMER0      1u         // IRQ1,  exception number 17
+#define NVIC_IRQ_TIMER1      2u         // IRQ2,  exception number 18
+#define NVIC_IRQ_TIMER2      3u         // IRQ3,  exception number 19
+#define NVIC_IRQ_TIMER3      4u         // IRQ4,  exception number 20
+#define NVIC_IRQ_UART0       5u         // IRQ5,  exception number 21
+#define NVIC_IRQ_UART1       6u         // IRQ6,  exception number 22
+#define NVIC_IRQ_UART2       7u         // IRQ7,  exception number 23
+#define NVIC_IRQ_UART3       8u         // IRQ8,  exception number 24
+#define NVIC_IRQ_PWM1        9u         // IRQ9,  exception number 25
+#define NVIC_IRQ_I2C0        10u        // IRQ10, exception number 26
+#define NVIC_IRQ_I2C1        11u        // IRQ11, exception number 27
+#define NVIC_IRQ_I2C2        12u        // IRQ12, exception number 28
+#define NVIC_IRQ_SPI         13u        // IRQ13, exception number 29
+#define NVIC_IRQ_SSP0        14u        // IRQ14, exception number 30
+#define NVIC_IRQ_SSP1        15u        // IRQ15, exception number 31
+#define NVIC_IRQ_PLL0        16u        // IRQ16, exception number 32
+#define NVIC_IRQ_RTC         17u        // IRQ17, exception number 33
+#define NVIC_IRQ_EINT0       18u        // IRQ18, exception number 34
+#define NVIC_IRQ_EINT1       19u        // IRQ19, exception number 35
+#define NVIC_IRQ_EINT2       20u        // IRQ20, exception number 36
+#define NVIC_IRQ_EINT3       21u        // IRQ21, exception number 37
+#define NVIC_IRQ_ADC         22u        // IRQ22, exception number 38
+#define NVIC_IRQ_BOD         23u        // IRQ23, exception number 39
+#define NVIC_IRQ_USB         24u        // IRQ24, exception number 40
+#define NVIC_IRQ_CAN         25u        // IRQ25, exception number 41
+#define NVIC_IRQ_GPDMA       26u        // IRQ26, exception number 42
+#define NVIC_IRQ_I2S         27u        // IRQ27, exception number 43
+#define NVIC_IRQ_ETHERNET    28u        // IRQ28, exception number 44
+#define NVIC_IRQ_RIT         29u        // IRQ29, exception number 45
+#define NVIC_IRQ_MCPWM       30u        // IRQ30, exception number 46
+#define NVIC_IRQ_QE          31u        // IRQ31, exception number 47
+#define NVIC_IRQ_PLL1        32u        // IRQ32, exception number 48
+#define NVIC_IRQ_USB_ACT     33u        // IRQ33, exception number 49
+#define NVIC_IRQ_CAN_ACT     34u        // IRQ34, exception number 50
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+typedef enum IRQn
+{
+/******  Cortex-M3 Processor Exceptions Numbers ***************************************************/
+  NonMaskableInt_IRQn           = -14,      /*!< 2 Non Maskable Interrupt                         */
+  MemoryManagement_IRQn         = -12,      /*!< 4 Cortex-M3 Memory Management Interrupt          */
+  BusFault_IRQn                 = -11,      /*!< 5 Cortex-M3 Bus Fault Interrupt                  */
+  UsageFault_IRQn               = -10,      /*!< 6 Cortex-M3 Usage Fault Interrupt                */
+  SVCall_IRQn                   = -5,       /*!< 11 Cortex-M3 SV Call Interrupt                   */
+  DebugMonitor_IRQn             = -4,       /*!< 12 Cortex-M3 Debug Monitor Interrupt             */
+  PendSV_IRQn                   = -2,       /*!< 14 Cortex-M3 Pend SV Interrupt                   */
+  SysTick_IRQn                  = -1,       /*!< 15 Cortex-M3 System Tick Interrupt               */
+
+/******  LPC17xx Specific Interrupt Numbers *******************************************************/
+  WDT_IRQn                      = 0,        /*!< Watchdog Timer Interrupt                         */
+  TIMER0_IRQn                   = 1,        /*!< Timer0 Interrupt                                 */
+  TIMER1_IRQn                   = 2,        /*!< Timer1 Interrupt                                 */
+  TIMER2_IRQn                   = 3,        /*!< Timer2 Interrupt                                 */
+  TIMER3_IRQn                   = 4,        /*!< Timer3 Interrupt                                 */
+  UART0_IRQn                    = 5,        /*!< UART0 Interrupt                                  */
+  UART1_IRQn                    = 6,        /*!< UART1 Interrupt                                  */
+  UART2_IRQn                    = 7,        /*!< UART2 Interrupt                                  */
+  UART3_IRQn                    = 8,        /*!< UART3 Interrupt                                  */
+  PWM1_IRQn                     = 9,        /*!< PWM1 Interrupt                                   */
+  I2C0_IRQn                     = 10,       /*!< I2C0 Interrupt                                   */
+  I2C1_IRQn                     = 11,       /*!< I2C1 Interrupt                                   */
+  I2C2_IRQn                     = 12,       /*!< I2C2 Interrupt                                   */
+  SPI_IRQn                      = 13,       /*!< SPI Interrupt                                    */
+  SSP0_IRQn                     = 14,       /*!< SSP0 Interrupt                                   */
+  SSP1_IRQn                     = 15,       /*!< SSP1 Interrupt                                   */
+  PLL0_IRQn                     = 16,       /*!< PLL0 Lock (Main PLL) Interrupt                   */
+  RTC_IRQn                      = 17,       /*!< Real Time Clock Interrupt                        */
+  EINT0_IRQn                    = 18,       /*!< External Interrupt 0 Interrupt                   */
+  EINT1_IRQn                    = 19,       /*!< External Interrupt 1 Interrupt                   */
+  EINT2_IRQn                    = 20,       /*!< External Interrupt 2 Interrupt                   */
+  EINT3_IRQn                    = 21,       /*!< External Interrupt 3 Interrupt                   */
+  ADC_IRQn                      = 22,       /*!< A/D Converter Interrupt                          */
+  BOD_IRQn                      = 23,       /*!< Brown-Out Detect Interrupt                       */
+  USB_IRQn                      = 24,       /*!< USB Interrupt                                    */
+  CAN_IRQn                      = 25,       /*!< CAN Interrupt                                    */
+  DMA_IRQn                      = 26,       /*!< General Purpose DMA Interrupt                    */
+  I2S_IRQn                      = 27,       /*!< I2S Interrupt                                    */
+  ENET_IRQn                     = 28,       /*!< Ethernet Interrupt                               */
+  RIT_IRQn                      = 29,       /*!< Repetitive Interrupt Timer Interrupt             */
+  MCPWM_IRQn                    = 30,       /*!< Motor Control PWM Interrupt                      */
+  QEI_IRQn                      = 31,       /*!< Quadrature Encoder Interface Interrupt           */
+  PLL1_IRQn                     = 32,       /*!< PLL1 Lock (USB PLL) Interrupt                    */
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */
+#define __MPU_PRESENT             1         /*!< MPU present or not                               */
+#define __NVIC_PRIO_BITS          5         /*!< Number of Bits used for Priority Levels          */
+#define __Vendor_SysTickConfig    0         /*!< Set to 1 if different SysTick Config is used     */
+
+
+//#include <core_cm3.h>                       /* Cortex-M3 processor and core peripherals           */
+#include "core_cm3.h"    // by roger
+
+/******************************************************************************/
+/*                Device Specific Peripheral registers structures             */
+/******************************************************************************/
+
+#pragma anon_unions
+
+/*------------- System Control (SC) ------------------------------------------*/
+typedef struct
+{
+  __IO uint32_t FLASHCFG;               /* Flash Accelerator Module           */
+       uint32_t RESERVED0[31];
+  __IO uint32_t PLL0CON;                /* Clocking and Power Control         */
+  __IO uint32_t PLL0CFG;
+  __I  uint32_t PLL0STAT;
+  __O  uint32_t PLL0FEED;
+       uint32_t RESERVED1[4];
+  __IO uint32_t PLL1CON;
+  __IO uint32_t PLL1CFG;
+  __I  uint32_t PLL1STAT;
+  __O  uint32_t PLL1FEED;
+       uint32_t RESERVED2[4];
+  __IO uint32_t PCON;
+  __IO uint32_t PCONP;
+       uint32_t RESERVED3[15];
+  __IO uint32_t CCLKCFG;
+  __IO uint32_t USBCLKCFG;
+  __IO uint32_t CLKSRCSEL;
+       uint32_t RESERVED4[12];
+  __IO uint32_t EXTINT;                 /* External Interrupts                */
+       uint32_t RESERVED5;
+  __IO uint32_t EXTMODE;
+  __IO uint32_t EXTPOLAR;
+       uint32_t RESERVED6[12];
+  __IO uint32_t RSID;                   /* Reset                              */
+       uint32_t RESERVED7[7];
+  __IO uint32_t SCS;                    /* Syscon Miscellaneous Registers     */
+  __IO uint32_t IRCTRIM;                /* Clock Dividers                     */
+  __IO uint32_t PCLKSEL0;
+  __IO uint32_t PCLKSEL1;
+       uint32_t RESERVED8[4];
+  __IO uint32_t USBIntSt;               /* USB Device/OTG Interrupt Register  */
+       uint32_t RESERVED9;
+  __IO uint32_t CLKOUTCFG;              /* Clock Output Configuration         */
+ } LPC_SC_TypeDef;
+
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/
+typedef struct
+{
+  __IO uint32_t PINSEL0;
+  __IO uint32_t PINSEL1;
+  __IO uint32_t PINSEL2;
+  __IO uint32_t PINSEL3;
+  __IO uint32_t PINSEL4;
+  __IO uint32_t PINSEL5;
+  __IO uint32_t PINSEL6;
+  __IO uint32_t PINSEL7;
+  __IO uint32_t PINSEL8;
+  __IO uint32_t PINSEL9;
+  __IO uint32_t PINSEL10;
+       uint32_t RESERVED0[5];
+  __IO uint32_t PINMODE0;
+  __IO uint32_t PINMODE1;
+  __IO uint32_t PINMODE2;
+  __IO uint32_t PINMODE3;
+  __IO uint32_t PINMODE4;
+  __IO uint32_t PINMODE5;
+  __IO uint32_t PINMODE6;
+  __IO uint32_t PINMODE7;
+  __IO uint32_t PINMODE8;
+  __IO uint32_t PINMODE9;
+  __IO uint32_t PINMODE_OD0;
+  __IO uint32_t PINMODE_OD1;
+  __IO uint32_t PINMODE_OD2;
+  __IO uint32_t PINMODE_OD3;
+  __IO uint32_t PINMODE_OD4;
+  __IO uint32_t I2CPADCFG;
+} LPC_PINCON_TypeDef;
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+typedef struct
+{
+  __IO uint32_t FIODIR;
+       uint32_t RESERVED0[3];
+  __IO uint32_t FIOMASK;
+  __IO uint32_t FIOPIN;
+  __IO uint32_t FIOSET;
+  __O  uint32_t FIOCLR;
+} LPC_GPIO_TypeDef;
+
+typedef struct
+{
+  __I  uint32_t IntStatus;
+  __I  uint32_t IO0IntStatR;
+  __I  uint32_t IO0IntStatF;
+  __O  uint32_t IO0IntClr;
+  __IO uint32_t IO0IntEnR;
+  __IO uint32_t IO0IntEnF;
+       uint32_t RESERVED0[3];
+  __I  uint32_t IO2IntStatR;
+  __I  uint32_t IO2IntStatF;
+  __O  uint32_t IO2IntClr;
+  __IO uint32_t IO2IntEnR;
+  __IO uint32_t IO2IntEnF;
+} LPC_GPIOINT_TypeDef;
+
+/*------------- Timer (TIM) --------------------------------------------------*/
+typedef struct
+{
+  __IO uint32_t IR;
+  __IO uint32_t TCR;
+  __IO uint32_t TC;
+  __IO uint32_t PR;
+  __IO uint32_t PC;
+  __IO uint32_t MCR;
+  __IO uint32_t MR0;
+  __IO uint32_t MR1;
+  __IO uint32_t MR2;
+  __IO uint32_t MR3;
+  __IO uint32_t CCR;
+  __I  uint32_t CR0;
+  __I  uint32_t CR1;
+       uint32_t RESERVED0[2];
+  __IO uint32_t EMR;
+       uint32_t RESERVED1[12];
+  __IO uint32_t CTCR;
+} LPC_TIM_TypeDef;
+
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/
+typedef struct
+{
+  __IO uint32_t IR;
+  __IO uint32_t TCR;
+  __IO uint32_t TC;
+  __IO uint32_t PR;
+  __IO uint32_t PC;
+  __IO uint32_t MCR;
+  __IO uint32_t MR0;
+  __IO uint32_t MR1;
+  __IO uint32_t MR2;
+  __IO uint32_t MR3;
+  __IO uint32_t CCR;
+  __I  uint32_t CR0;
+  __I  uint32_t CR1;
+  __I  uint32_t CR2;
+  __I  uint32_t CR3;
+       uint32_t RESERVED0;
+  __IO uint32_t MR4;
+  __IO uint32_t MR5;
+  __IO uint32_t MR6;
+  __IO uint32_t PCR;
+  __IO uint32_t LER;
+       uint32_t RESERVED1[7];
+  __IO uint32_t CTCR;
+} LPC_PWM_TypeDef;
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+typedef struct
+{
+  union {
+  __I  uint8_t  RBR;
+  __O  uint8_t  THR;
+  __IO uint8_t  DLL;
+       uint32_t RESERVED0;
+  };
+  union {
+  __IO uint8_t  DLM;
+  __IO uint32_t IER;
+  };
+  union {
+  __I  uint32_t IIR;
+  __O  uint8_t  FCR;
+  };
+  __IO uint8_t  LCR;
+       uint8_t  RESERVED1[7];
+  __I  uint8_t  LSR;
+       uint8_t  RESERVED2[7];
+  __IO uint8_t  SCR;
+       uint8_t  RESERVED3[3];
+  __IO uint32_t ACR;
+  __IO uint8_t  ICR;
+       uint8_t  RESERVED4[3];
+  __IO uint8_t  FDR;
+       uint8_t  RESERVED5[7];
+  __IO uint8_t  TER;
+       uint8_t  RESERVED6[39];
+  __I  uint8_t  FIFOLVL;
+} LPC_UART_TypeDef;
+
+typedef struct
+{
+  union {
+  __I  uint8_t  RBR;
+  __O  uint8_t  THR;
+  __IO uint8_t  DLL;
+       uint32_t RESERVED0;
+  };
+  union {
+  __IO uint8_t  DLM;
+  __IO uint32_t IER;
+  };
+  union {
+  __I  uint32_t IIR;
+  __O  uint8_t  FCR;
+  };
+  __IO uint8_t  LCR;
+       uint8_t  RESERVED1[7];
+  __I  uint8_t  LSR;
+       uint8_t  RESERVED2[7];
+  __IO uint8_t  SCR;
+       uint8_t  RESERVED3[3];
+  __IO uint32_t ACR;
+  __IO uint8_t  ICR;
+       uint8_t  RESERVED4[3];
+  __IO uint8_t  FDR;
+       uint8_t  RESERVED5[7];
+  __IO uint8_t  TER;
+       uint8_t  RESERVED6[39];
+  __I  uint8_t  FIFOLVL;
+       uint8_t  RESERVED7[363];
+  __IO uint32_t DMAREQSEL;
+} LPC_UART0_TypeDef;
+
+typedef struct
+{
+  union {
+  __I  uint8_t  RBR;
+  __O  uint8_t  THR;
+  __IO uint8_t  DLL;
+       uint32_t RESERVED0;
+  };
+  union {
+  __IO uint8_t  DLM;
+  __IO uint32_t IER;
+  };
+  union {
+  __I  uint32_t IIR;
+  __O  uint8_t  FCR;
+  };
+  __IO uint8_t  LCR;
+       uint8_t  RESERVED1[3];
+  __IO uint8_t  MCR;
+       uint8_t  RESERVED2[3];
+  __I  uint8_t  LSR;
+       uint8_t  RESERVED3[3];
+  __I  uint8_t  MSR;
+       uint8_t  RESERVED4[3];
+  __IO uint8_t  SCR;
+       uint8_t  RESERVED5[3];
+  __IO uint32_t ACR;
+       uint32_t RESERVED6;
+  __IO uint32_t FDR;
+       uint32_t RESERVED7;
+  __IO uint8_t  TER;
+       uint8_t  RESERVED8[27];
+  __IO uint8_t  RS485CTRL;
+       uint8_t  RESERVED9[3];
+  __IO uint8_t  ADRMATCH;
+       uint8_t  RESERVED10[3];
+  __IO uint8_t  RS485DLY;
+       uint8_t  RESERVED11[3];
+  __I  uint8_t  FIFOLVL;
+} LPC_UART1_TypeDef;
+
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/
+typedef struct
+{
+  __IO uint32_t SPCR;
+  __I  uint32_t SPSR;
+  __IO uint32_t SPDR;
+  __IO uint32_t SPCCR;
+       uint32_t RESERVED0[3];
+  __IO uint32_t SPINT;
+} LPC_SPI_TypeDef;
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+typedef struct
+{
+  __IO uint32_t CR0;
+  __IO uint32_t CR1;
+  __IO uint32_t DR;
+  __I  uint32_t SR;
+  __IO uint32_t CPSR;
+  __IO uint32_t IMSC;
+  __IO uint32_t RIS;
+  __IO uint32_t MIS;
+  __IO uint32_t ICR;
+  __IO uint32_t DMACR;
+} LPC_SSP_TypeDef;
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+typedef struct
+{
+  __IO uint32_t I2CONSET;
+  __I  uint32_t I2STAT;
+  __IO uint32_t I2DAT;
+  __IO uint32_t I2ADR0;
+  __IO uint32_t I2SCLH;
+  __IO uint32_t I2SCLL;
+  __O  uint32_t I2CONCLR;
+  __IO uint32_t MMCTRL;
+  __IO uint32_t I2ADR1;
+  __IO uint32_t I2ADR2;
+  __IO uint32_t I2ADR3;
+  __I  uint32_t I2DATA_BUFFER;
+  __IO uint32_t I2MASK0;
+  __IO uint32_t I2MASK1;
+  __IO uint32_t I2MASK2;
+  __IO uint32_t I2MASK3;
+} LPC_I2C_TypeDef;
+
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/
+typedef struct
+{
+  __IO uint32_t I2SDAO;
+  __IO uint32_t I2SDAI;
+  __O  uint32_t I2STXFIFO;
+  __I  uint32_t I2SRXFIFO;
+  __I  uint32_t I2SSTATE;
+  __IO uint32_t I2SDMA1;
+  __IO uint32_t I2SDMA2;
+  __IO uint32_t I2SIRQ;
+  __IO uint32_t I2STXRATE;
+  __IO uint32_t I2SRXRATE;
+  __IO uint32_t I2STXBITRATE;
+  __IO uint32_t I2SRXBITRATE;
+  __IO uint32_t I2STXMODE;
+  __IO uint32_t I2SRXMODE;
+} LPC_I2S_TypeDef;
+
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/
+typedef struct
+{
+  __IO uint32_t RICOMPVAL;
+  __IO uint32_t RIMASK;
+  __IO uint8_t  RICTRL;
+       uint8_t  RESERVED0[3];
+  __IO uint32_t RICOUNTER;
+} LPC_RIT_TypeDef;
+
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/
+typedef struct
+{
+  __IO uint8_t  ILR;
+       uint8_t  RESERVED0[7];
+  __IO uint8_t  CCR;
+       uint8_t  RESERVED1[3];
+  __IO uint8_t  CIIR;
+       uint8_t  RESERVED2[3];
+  __IO uint8_t  AMR;
+       uint8_t  RESERVED3[3];
+  __I  uint32_t CTIME0;
+  __I  uint32_t CTIME1;
+  __I  uint32_t CTIME2;
+  __IO uint8_t  SEC;
+       uint8_t  RESERVED4[3];
+  __IO uint8_t  MIN;
+       uint8_t  RESERVED5[3];
+  __IO uint8_t  HOUR;
+       uint8_t  RESERVED6[3];
+  __IO uint8_t  DOM;
+       uint8_t  RESERVED7[3];
+  __IO uint8_t  DOW;
+       uint8_t  RESERVED8[3];
+  __IO uint16_t DOY;
+       uint16_t RESERVED9;
+  __IO uint8_t  MONTH;
+       uint8_t  RESERVED10[3];
+  __IO uint16_t YEAR;
+       uint16_t RESERVED11;
+  __IO uint32_t CALIBRATION;
+  __IO uint32_t GPREG0;
+  __IO uint32_t GPREG1;
+  __IO uint32_t GPREG2;
+  __IO uint32_t GPREG3;
+  __IO uint32_t GPREG4;
+  __IO uint8_t  RTC_AUXEN;
+       uint8_t  RESERVED12[3];
+  __IO uint8_t  RTC_AUX;
+       uint8_t  RESERVED13[3];
+  __IO uint8_t  ALSEC;
+       uint8_t  RESERVED14[3];
+  __IO uint8_t  ALMIN;
+       uint8_t  RESERVED15[3];
+  __IO uint8_t  ALHOUR;
+       uint8_t  RESERVED16[3];
+  __IO uint8_t  ALDOM;
+       uint8_t  RESERVED17[3];
+  __IO uint8_t  ALDOW;
+       uint8_t  RESERVED18[3];
+  __IO uint16_t ALDOY;
+       uint16_t RESERVED19;
+  __IO uint8_t  ALMON;
+       uint8_t  RESERVED20[3];
+  __IO uint16_t ALYEAR;
+       uint16_t RESERVED21;
+} LPC_RTC_TypeDef;
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+typedef struct
+{
+  __IO uint8_t  WDMOD;
+       uint8_t  RESERVED0[3];
+  __IO uint32_t WDTC;
+  __O  uint8_t  WDFEED;
+       uint8_t  RESERVED1[3];
+  __I  uint32_t WDTV;
+  __IO uint32_t WDCLKSEL;
+} LPC_WDT_TypeDef;
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+typedef struct
+{
+  __IO uint32_t ADCR;
+  __IO uint32_t ADGDR;
+       uint32_t RESERVED0;
+  __IO uint32_t ADINTEN;
+  __I  uint32_t ADDR0;
+  __I  uint32_t ADDR1;
+  __I  uint32_t ADDR2;
+  __I  uint32_t ADDR3;
+  __I  uint32_t ADDR4;
+  __I  uint32_t ADDR5;
+  __I  uint32_t ADDR6;
+  __I  uint32_t ADDR7;
+  __I  uint32_t ADSTAT;
+  __IO uint32_t ADTRM;
+} LPC_ADC_TypeDef;
+
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/
+typedef struct
+{
+  __IO uint32_t DACR;
+  __IO uint32_t DACCTRL;
+  __IO uint16_t DACCNTVAL;
+} LPC_DAC_TypeDef;
+
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/
+typedef struct
+{
+  __I  uint32_t MCCON;
+  __O  uint32_t MCCON_SET;
+  __O  uint32_t MCCON_CLR;
+  __I  uint32_t MCCAPCON;
+  __O  uint32_t MCCAPCON_SET;
+  __O  uint32_t MCCAPCON_CLR;
+  __IO uint32_t MCTIM0;
+  __IO uint32_t MCTIM1;
+  __IO uint32_t MCTIM2;
+  __IO uint32_t MCPER0;
+  __IO uint32_t MCPER1;
+  __IO uint32_t MCPER2;
+  __IO uint32_t MCPW0;
+  __IO uint32_t MCPW1;
+  __IO uint32_t MCPW2;
+  __IO uint32_t MCDEADTIME;
+  __IO uint32_t MCCCP;
+  __IO uint32_t MCCR0;
+  __IO uint32_t MCCR1;
+  __IO uint32_t MCCR2;
+  __I  uint32_t MCINTEN;
+  __O  uint32_t MCINTEN_SET;
+  __O  uint32_t MCINTEN_CLR;
+  __I  uint32_t MCCNTCON;
+  __O  uint32_t MCCNTCON_SET;
+  __O  uint32_t MCCNTCON_CLR;
+  __I  uint32_t MCINTFLAG;
+  __O  uint32_t MCINTFLAG_SET;
+  __O  uint32_t MCINTFLAG_CLR;
+  __O  uint32_t MCCAP_CLR;
+} LPC_MCPWM_TypeDef;
+
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/
+typedef struct
+{
+  __O  uint32_t QEICON;
+  __I  uint32_t QEISTAT;
+  __IO uint32_t QEICONF;
+  __I  uint32_t QEIPOS;
+  __IO uint32_t QEIMAXPOS;
+  __IO uint32_t CMPOS0;
+  __IO uint32_t CMPOS1;
+  __IO uint32_t CMPOS2;
+  __I  uint32_t INXCNT;
+  __IO uint32_t INXCMP;
+  __IO uint32_t QEILOAD;
+  __I  uint32_t QEITIME;
+  __I  uint32_t QEIVEL;
+  __I  uint32_t QEICAP;
+  __IO uint32_t VELCOMP;
+  __IO uint32_t FILTER;
+       uint32_t RESERVED0[998];
+  __O  uint32_t QEIIEC;
+  __O  uint32_t QEIIES;
+  __I  uint32_t QEIINTSTAT;
+  __I  uint32_t QEIIE;
+  __O  uint32_t QEICLR;
+  __O  uint32_t QEISET;
+} LPC_QEI_TypeDef;
+
+/*------------- Controller Area Network (CAN) --------------------------------*/
+typedef struct
+{
+  __IO uint32_t mask[512];              /* ID Masks                           */
+} LPC_CANAF_RAM_TypeDef;
+
+typedef struct                          /* Acceptance Filter Registers        */
+{
+  __IO uint32_t AFMR;
+  __IO uint32_t SFF_sa;
+  __IO uint32_t SFF_GRP_sa;
+  __IO uint32_t EFF_sa;
+  __IO uint32_t EFF_GRP_sa;
+  __IO uint32_t ENDofTable;
+  __I  uint32_t LUTerrAd;
+  __I  uint32_t LUTerr;
+  __IO uint32_t FCANIE;
+  __IO uint32_t FCANIC0;
+  __IO uint32_t FCANIC1;
+} LPC_CANAF_TypeDef;
+
+typedef struct                          /* Central Registers                  */
+{
+  __I  uint32_t CANTxSR;
+  __I  uint32_t CANRxSR;
+  __I  uint32_t CANMSR;
+} LPC_CANCR_TypeDef;
+
+typedef struct                          /* Controller Registers               */
+{
+  __IO uint32_t MOD;
+  __O  uint32_t CMR;
+  __IO uint32_t GSR;
+  __I  uint32_t ICR;
+  __IO uint32_t IER;
+  __IO uint32_t BTR;
+  __IO uint32_t EWL;
+  __I  uint32_t SR;
+  __IO uint32_t RFS;
+  __IO uint32_t RID;
+  __IO uint32_t RDA;
+  __IO uint32_t RDB;
+  __IO uint32_t TFI1;
+  __IO uint32_t TID1;
+  __IO uint32_t TDA1;
+  __IO uint32_t TDB1;
+  __IO uint32_t TFI2;
+  __IO uint32_t TID2;
+  __IO uint32_t TDA2;
+  __IO uint32_t TDB2;
+  __IO uint32_t TFI3;
+  __IO uint32_t TID3;
+  __IO uint32_t TDA3;
+  __IO uint32_t TDB3;
+} LPC_CAN_TypeDef;
+
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/
+typedef struct                          /* Common Registers                   */
+{
+  __I  uint32_t DMACIntStat;
+  __I  uint32_t DMACIntTCStat;
+  __O  uint32_t DMACIntTCClear;
+  __I  uint32_t DMACIntErrStat;
+  __O  uint32_t DMACIntErrClr;
+  __I  uint32_t DMACRawIntTCStat;
+  __I  uint32_t DMACRawIntErrStat;
+  __I  uint32_t DMACEnbldChns;
+  __IO uint32_t DMACSoftBReq;
+  __IO uint32_t DMACSoftSReq;
+  __IO uint32_t DMACSoftLBReq;
+  __IO uint32_t DMACSoftLSReq;
+  __IO uint32_t DMACConfig;
+  __IO uint32_t DMACSync;
+} LPC_GPDMA_TypeDef;
+
+typedef struct                          /* Channel Registers                  */
+{
+  __IO uint32_t DMACCSrcAddr;
+  __IO uint32_t DMACCDestAddr;
+  __IO uint32_t DMACCLLI;
+  __IO uint32_t DMACCControl;
+  __IO uint32_t DMACCConfig;
+} LPC_GPDMACH_TypeDef;
+
+/*------------- Universal Serial Bus (USB) -----------------------------------*/
+typedef struct
+{
+  __I  uint32_t HcRevision;             /* USB Host Registers                 */
+  __IO uint32_t HcControl;
+  __IO uint32_t HcCommandStatus;
+  __IO uint32_t HcInterruptStatus;
+  __IO uint32_t HcInterruptEnable;
+  __IO uint32_t HcInterruptDisable;
+  __IO uint32_t HcHCCA;
+  __I  uint32_t HcPeriodCurrentED;
+  __IO uint32_t HcControlHeadED;
+  __IO uint32_t HcControlCurrentED;
+  __IO uint32_t HcBulkHeadED;
+  __IO uint32_t HcBulkCurrentED;
+  __I  uint32_t HcDoneHead;
+  __IO uint32_t HcFmInterval;
+  __I  uint32_t HcFmRemaining;
+  __I  uint32_t HcFmNumber;
+  __IO uint32_t HcPeriodicStart;
+  __IO uint32_t HcLSTreshold;
+  __IO uint32_t HcRhDescriptorA;
+  __IO uint32_t HcRhDescriptorB;
+  __IO uint32_t HcRhStatus;
+  __IO uint32_t HcRhPortStatus1;
+  __IO uint32_t HcRhPortStatus2;
+       uint32_t RESERVED0[40];
+  __I  uint32_t Module_ID;
+
+  __I  uint32_t OTGIntSt;               /* USB On-The-Go Registers            */
+  __IO uint32_t OTGIntEn;
+  __O  uint32_t OTGIntSet;
+  __O  uint32_t OTGIntClr;
+  __IO uint32_t OTGStCtrl;
+  __IO uint32_t OTGTmr;
+       uint32_t RESERVED1[58];
+
+  __I  uint32_t USBDevIntSt;            /* USB Device Interrupt Registers     */
+  __IO uint32_t USBDevIntEn;
+  __O  uint32_t USBDevIntClr;
+  __O  uint32_t USBDevIntSet;
+
+  __O  uint32_t USBCmdCode;             /* USB Device SIE Command Registers   */
+  __I  uint32_t USBCmdData;
+
+  __I  uint32_t USBRxData;              /* USB Device Transfer Registers      */
+  __O  uint32_t USBTxData;
+  __I  uint32_t USBRxPLen;
+  __O  uint32_t USBTxPLen;
+  __IO uint32_t USBCtrl;
+  __O  uint32_t USBDevIntPri;
+
+  __I  uint32_t USBEpIntSt;             /* USB Device Endpoint Interrupt Regs */
+  __IO uint32_t USBEpIntEn;
+  __O  uint32_t USBEpIntClr;
+  __O  uint32_t USBEpIntSet;
+  __O  uint32_t USBEpIntPri;
+
+  __IO uint32_t USBReEp;                /* USB Device Endpoint Realization Reg*/
+  __O  uint32_t USBEpInd;
+  __IO uint32_t USBMaxPSize;
+
+  __I  uint32_t USBDMARSt;              /* USB Device DMA Registers           */
+  __O  uint32_t USBDMARClr;
+  __O  uint32_t USBDMARSet;
+       uint32_t RESERVED2[9];
+  __IO uint32_t USBUDCAH;
+  __I  uint32_t USBEpDMASt;
+  __O  uint32_t USBEpDMAEn;
+  __O  uint32_t USBEpDMADis;
+  __I  uint32_t USBDMAIntSt;
+  __IO uint32_t USBDMAIntEn;
+       uint32_t RESERVED3[2];
+  __I  uint32_t USBEoTIntSt;
+  __O  uint32_t USBEoTIntClr;
+  __O  uint32_t USBEoTIntSet;
+  __I  uint32_t USBNDDRIntSt;
+  __O  uint32_t USBNDDRIntClr;
+  __O  uint32_t USBNDDRIntSet;
+  __I  uint32_t USBSysErrIntSt;
+  __O  uint32_t USBSysErrIntClr;
+  __O  uint32_t USBSysErrIntSet;
+       uint32_t RESERVED4[15];
+
+  __I  uint32_t I2C_RX;                 /* USB OTG I2C Registers              */
+  __O  uint32_t I2C_WO;
+  __I  uint32_t I2C_STS;
+  __IO uint32_t I2C_CTL;
+  __IO uint32_t I2C_CLKHI;
+  __O  uint32_t I2C_CLKLO;
+       uint32_t RESERVED5[823];
+
+  union {
+  __IO uint32_t USBClkCtrl;             /* USB Clock Control Registers        */
+  __IO uint32_t OTGClkCtrl;
+  };
+  union {
+  __I  uint32_t USBClkSt;
+  __I  uint32_t OTGClkSt;
+  };
+} LPC_USB_TypeDef;
+
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/
+typedef struct
+{
+  __IO uint32_t MAC1;                   /* MAC Registers                      */
+  __IO uint32_t MAC2;
+  __IO uint32_t IPGT;
+  __IO uint32_t IPGR;
+  __IO uint32_t CLRT;
+  __IO uint32_t MAXF;
+  __IO uint32_t SUPP;
+  __IO uint32_t TEST;
+  __IO uint32_t MCFG;
+  __IO uint32_t MCMD;
+  __IO uint32_t MADR;
+  __O  uint32_t MWTD;
+  __I  uint32_t MRDD;
+  __I  uint32_t MIND;
+       uint32_t RESERVED0[2];
+  __IO uint32_t SA0;
+  __IO uint32_t SA1;
+  __IO uint32_t SA2;
+       uint32_t RESERVED1[45];
+  __IO uint32_t Command;                /* Control Registers                  */
+  __I  uint32_t Status;
+  __IO uint32_t RxDescriptor;
+  __IO uint32_t RxStatus;
+  __IO uint32_t RxDescriptorNumber;
+  __I  uint32_t RxProduceIndex;
+  __IO uint32_t RxConsumeIndex;
+  __IO uint32_t TxDescriptor;
+  __IO uint32_t TxStatus;
+  __IO uint32_t TxDescriptorNumber;
+  __IO uint32_t TxProduceIndex;
+  __I  uint32_t TxConsumeIndex;
+       uint32_t RESERVED2[10];
+  __I  uint32_t TSV0;
+  __I  uint32_t TSV1;
+  __I  uint32_t RSV;
+       uint32_t RESERVED3[3];
+  __IO uint32_t FlowControlCounter;
+  __I  uint32_t FlowControlStatus;
+       uint32_t RESERVED4[34];
+  __IO uint32_t RxFilterCtrl;           /* Rx Filter Registers                */
+  __IO uint32_t RxFilterWoLStatus;
+  __IO uint32_t RxFilterWoLClear;
+       uint32_t RESERVED5;
+  __IO uint32_t HashFilterL;
+  __IO uint32_t HashFilterH;
+       uint32_t RESERVED6[882];
+  __I  uint32_t IntStatus;              /* Module Control Registers           */
+  __IO uint32_t IntEnable;
+  __O  uint32_t IntClear;
+  __O  uint32_t IntSet;
+       uint32_t RESERVED7;
+  __IO uint32_t PowerDown;
+       uint32_t RESERVED8;
+  __IO uint32_t Module_ID;
+} LPC_EMAC_TypeDef;
+
+#pragma no_anon_unions
+
+
+/******************************************************************************/
+/*                         Peripheral memory map                              */
+/******************************************************************************/
+/* Base addresses                                                             */
+#define LPC_FLASH_BASE        (0x00000000UL)
+#define LPC_RAM_BASE          (0x10000000UL)
+#define LPC_GPIO_BASE         (0x2009C000UL)
+#define LPC_APB0_BASE         (0x40000000UL)
+#define LPC_APB1_BASE         (0x40080000UL)
+#define LPC_AHB_BASE          (0x50000000UL)
+#define LPC_CM3_BASE          (0xE0000000UL)
+
+/* APB0 peripherals                                                           */
+#define LPC_WDT_BASE          (LPC_APB0_BASE + 0x00000)
+#define LPC_TIM0_BASE         (LPC_APB0_BASE + 0x04000)
+#define LPC_TIM1_BASE         (LPC_APB0_BASE + 0x08000)
+#define LPC_UART0_BASE        (LPC_APB0_BASE + 0x0C000)
+#define LPC_UART1_BASE        (LPC_APB0_BASE + 0x10000)
+#define LPC_PWM1_BASE         (LPC_APB0_BASE + 0x18000)
+#define LPC_I2C0_BASE         (LPC_APB0_BASE + 0x1C000)
+#define LPC_SPI_BASE          (LPC_APB0_BASE + 0x20000)
+#define LPC_RTC_BASE          (LPC_APB0_BASE + 0x24000)
+#define LPC_GPIOINT_BASE      (LPC_APB0_BASE + 0x28080)
+#define LPC_PINCON_BASE       (LPC_APB0_BASE + 0x2C000)
+#define LPC_SSP1_BASE         (LPC_APB0_BASE + 0x30000)
+#define LPC_ADC_BASE          (LPC_APB0_BASE + 0x34000)
+#define LPC_CANAF_RAM_BASE    (LPC_APB0_BASE + 0x38000)
+#define LPC_CANAF_BASE        (LPC_APB0_BASE + 0x3C000)
+#define LPC_CANCR_BASE        (LPC_APB0_BASE + 0x40000)
+#define LPC_CAN1_BASE         (LPC_APB0_BASE + 0x44000)
+#define LPC_CAN2_BASE         (LPC_APB0_BASE + 0x48000)
+#define LPC_I2C1_BASE         (LPC_APB0_BASE + 0x5C000)
+
+/* APB1 peripherals                                                           */
+#define LPC_SSP0_BASE         (LPC_APB1_BASE + 0x08000)
+#define LPC_DAC_BASE          (LPC_APB1_BASE + 0x0C000)
+#define LPC_TIM2_BASE         (LPC_APB1_BASE + 0x10000)
+#define LPC_TIM3_BASE         (LPC_APB1_BASE + 0x14000)
+#define LPC_UART2_BASE        (LPC_APB1_BASE + 0x18000)
+#define LPC_UART3_BASE        (LPC_APB1_BASE + 0x1C000)
+#define LPC_I2C2_BASE         (LPC_APB1_BASE + 0x20000)
+#define LPC_I2S_BASE          (LPC_APB1_BASE + 0x28000)
+#define LPC_RIT_BASE          (LPC_APB1_BASE + 0x30000)
+#define LPC_MCPWM_BASE        (LPC_APB1_BASE + 0x38000)
+#define LPC_QEI_BASE          (LPC_APB1_BASE + 0x3C000)
+#define LPC_SC_BASE           (LPC_APB1_BASE + 0x7C000)
+
+/* AHB peripherals                                                            */
+#define LPC_EMAC_BASE         (LPC_AHB_BASE  + 0x00000)
+#define LPC_GPDMA_BASE        (LPC_AHB_BASE  + 0x04000)
+#define LPC_GPDMACH0_BASE     (LPC_AHB_BASE  + 0x04100)
+#define LPC_GPDMACH1_BASE     (LPC_AHB_BASE  + 0x04120)
+#define LPC_GPDMACH2_BASE     (LPC_AHB_BASE  + 0x04140)
+#define LPC_GPDMACH3_BASE     (LPC_AHB_BASE  + 0x04160)
+#define LPC_GPDMACH4_BASE     (LPC_AHB_BASE  + 0x04180)
+#define LPC_GPDMACH5_BASE     (LPC_AHB_BASE  + 0x041A0)
+#define LPC_GPDMACH6_BASE     (LPC_AHB_BASE  + 0x041C0)
+#define LPC_GPDMACH7_BASE     (LPC_AHB_BASE  + 0x041E0)
+#define LPC_USB_BASE          (LPC_AHB_BASE  + 0x0C000)
+
+/* GPIOs                                                                      */
+#define LPC_GPIO0_BASE        (LPC_GPIO_BASE + 0x00000)
+#define LPC_GPIO1_BASE        (LPC_GPIO_BASE + 0x00020)
+#define LPC_GPIO2_BASE        (LPC_GPIO_BASE + 0x00040)
+#define LPC_GPIO3_BASE        (LPC_GPIO_BASE + 0x00060)
+#define LPC_GPIO4_BASE        (LPC_GPIO_BASE + 0x00080)
+
+
+/******************************************************************************/
+/*                         Peripheral declaration                             */
+/******************************************************************************/
+#define LPC_SC                ((LPC_SC_TypeDef        *) LPC_SC_BASE       )
+#define LPC_GPIO0             ((LPC_GPIO_TypeDef      *) LPC_GPIO0_BASE    )
+#define LPC_GPIO1             ((LPC_GPIO_TypeDef      *) LPC_GPIO1_BASE    )
+#define LPC_GPIO2             ((LPC_GPIO_TypeDef      *) LPC_GPIO2_BASE    )
+#define LPC_GPIO3             ((LPC_GPIO_TypeDef      *) LPC_GPIO3_BASE    )
+#define LPC_GPIO4             ((LPC_GPIO_TypeDef      *) LPC_GPIO4_BASE    )
+#define LPC_WDT               ((LPC_WDT_TypeDef       *) LPC_WDT_BASE      )
+#define LPC_TIM0              ((LPC_TIM_TypeDef       *) LPC_TIM0_BASE     )
+#define LPC_TIM1              ((LPC_TIM_TypeDef       *) LPC_TIM1_BASE     )
+#define LPC_TIM2              ((LPC_TIM_TypeDef       *) LPC_TIM2_BASE     )
+#define LPC_TIM3              ((LPC_TIM_TypeDef       *) LPC_TIM3_BASE     )
+#define LPC_RIT               ((LPC_RIT_TypeDef       *) LPC_RIT_BASE      )
+#define LPC_UART0             ((LPC_UART0_TypeDef     *) LPC_UART0_BASE    )
+#define LPC_UART1             ((LPC_UART1_TypeDef     *) LPC_UART1_BASE    )
+#define LPC_UART2             ((LPC_UART_TypeDef      *) LPC_UART2_BASE    )
+#define LPC_UART3             ((LPC_UART_TypeDef      *) LPC_UART3_BASE    )
+#define LPC_PWM1              ((LPC_PWM_TypeDef       *) LPC_PWM1_BASE     )
+#define LPC_I2C0              ((LPC_I2C_TypeDef       *) LPC_I2C0_BASE     )
+#define LPC_I2C1              ((LPC_I2C_TypeDef       *) LPC_I2C1_BASE     )
+#define LPC_I2C2              ((LPC_I2C_TypeDef       *) LPC_I2C2_BASE     )
+#define LPC_I2S               ((LPC_I2S_TypeDef       *) LPC_I2S_BASE      )
+#define LPC_SPI               ((LPC_SPI_TypeDef       *) LPC_SPI_BASE      )
+#define LPC_RTC               ((LPC_RTC_TypeDef       *) LPC_RTC_BASE      )
+#define LPC_GPIOINT           ((LPC_GPIOINT_TypeDef   *) LPC_GPIOINT_BASE  )
+#define LPC_PINCON            ((LPC_PINCON_TypeDef    *) LPC_PINCON_BASE   )
+#define LPC_SSP0              ((LPC_SSP_TypeDef       *) LPC_SSP0_BASE     )
+#define LPC_SSP1              ((LPC_SSP_TypeDef       *) LPC_SSP1_BASE     )
+#define LPC_ADC               ((LPC_ADC_TypeDef       *) LPC_ADC_BASE      )
+#define LPC_DAC               ((LPC_DAC_TypeDef       *) LPC_DAC_BASE      )
+#define LPC_CANAF_RAM         ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE)
+#define LPC_CANAF             ((LPC_CANAF_TypeDef     *) LPC_CANAF_BASE    )
+#define LPC_CANCR             ((LPC_CANCR_TypeDef     *) LPC_CANCR_BASE    )
+#define LPC_CAN1              ((LPC_CAN_TypeDef       *) LPC_CAN1_BASE     )
+#define LPC_CAN2              ((LPC_CAN_TypeDef       *) LPC_CAN2_BASE     )
+#define LPC_MCPWM             ((LPC_MCPWM_TypeDef     *) LPC_MCPWM_BASE    )
+#define LPC_QEI               ((LPC_QEI_TypeDef       *) LPC_QEI_BASE      )
+#define LPC_EMAC              ((LPC_EMAC_TypeDef      *) LPC_EMAC_BASE     )
+#define LPC_GPDMA             ((LPC_GPDMA_TypeDef     *) LPC_GPDMA_BASE    )
+#define LPC_GPDMACH0          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH0_BASE )
+#define LPC_GPDMACH1          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH1_BASE )
+#define LPC_GPDMACH2          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH2_BASE )
+#define LPC_GPDMACH3          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH3_BASE )
+#define LPC_GPDMACH4          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH4_BASE )
+#define LPC_GPDMACH5          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH5_BASE )
+#define LPC_GPDMACH6          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH6_BASE )
+#define LPC_GPDMACH7          ((LPC_GPDMACH_TypeDef   *) LPC_GPDMACH7_BASE )
+#define LPC_USB               ((LPC_USB_TypeDef       *) LPC_USB_BASE      )
+
+#endif  // __LPC17xx_H__
diff -r 000000000000 -r d4960fcea8ff ParTest.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ParTest.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,234 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute
+    a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public 
+    License and the FreeRTOS license exception along with FreeRTOS; if not it 
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
+    by writing to Richard Barry, contact details for whom are available on the
+    FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and
+    contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety
+    critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting,
+    licensing and training services.
+*/
+
+/*
+ *  Modified for mbed NXP LPC1768 board
+ *  By Kenji Arai / JH1PJL on March 13th,2010
+ *         April 12th, 2010    Changed LPC17xx.h then convert all "GPIO" to "LPC_GPIO"
+ *         August 1st, 2010    Change Port definition
+ *         August 28th, 2010
+ */
+
+
+/* FreeRTOS.org includes. */
+#include "FreeRTOS.h"
+
+/* Demo application includes. */
+#include "partest.h"
+
+/*-----------------------------------------------------------
+ * Simple parallel port IO routines.
+ *-----------------------------------------------------------*/
+#if (USE_XPRESSO == 1)
+void vParTestInitialise( void )
+{
+    /* LEDs on port 1. */
+    LPC_GPIO0->FIODIR  = partstFIO1_BITS;
+    /* Start will all LEDs off. */
+    LPC_GPIO0->FIOCLR = partstFIO1_BITS;
+
+    // Switch
+    LPC_GPIO2->FIODIR  &= ~0x00;    // Input mode
+    LPC_PINCON->PINMODE4 |= 0x3f3;    // Pull-down P2.0,.2,.3,.4
+    //xprintf("GPIO2     = %x\r\n", LPC_GPIO2->FIOPIN);
+    //xprintf("GPIO2.DIR = %x\r\n", LPC_GPIO2->FIODIR);
+}
+/*-----------------------------------------------------------*/
+
+void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        /* Set or clear the output. */
+        if( xValue )
+        {
+            LPC_GPIO0->FIOCLR = ulLEDs[ uxLED ];
+        }
+        else
+        {
+            LPC_GPIO0->FIOSET = ulLEDs[ uxLED ];
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        if( LPC_GPIO0->FIOPIN & ulLEDs[ uxLED ] )
+        {
+            LPC_GPIO0->FIOCLR = ulLEDs[ uxLED ];
+        }
+        else
+        {
+            LPC_GPIO0->FIOSET = ulLEDs[ uxLED ];
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxParTextGetLED( unsigned portBASE_TYPE uxLED )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        return ( LPC_GPIO0->FIOPIN & ulLEDs[ uxLED ] );
+    }
+    else
+    {
+        return 0;
+    }
+}
+/*-----------------------------------------------------------*/
+#else
+void vParTestInitialise( void )
+{
+    /* LEDs on port 1. */
+    LPC_GPIO1->FIODIR  = partstFIO1_BITS;
+    /* Start will all LEDs off. */
+    LPC_GPIO1->FIOCLR = partstFIO1_BITS;
+
+    // Switch
+    LPC_GPIO2->FIODIR  &= ~0x00;    // Input mode
+    LPC_PINCON->PINMODE4 |= 0x3f3;    // Pull-down P2.0,.2,.3,.4
+    //xprintf("GPIO2     = %x\r\n", LPC_GPIO2->FIOPIN);
+    //xprintf("GPIO2.DIR = %x\r\n", LPC_GPIO2->FIODIR);
+}
+/*-----------------------------------------------------------*/
+
+void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        /* Set or clear the output. */
+        if( xValue )
+        {
+            LPC_GPIO1->FIOCLR = ulLEDs[ uxLED ];
+        }
+        else
+        {
+            LPC_GPIO1->FIOSET = ulLEDs[ uxLED ];
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        if( LPC_GPIO1->FIOPIN & ulLEDs[ uxLED ] )
+        {
+            LPC_GPIO1->FIOCLR = ulLEDs[ uxLED ];
+        }
+        else
+        {
+            LPC_GPIO1->FIOSET = ulLEDs[ uxLED ];
+        }
+    }
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxParTextGetLED( unsigned portBASE_TYPE uxLED )
+{
+    if( uxLED < partstNUM_LEDS )
+    {
+        return ( LPC_GPIO1->FIOPIN & ulLEDs[ uxLED ] );
+    }
+    else
+    {
+        return 0;
+    }
+}
+/*-----------------------------------------------------------*/
+#endif
+
+unsigned int vParTestSW_Rec( void ){ //Record switch = P2.3 (mbed p23)
+    //xputs("mbed P23 (LPC1768 p2.3) = ");
+    //if (LPC_GPIO2->FIOPIN & 0x08){
+    //    xputs("ON  \r\n");
+    //} else {
+    //    xputs("OFF \r\n");
+    //}
+    if (LPC_GPIO2->FIOPIN & 0x08){
+        //xputs("ON  \r\n");
+        return 0;
+    } else {
+        //xputs("OFF \r\n");
+        return 1;
+    }
+}
+
+unsigned int vParTestSW_Mode( void ){ //Record switch = P2.4 (mbed p22)
+    //xputs("mbed P22 (LPC1768 p2.4) = ");
+    //if (LPC_GPIO2->FIOPIN & 0x10){
+    //    xputs("ON  \r\n");
+    //} else {
+    //    xputs("OFF \r\n");
+    //}
+    if (LPC_GPIO2->FIOPIN & 0x10){
+        //xputs("ON  \r\n");
+        return 0;
+    } else {
+        //xputs("OFF \r\n");
+        return 1;
+    }
+}
+/*-----------------------------------------------------------*/
+
+
+
+
+
+
+
diff -r 000000000000 -r d4960fcea8ff core_cm3.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core_cm3.h	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,1366 @@
+/******************************************************************************
+ * @file:    core_cm3.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version: V1.20
+ * @date:    22. May 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CM3_CORE_H__
+#define __CM3_CORE_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#define __CM3_CMSIS_VERSION_MAIN  (0x01)                                                       /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB   (0x20)                                                       /*!< [15:0]  CMSIS HAL sub version  */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number       */
+
+#define __CORTEX_M                (0x03)                                                       /*!< Cortex core                    */
+
+/**
+ *  Lint configuration \n
+ *  ----------------------- \n
+ *
+ *  The following Lint messages will be suppressed and not shown: \n
+ *  \n
+ *    --- Error 10: --- \n
+ *    register uint32_t __regBasePri         __asm("basepri"); \n
+ *    Error 10: Expecting ';' \n
+ *     \n
+ *    --- Error 530: --- \n
+ *    return(__regBasePri); \n
+ *    Warning 530: Symbol '__regBasePri' (line 264) not initialized \n
+ *     \n
+ *    --- Error 550: --- \n
+ *      __regBasePri = (basePri & 0x1ff); \n
+ *    } \n
+ *    Warning 550: Symbol '__regBasePri' (line 271) not accessed \n
+ *     \n
+ *    --- Error 754: --- \n
+ *    uint32_t RESERVED0[24]; \n
+ *    Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n
+ *     \n
+ *    --- Error 750: --- \n
+ *    #define __CM3_CORE_H__ \n
+ *    Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n
+ *     \n
+ *    --- Error 528: --- \n
+ *    static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ *    Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n
+ *     \n
+ *    --- Error 751: --- \n
+ *    } InterruptType_Type; \n
+ *    Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n
+ * \n
+ * \n
+ *    Note:  To re-enable a Message, insert a space before 'lint' * \n
+ *
+ */
+
+/*lint -save */
+/*lint -e10  */
+/*lint -e530 */
+/*lint -e550 */
+/*lint -e754 */
+/*lint -e750 */
+/*lint -e528 */
+/*lint -e751 */
+
+
+#include <stdint.h>                           /* Include standard types */
+
+#if defined (__ICCARM__)
+  #include <intrinsics.h>                     /* IAR Intrinsics   */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+  #define __NVIC_PRIO_BITS    4               /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+#define     __I     volatile                  /*!< defines 'read only' permissions      */
+#else
+#define     __I     volatile const            /*!< defines 'read only' permissions      */
+#endif
+#define     __O     volatile                  /*!< defines 'write only' permissions     */
+#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+ ******************************************************************************/
+
+
+/* System Reset */
+#define NVIC_VECTRESET              0         /*!< Vector Reset Bit             */
+#define NVIC_SYSRESETREQ            2         /*!< System Reset Request         */
+#define NVIC_AIRCR_VECTKEY    (0x5FA << 16)   /*!< AIRCR Key for write access   */
+#define NVIC_AIRCR_ENDIANESS        15        /*!< Endianess                    */
+
+/* Core Debug */
+#define CoreDebug_DEMCR_TRCENA (1 << 24)      /*!< DEMCR TRCENA enable          */
+#define ITM_TCR_ITMENA              1         /*!< ITM enable                   */
+
+
+
+
+/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
+typedef struct
+{
+  __IO uint32_t ISER[8];                      /*!< Interrupt Set Enable Register            */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                      /*!< Interrupt Clear Enable Register          */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                      /*!< Interrupt Set Pending Register           */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                      /*!< Interrupt Clear Pending Register         */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                      /*!< Interrupt Active bit Register            */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                      /*!< Interrupt Priority Register, 8Bit wide   */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                         /*!< Software Trigger Interrupt Register      */
+}  NVIC_Type;
+
+
+/* memory mapping struct for System Control Block */
+typedef struct
+{
+  __I  uint32_t CPUID;                        /*!< CPU ID Base Register                                     */
+  __IO uint32_t ICSR;                         /*!< Interrupt Control State Register                         */
+  __IO uint32_t VTOR;                         /*!< Vector Table Offset Register                             */
+  __IO uint32_t AIRCR;                        /*!< Application Interrupt / Reset Control Register           */
+  __IO uint32_t SCR;                          /*!< System Control Register                                  */
+  __IO uint32_t CCR;                          /*!< Configuration Control Register                           */
+  __IO uint8_t  SHP[12];                      /*!< System Handlers Priority Registers (4-7, 8-11, 12-15)    */
+  __IO uint32_t SHCSR;                        /*!< System Handler Control and State Register                */
+  __IO uint32_t CFSR;                         /*!< Configurable Fault Status Register                       */
+  __IO uint32_t HFSR;                         /*!< Hard Fault Status Register                               */
+  __IO uint32_t DFSR;                         /*!< Debug Fault Status Register                              */
+  __IO uint32_t MMFAR;                        /*!< Mem Manage Address Register                              */
+  __IO uint32_t BFAR;                         /*!< Bus Fault Address Register                               */
+  __IO uint32_t AFSR;                         /*!< Auxiliary Fault Status Register                          */
+  __I  uint32_t PFR[2];                       /*!< Processor Feature Register                               */
+  __I  uint32_t DFR;                          /*!< Debug Feature Register                                   */
+  __I  uint32_t ADR;                          /*!< Auxiliary Feature Register                               */
+  __I  uint32_t MMFR[4];                      /*!< Memory Model Feature Register                            */
+  __I  uint32_t ISAR[5];                      /*!< ISA Feature Register                                     */
+} SCB_Type;
+
+
+/* memory mapping struct for SysTick */
+typedef struct
+{
+  __IO uint32_t CTRL;                         /*!< SysTick Control and Status Register */
+  __IO uint32_t LOAD;                         /*!< SysTick Reload Value Register       */
+  __IO uint32_t VAL;                          /*!< SysTick Current Value Register      */
+  __I  uint32_t CALIB;                        /*!< SysTick Calibration Register        */
+} SysTick_Type;
+
+
+/* memory mapping structur for ITM */
+typedef struct
+{
+  __O  union  
+  {
+    __O  uint8_t    u8;                       /*!< ITM Stimulus Port 8-bit               */
+    __O  uint16_t   u16;                      /*!< ITM Stimulus Port 16-bit              */
+    __O  uint32_t   u32;                      /*!< ITM Stimulus Port 32-bit              */
+  }  PORT [32];                               /*!< ITM Stimulus Port Registers           */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                          /*!< ITM Trace Enable Register             */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                          /*!< ITM Trace Privilege Register          */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                          /*!< ITM Trace Control Register            */
+       uint32_t RESERVED3[29];
+  __IO uint32_t IWR;                          /*!< ITM Integration Write Register        */
+  __IO uint32_t IRR;                          /*!< ITM Integration Read Register         */
+  __IO uint32_t IMCR;                         /*!< ITM Integration Mode Control Register */
+       uint32_t RESERVED4[43];
+  __IO uint32_t LAR;                          /*!< ITM Lock Access Register              */
+  __IO uint32_t LSR;                          /*!< ITM Lock Status Register              */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                         /*!< ITM Product ID Registers              */
+  __I  uint32_t PID5;
+  __I  uint32_t PID6;
+  __I  uint32_t PID7;
+  __I  uint32_t PID0;
+  __I  uint32_t PID1;
+  __I  uint32_t PID2;
+  __I  uint32_t PID3;
+  __I  uint32_t CID0;
+  __I  uint32_t CID1;
+  __I  uint32_t CID2;
+  __I  uint32_t CID3;
+} ITM_Type;
+
+
+/* memory mapped struct for Interrupt Type */
+typedef struct
+{
+       uint32_t RESERVED0;
+  __I  uint32_t ICTR;                         /*!< Interrupt Control Type Register  */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+  __IO uint32_t ACTLR;                        /*!< Auxiliary Control Register       */
+#else
+       uint32_t RESERVED1;
+#endif
+} InterruptType_Type;
+
+
+/* Memory Protection Unit */
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+typedef struct
+{
+  __I  uint32_t TYPE;                         /*!< MPU Type Register                               */
+  __IO uint32_t CTRL;                         /*!< MPU Control Register                            */
+  __IO uint32_t RNR;                          /*!< MPU Region RNRber Register                      */
+  __IO uint32_t RBAR;                         /*!< MPU Region Base Address Register                */
+  __IO uint32_t RASR;                         /*!< MPU Region Attribute and Size Register          */
+  __IO uint32_t RBAR_A1;                      /*!< MPU Alias 1 Region Base Address Register        */
+  __IO uint32_t RASR_A1;                      /*!< MPU Alias 1 Region Attribute and Size Register  */
+  __IO uint32_t RBAR_A2;                      /*!< MPU Alias 2 Region Base Address Register        */
+  __IO uint32_t RASR_A2;                      /*!< MPU Alias 2 Region Attribute and Size Register  */
+  __IO uint32_t RBAR_A3;                      /*!< MPU Alias 3 Region Base Address Register        */
+  __IO uint32_t RASR_A3;                      /*!< MPU Alias 3 Region Attribute and Size Register  */
+} MPU_Type;
+#endif
+
+
+/* Core Debug Register */
+typedef struct
+{
+  __IO uint32_t DHCSR;                        /*!< Debug Halting Control and Status Register       */
+  __O  uint32_t DCRSR;                        /*!< Debug Core Register Selector Register           */
+  __IO uint32_t DCRDR;                        /*!< Debug Core Register Data Register               */
+  __IO uint32_t DEMCR;                        /*!< Debug Exception and Monitor Control Register    */
+} CoreDebug_Type;
+
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000)                              /*!< System Control Space Base Address    */
+#define ITM_BASE            (0xE0000000)                              /*!< ITM Base Address                     */
+#define CoreDebug_BASE      (0xE000EDF0)                              /*!< Core Debug Base Address              */
+#define SysTick_BASE        (SCS_BASE +  0x0010)                      /*!< SysTick Base Address                 */
+#define NVIC_BASE           (SCS_BASE +  0x0100)                      /*!< NVIC Base Address                    */
+#define SCB_BASE            (SCS_BASE +  0x0D00)                      /*!< System Control Block Base Address    */
+
+#define InterruptType       ((InterruptType_Type *) SCS_BASE)         /*!< Interrupt Type Register              */
+#define SCB                 ((SCB_Type *)           SCB_BASE)         /*!< SCB configuration struct             */
+#define SysTick             ((SysTick_Type *)       SysTick_BASE)     /*!< SysTick configuration struct         */
+#define NVIC                ((NVIC_Type *)          NVIC_BASE)        /*!< NVIC configuration struct            */
+#define ITM                 ((ITM_Type *)           ITM_BASE)         /*!< ITM configuration struct             */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct      */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90)                      /*!< Memory Protection Unit               */
+  #define MPU               ((MPU_Type*)            MPU_BASE)         /*!< Memory Protection Unit               */
+#endif
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+#if defined ( __CC_ARM   )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+
+#elif defined ( __ICCARM__ )
+  #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler           */
+  #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined   (  __GNUC__  )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+
+#elif defined   (  __TASKING__  )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler       */
+
+#endif
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+
+#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#define __enable_fault_irq                __enable_fiq
+#define __disable_fault_irq               __disable_fiq
+
+#define __NOP                             __nop
+#define __WFI                             __wfi
+#define __WFE                             __wfe
+#define __SEV                             __sev
+#define __ISB()                           __isb(0)
+#define __DSB()                           __dsb(0)
+#define __DMB()                           __dmb(0)
+#define __REV                             __rev
+#define __RBIT                            __rbit
+#define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))
+#define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))
+#define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))
+#define __STREXB(value, ptr)              __strex(value, ptr)
+#define __STREXH(value, ptr)              __strex(value, ptr)
+#define __STREXW(value, ptr)              __strex(value, ptr)
+
+
+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */
+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+
+/**
+ * @brief  Return the Process Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief  Set the Process Stack Pointer
+ *
+ * @param  uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP 
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief  Return the Main Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief  Set the Main Stack Pointer
+ *
+ * @param  uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP 
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief  Reverse byte order in unsigned short value
+ *
+ * @param  uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/*
+ * @brief  Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param  int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief  Remove the exclusive lock created by ldrex
+ *
+ * @param  none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+extern void __CLREX(void);
+
+/**
+ * @brief  Return the Base Priority value
+ *
+ * @param  none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief  Set the Base Priority value
+ *
+ * @param  uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief  Return the Priority Mask value
+ *
+ * @param  none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief  Set the Priority Mask value
+ *
+ * @param  uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief  Return the Fault Mask value
+ *
+ * @param  none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief  Set the Fault Mask value
+ *
+ * @param  uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief  Return the Control Register value
+ * 
+ * @param  none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief  Set the Control Register value
+ *
+ * @param  uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+#else  /* (__ARMCC_VERSION >= 400000)  */
+
+
+/**
+ * @brief  Remove the exclusive lock created by ldrex
+ *
+ * @param  none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+#define __CLREX                           __clrex
+
+/**
+ * @brief  Return the Base Priority value
+ *
+ * @param  none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+static __INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+/**
+ * @brief  Set the Base Priority value
+ *
+ * @param  uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+static __INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0x1ff);
+}
+
+/**
+ * @brief  Return the Priority Mask value
+ *
+ * @param  none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+/**
+ * @brief  Set the Priority Mask value
+ *
+ * @param  uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+/**
+ * @brief  Return the Fault Mask value
+ *
+ * @param  none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+static __INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+/**
+ * @brief  Set the Fault Mask value
+ *
+ * @param  uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & 1);
+}
+
+/**
+ * @brief  Return the Control Register value
+ * 
+ * @param  none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+/**
+ * @brief  Set the Control Register value
+ *
+ * @param  uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+#endif /* __ARMCC_VERSION  */ 
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#define __enable_irq                              __enable_interrupt        /*!< global Interrupt enable */
+#define __disable_irq                             __disable_interrupt       /*!< global Interrupt disable */
+
+static __INLINE void __enable_fault_irq()         { __ASM ("cpsie f"); }
+static __INLINE void __disable_fault_irq()        { __ASM ("cpsid f"); }
+
+#define __NOP                                     __no_operation()          /*!< no operation intrinsic in IAR Compiler */ 
+static __INLINE  void __WFI()                     { __ASM ("wfi"); }
+static __INLINE  void __WFE()                     { __ASM ("wfe"); }
+static __INLINE  void __SEV()                     { __ASM ("sev"); }
+static __INLINE  void __CLREX()                   { __ASM ("clrex"); }
+
+/* intrinsic void __ISB(void)                                     */
+/* intrinsic void __DSB(void)                                     */
+/* intrinsic void __DMB(void)                                     */
+/* intrinsic void __set_PRIMASK();                                */
+/* intrinsic void __get_PRIMASK();                                */
+/* intrinsic void __set_FAULTMASK();                              */
+/* intrinsic void __get_FAULTMASK();                              */
+/* intrinsic uint32_t __REV(uint32_t value);                      */
+/* intrinsic uint32_t __REVSH(uint32_t value);                    */
+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */
+/* intrinsic unsigned long __LDREX(unsigned long *);              */
+
+
+/**
+ * @brief  Return the Process Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief  Set the Process Stack Pointer
+ *
+ * @param  uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP 
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief  Return the Main Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief  Set the Main Stack Pointer
+ *
+ * @param  uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP 
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief  Reverse byte order in unsigned short value
+ *
+ * @param  uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief  Reverse bit order of value
+ *
+ * @param  uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint8_t *address
+ * @param  uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint16_t *address
+ * @param  uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint32_t *address
+ * @param  uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+static __INLINE void __enable_irq()               { __ASM volatile ("cpsie i"); }
+static __INLINE void __disable_irq()              { __ASM volatile ("cpsid i"); }
+
+static __INLINE void __enable_fault_irq()         { __ASM volatile ("cpsie f"); }
+static __INLINE void __disable_fault_irq()        { __ASM volatile ("cpsid f"); }
+
+static __INLINE void __NOP()                      { __ASM volatile ("nop"); }
+static __INLINE void __WFI()                      { __ASM volatile ("wfi"); }
+static __INLINE void __WFE()                      { __ASM volatile ("wfe"); }
+static __INLINE void __SEV()                      { __ASM volatile ("sev"); }
+static __INLINE void __ISB()                      { __ASM volatile ("isb"); }
+static __INLINE void __DSB()                      { __ASM volatile ("dsb"); }
+static __INLINE void __DMB()                      { __ASM volatile ("dmb"); }
+static __INLINE void __CLREX()                    { __ASM volatile ("clrex"); }
+
+
+/**
+ * @brief  Return the Process Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief  Set the Process Stack Pointer
+ *
+ * @param  uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP 
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief  Return the Main Stack Pointer
+ *
+ * @param  none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief  Set the Main Stack Pointer
+ *
+ * @param  uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP 
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief  Return the Base Priority value
+ *
+ * @param  none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief  Set the Base Priority value
+ *
+ * @param  uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief  Return the Priority Mask value
+ *
+ * @param  none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+extern uint32_t  __get_PRIMASK(void);
+
+/**
+ * @brief  Set the Priority Mask value
+ *
+ * @param  uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief  Return the Fault Mask value
+ *
+ * @param  none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief  Set the Fault Mask value
+ *
+ * @param  uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief  Return the Control Register value
+* 
+*  @param  none
+*  @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief  Set the Control Register value
+ *
+ * @param  uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+/**
+ * @brief  Reverse byte order in integer value
+ *
+ * @param  uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in integer value
+ */
+extern uint32_t __REV(uint32_t value);
+
+/**
+ * @brief  Reverse byte order in unsigned short value
+ *
+ * @param  uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/*
+ * Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param  int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * @brief  Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+/**
+ * @brief  Reverse bit order of value
+ *
+ * @param  uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief  LDR Exclusive
+ *
+ * @param  uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint8_t *address
+ * @param  uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint16_t *address
+ * @param  uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief  STR Exclusive
+ *
+ * @param  uint32_t *address
+ * @param  uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+
+/* ##########################   NVIC functions  #################################### */
+
+
+/**
+ * @brief  Set the Priority Grouping in NVIC Interrupt Controller
+ *
+ * @param  uint32_t priority_grouping is priority grouping field
+ * @return none 
+ *
+ * Set the priority grouping field using the required unlock sequence.
+ * The parameter priority_grouping is assigned to the field 
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */
+  
+  reg_value  = SCB->AIRCR;                                                    /* read old register configuration    */
+  reg_value &= ~((0xFFFFU << 16) | (0x0F << 8));                              /* clear bits to change               */
+  reg_value  = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8)));  /* Insert write key and priorty group */
+  SCB->AIRCR = reg_value;
+}
+
+/**
+ * @brief  Get the Priority Grouping from NVIC Interrupt Controller
+ *
+ * @param  none
+ * @return uint32_t   priority grouping field 
+ *
+ * Get the priority grouping from NVIC Interrupt Controller.
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((SCB->AIRCR >> 8) & 0x07);                                          /* read priority grouping field */
+}
+
+/**
+ * @brief  Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param  IRQn_Type IRQn specifies the interrupt number
+ * @return none 
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+/**
+ * @brief  Disable the interrupt line for external interrupt specified
+ * 
+ * @param  IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ * 
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+/**
+ * @brief  Read the interrupt pending bit for a device specific interrupt source
+ * 
+ * @param  IRQn_Type IRQn is the number of the device specifc interrupt
+ * @return uint32_t 1 if pending interrupt else 0
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending, 
+ * otherwise it returns 0
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+/**
+ * @brief  Set the pending bit for an external interrupt
+ * 
+ * @param  IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+/**
+ * @brief  Clear the pending bit for an external interrupt
+ *
+ * @param  IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Clear the pending bit for the specified interrupt. 
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+/**
+ * @brief  Read the active bit for an external interrupt
+ *
+ * @param  IRQn_Type  IRQn is the Number of the interrupt
+ * @return uint32_t   1 if active else 0
+ *
+ * Read the active register in NVIC and returns 1 if its status is active, 
+ * otherwise it returns 0.
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+/**
+ * @brief  Set the priority for an interrupt
+ *
+ * @param  IRQn_Type IRQn is the Number of the interrupt
+ * @param  priority is the priority for the interrupt
+ * @return none
+ *
+ * Set the priority for the specified interrupt. The interrupt 
+ * number can be positive to specify an external (device specific) 
+ * interrupt, or negative to specify an internal (core) interrupt. \n
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts      */
+}
+
+/**
+ * @brief  Read the priority for an interrupt
+ *
+ * @param  IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t  priority is the priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt 
+ * number can be positive to specify an external (device specific) 
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M3 system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/**
+ * @brief  Encode the priority for an interrupt
+ *
+ * @param  uint32_t PriorityGroup   is the used priority group
+ * @param  uint32_t PreemptPriority is the preemptive priority value (starting from 0)
+ * @param  uint32_t SubPriority     is the sub priority value (starting from 0)
+ * @return uint32_t                    the priority for the interrupt
+ *
+ * Encode the priority for an interrupt with the given priority group,
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The returned priority value can be used for NVIC_SetPriority(...) function
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+ 
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/**
+ * @brief  Decode the priority of an interrupt
+ *
+ * @param  uint32_t   Priority       the priority for the interrupt
+ * @param  uint32_t   PrioGroup   is the used priority group
+ * @param  uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)
+ * @param  uint32_t* pSubPrio     is the sub priority value (starting from 0)
+ * @return none
+ *
+ * Decode an interrupt priority value with the given priority group to 
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The priority value can be retrieved with NVIC_GetPriority(...) function
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+  
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+
+/* ##################################    SysTick function  ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+/* SysTick constants */
+#define SYSTICK_ENABLE              0                                          /* Config-Bit to start or stop the SysTick Timer                         */
+#define SYSTICK_TICKINT             1                                          /* Config-Bit to enable or disable the SysTick interrupt                 */
+#define SYSTICK_CLKSOURCE           2                                          /* Clocksource has the offset 2 in SysTick Control and Status Register   */
+#define SYSTICK_MAXCOUNT       ((1<<24) -1)                                    /* SysTick MaxCount                                                      */
+
+/**
+ * @brief  Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param  uint32_t ticks is the number of ticks between two interrupts
+ * @return  none
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate 
+ * periodical interrupts.
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{ 
+  if (ticks > SYSTICK_MAXCOUNT)  return (1);                                             /* Reload value impossible */
+
+  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;                                      /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);                            /* set Priority for Cortex-M0 System Interrupts */
+  SysTick->VAL   =  (0x00);                                                              /* Load the SysTick Counter Value */
+  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                                            /* Function successful */
+}
+#endif
+
+
+
+
+
+/* ##################################    Reset function  ############################################ */
+
+/**
+ * @brief  Initiate a system reset request.
+ *
+ * @param   none
+ * @return  none
+ *
+ * Initialize a system reset request to reset the MCU
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+  SCB->AIRCR  = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */
+  __DSB();                                                                             /* Ensure completion of memory access */              
+  while(1);                                                                            /* wait until reset */
+}
+
+
+/* ##################################    Debug Output  function  ############################################ */
+
+
+/**
+ * @brief  Outputs a character via the ITM channel 0
+ *
+ * @param   uint32_t character to output
+ * @return  uint32_t input character
+ *
+ * The function outputs a character via the ITM channel 0. 
+ * The function returns when no debugger is connected that has booked the output.  
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted. 
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (ch == '\n') ITM_SendChar('\r');
+  
+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA)  &&
+      (ITM->TCR & ITM_TCR_ITMENA)                  &&
+      (ITM->TER & (1UL << 0))  ) 
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t) ch;
+  }  
+  return (ch);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CM3_CORE_H__ */
+
+/*lint -restore */
diff -r 000000000000 -r d4960fcea8ff main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,490 @@
+/*
+    FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+    ***************************************************************************
+    *                                                                         *
+    * If you are:                                                             *
+    *                                                                         *
+    *    + New to FreeRTOS,                                                   *
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
+    *    + Looking for basic training,                                        *
+    *    + Wanting to improve your FreeRTOS skills and productivity           *
+    *                                                                         *
+    * then take a look at the FreeRTOS eBook                                  *
+    *                                                                         *
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
+    *                  http://www.FreeRTOS.org/Documentation                  *
+    *                                                                         *
+    * A pdf reference manual is also available.  Both are usually delivered   *
+    * to your inbox within 20 minutes to two hours when purchased between 8am *
+    * and 8pm GMT (although please allow up to 24 hours in case of            *
+    * exceptional circumstances).  Thank you for your support!                *
+    *                                                                         *
+    ***************************************************************************
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2) as published by the Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+    ***NOTE*** The exception to the GPL is included to allow you to distribute a combined work that includes FreeRTOS without being obliged to provide the
+    source code for proprietary components outside of the FreeRTOS kernel.
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details. You should have received a copy of the GNU General Public License and the FreeRTOS license exception along with FreeRTOS; if not it can be viewed here: http://www.freertos.org/a00114.html and also obtained
+    by writing to Richard Barry, contact details for whom are available on the FreeRTOS WEB site.
+
+    1 tab == 4 spaces!
+
+    http://www.FreeRTOS.org - Documentation, latest information, license and contact details.
+
+    http://www.SafeRTOS.com - A version that is certified for use in safety critical systems.
+
+    http://www.OpenRTOS.com - Commercial support, development, porting, licensing and training services.
+*/
+
+//#error The batch file Demo\CORTEX_LPC1768_GCC_RedSuite\CreateProjectDirectoryStructure.bat must be executed before the first build.  After executing the batch file hit F5 to refrech the Eclipse project, then delete this line.
+
+/*
+ * Creates all the demo application tasks, then starts the scheduler.  The WEB documentation provides more details of the standard demo application tasks
+ * (which just exist to test the kernel port and provide an example of how to use each FreeRTOS API function).
+ *
+ * In addition to the standard demo tasks, the following tasks and tests are defined and/or created within this file:
+ *
+ * "Check" hook -  This only executes fully every five seconds from the tick hook.  Its main function is to check that all the standard demo tasks are
+ * still operational.  The status can be viewed using on the Task Stats page served by the WEB server.
+ *
+ * "uIP" task -  This is the task that handles the uIP stack.  All TCP/IP processing is performed in this task.
+ * 
+ * "USB" task - Enumerates the USB device as a CDC class, then echoes back all received characters with a configurable offset (for example, if the offset
+ * is 1 and 'A' is received then 'B' will be sent back).  A dumb terminal such as Hyperterminal can be used to talk to the USB task.
+ */
+/*----------------------------------------------------------------------------------------------------------*/
+/*
+ *  Modified for mbed IDE development environment
+ *  By Kenji Arai / JH1PJL on October 28th,2010
+ *      October 28th,2010
+ */
+
+#include <stdio.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "integer.h"
+#include "BlockQ.h"
+#include "blocktim.h"
+#include "flash.h"
+#include "partest.h"
+#include "semtest.h"
+#include "PollQ.h"
+#include "GenQTest.h"
+#include "QPeek.h"
+#include "queue.h"
+#include "recmutex.h"
+
+/*----------------------------------------------------------------------------------------------------------*/
+/* The time between cycles of the 'check' functionality (defined within the tick hook. */
+#define mainCHECK_DELAY                        ( ( portTickType ) 5000 / portTICK_RATE_MS )
+
+/* Task priorities. */
+#define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 2 )
+#define mainSEM_TEST_PRIORITY                ( tskIDLE_PRIORITY + 1 )
+#define mainBLOCK_Q_PRIORITY                ( tskIDLE_PRIORITY + 2 )
+#define mainUIP_TASK_PRIORITY                ( tskIDLE_PRIORITY + 3 )
+#define mainINTEGER_TASK_PRIORITY           ( tskIDLE_PRIORITY )
+#define mainGEN_QUEUE_TASK_PRIORITY            ( tskIDLE_PRIORITY )
+#define mainFLASH_TASK_PRIORITY                ( tskIDLE_PRIORITY + 2 )
+
+/* LED */
+#define LED1 0
+#define LED2 1
+#define LED3 2
+#define LED4 3
+
+// FLASH
+#define FLASH_SETUP           1
+#define FLASHCFG_Val          0x0000303A
+
+// Define clocks
+#define XTAL        (12000000UL)        /* Oscillator frequency               */
+#define OSC_CLK     (      XTAL)        /* Main oscillator frequency          */
+#define RTC_CLK     (   32000UL)        /* RTC oscillator frequency           */
+#define IRC_OSC     ( 4000000UL)        /* Internal RC oscillator frequency   */
+
+/*----------------------------------------------------------------------------------------------------------*/
+// Configure the hardware for mbed board
+static void prvSetupHardware( void );
+static void prvSetupSystem( void );
+
+//Control tasks for JH1PJL
+void vTask1( void *pvParameters );
+void vTask2( void *pvParameters );
+void vTask3( void *pvParameters );
+void vTask4( void *pvParameters );
+void vTask5( void *pvParameters );
+void vTask6( void *pvParameters );
+void vTask7( void *pvParameters );
+
+/*----------------------------------------------------------------------------------------------------------*/
+uint32_t SystemFrequency;    /*!< System Clock Frequency (Core Clock)  */
+
+unsigned portBASE_TYPE uxHiWtrMrk_tsk1, uxHiWtrMrk_tsk2;
+unsigned portBASE_TYPE uxHiWtrMrk_tsk3, uxHiWtrMrk_tsk4, uxHiWtrMrk_tsk5;
+unsigned portBASE_TYPE uxHiWtrMrk_tsk6, uxHiWtrMrk_tsk7;
+
+////////////////////////////// Constant Data /////////////////////////////////////////////////////////////////
+/* ---------------------------< Copyright >---------------------------------------------------------------- */
+const uint8_t copyright[]    = "Arai,Kenji / JH1PJL(c)2010 kenjia@sannet.ne.jp "__DATE__" (" __TIME__ ")";
+#if ( USE_XPRESSO == 1 )
+/* ---------------------------< Board >---------------------------------------------------------------- */
+const uint8_t board[]        = "LPCXpresso LPC1768";
+/*----------------------------------------------------------------------------------------------------------*/
+#elif ( USE_MBED == 1 )
+/* ---------------------------< Board >---------------------------------------------------------------- */
+const uint8_t board[]        = "med LPC1768";
+#else
+/* ---------------------------< Board >---------------------------------------------------------------- */
+const uint8_t board[]        = "No identification";
+#endif
+
+int main( void ){
+//    char cIPAddress[ 16 ]; 
+    /* Configure the hardware for mbed board */
+    prvSetupHardware();
+    prvSetupSystem();
+
+    /* Start the standard demo tasks.  These are just here to exercise the kernel port and provide examples of how the FreeRTOS API can be used. */
+    vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
+    vCreateBlockTimeTasks();
+    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
+    vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
+    vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
+    vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
+    vStartQueuePeekTasks();
+    vStartRecursiveMutexTasks();
+
+    // ??? Task
+    xTaskCreate( vTask1, ( signed char * ) "Task1", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask2, ( signed char * ) "Task2", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask3, ( signed char * ) "Task3", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask4, ( signed char * ) "Task4", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask5, ( signed char * ) "Task5", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask6, ( signed char * ) "Task6", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+    // ??? Task
+    xTaskCreate( vTask7, ( signed char * ) "Task7", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+
+    /* Start the scheduler. */
+    vTaskStartScheduler();
+
+    /* Will only get here if there was insufficient memory to create the idle task.  The idle task is created within vTaskStartScheduler(). */
+    for( ;; );
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #1 ******/
+// ????
+void vTask1 ( void *pvParameters ){
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    xDelayTime = 125 / portTICK_RATE_MS;
+    xLastCheckTime = xTaskGetTickCount();
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        vParTestToggleLED( LED1 );
+        uxHiWtrMrk_tsk1 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #2 ******/
+// ???
+void vTask2 ( void *pvParameters ){
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    xDelayTime = 250 / portTICK_RATE_MS;
+    xLastCheckTime = xTaskGetTickCount();
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        vParTestToggleLED( LED2 );
+        uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #3 ******/
+// ???
+void vTask3 ( void *pvParameters ){
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    xDelayTime = 500 / portTICK_RATE_MS;
+    xLastCheckTime = xTaskGetTickCount();
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        vParTestToggleLED( LED3 );
+        uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #4 ******/
+// ???
+void vTask4(void *pvParameters) {
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    xDelayTime = 1000 / portTICK_RATE_MS;
+    xLastCheckTime = xTaskGetTickCount();
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        vParTestToggleLED( LED4 );
+        uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #5 ******/
+// ?????
+void vTask5 ( void *pvParameters ){
+
+    vTaskDelay( 100 / portTICK_RATE_MS );            // Wait 0.1sec
+    while(1){
+        vTaskDelay( 10000 / portTICK_RATE_MS );        // Wait 10sec
+        uxHiWtrMrk_tsk5 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+/***** TASK #6 ******/
+// ????
+void vTask6(void *pvParameters) {
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    vTaskDelay(  200 / portTICK_RATE_MS );    // Wait
+    xDelayTime = 25 / portTICK_RATE_MS;
+    xLastCheckTime = xTaskGetTickCount();    // Need to initialize time prior to the first call to vTaskDelayUntil()
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        uxHiWtrMrk_tsk6 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+
+/***** TASK #7******/
+// ????
+void vTask7(void *pvParameters) {
+    portTickType xLastCheckTime;
+    portTickType xDelayTime;
+
+    xDelayTime = 10 / portTICK_RATE_MS;    // 10mS interval
+    xLastCheckTime = xTaskGetTickCount();
+    while(1){
+        vTaskDelayUntil( &xLastCheckTime, xDelayTime );
+        uxHiWtrMrk_tsk7 = uxTaskGetStackHighWaterMark( NULL );
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+void vApplicationTickHook( void ){
+    static unsigned long ulTicksSinceLastDisplay = 0;
+
+    /* Called from every tick interrupt as described in the comments at the top    of this file.
+    Have enough ticks passed to make it    time to perform our health status check again? */
+    ulTicksSinceLastDisplay++;
+    if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ){
+        /* Reset the counter so these checks run again in mainCHECK_DELAY
+        ticks time. */
+        ulTicksSinceLastDisplay = 0;
+    }
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+char *pcGetTaskStatusMessage( void ){
+    /* Not bothered about a critical section here. */
+    return 0;
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+void prvSetupSystem( void ){
+    ;
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+void prvSetupHardware( void ){
+    /* Disable peripherals power. */
+    LPC_SC->PCONP = 0;
+
+    /* Enable GPIO power. */
+    LPC_SC->PCONP = PCONP_PCGPIO;
+
+    /* Disable TPIU. */
+    LPC_PINCON->PINSEL10 = 0;
+
+    if ( LPC_SC->PLL0STAT & ( 1 << 25 ) ){
+        /* Enable PLL, disconnected. */
+        LPC_SC->PLL0CON = 1;
+        LPC_SC->PLL0FEED = PLLFEED_FEED1;
+        LPC_SC->PLL0FEED = PLLFEED_FEED2;
+    }
+    
+    /* Disable PLL, disconnected. */
+    LPC_SC->PLL0CON = 0;
+    LPC_SC->PLL0FEED = PLLFEED_FEED1;
+    LPC_SC->PLL0FEED = PLLFEED_FEED2;
+        
+    /* Enable main OSC. */
+    LPC_SC->SCS |= 0x20;
+    while( !( LPC_SC->SCS & 0x40 ) );
+    
+    /* select main OSC, 12MHz, as the PLL clock source. */
+    LPC_SC->CLKSRCSEL = 0x1;
+    
+    LPC_SC->PLL0CFG = 0x20031;
+    LPC_SC->PLL0FEED = PLLFEED_FEED1;
+    LPC_SC->PLL0FEED = PLLFEED_FEED2;
+          
+    /* Enable PLL, disconnected. */
+    LPC_SC->PLL0CON = 1;
+    LPC_SC->PLL0FEED = PLLFEED_FEED1;
+    LPC_SC->PLL0FEED = PLLFEED_FEED2;
+    
+    /* Set clock divider. */
+    LPC_SC->CCLKCFG = 0x03;
+    
+    /* Configure flash accelerator. */
+    LPC_SC->FLASHCFG = 0x403a;
+    
+    /* Check lock bit status. */
+    while( ( ( LPC_SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );
+        
+    /* Enable and connect. */
+    LPC_SC->PLL0CON = 3;
+    LPC_SC->PLL0FEED = PLLFEED_FEED1;
+    LPC_SC->PLL0FEED = PLLFEED_FEED2;
+    while( ( ( LPC_SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );
+    
+    
+    /* Configure the clock for the USB. */
+      
+    if( LPC_SC->PLL1STAT & ( 1 << 9 ) )
+    {
+        /* Enable PLL, disconnected. */
+        LPC_SC->PLL1CON = 1;
+        LPC_SC->PLL1FEED = PLLFEED_FEED1;
+        LPC_SC->PLL1FEED = PLLFEED_FEED2;
+    }
+    
+    /* Disable PLL, disconnected. */
+    LPC_SC->PLL1CON = 0;
+    LPC_SC->PLL1FEED = PLLFEED_FEED1;
+    LPC_SC->PLL1FEED = PLLFEED_FEED2;
+    
+    LPC_SC->PLL1CFG = 0x23;
+    LPC_SC->PLL1FEED = PLLFEED_FEED1;
+    LPC_SC->PLL1FEED = PLLFEED_FEED2;
+          
+    /* Enable PLL, disconnected. */
+    LPC_SC->PLL1CON = 1;
+    LPC_SC->PLL1FEED = PLLFEED_FEED1;
+    LPC_SC->PLL1FEED = PLLFEED_FEED2;
+    while( ( ( LPC_SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );
+    
+    /* Enable and connect. */
+    LPC_SC->PLL1CON = 3;
+    LPC_SC->PLL1FEED = PLLFEED_FEED1;
+    LPC_SC->PLL1FEED = PLLFEED_FEED2;
+    while( ( ( LPC_SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );
+
+    /*  Setup the peripheral bus to be the same as the PLL output (64 MHz). */
+    LPC_SC->PCLKSEL0 = 0x05555555;
+
+    /* Porting from system_LPC17xx.c void SystemInit()                            */
+    /* Determine clock frequency according to clock register values             */
+    if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) {/* If PLL0 enabled and connected      */
+        switch (LPC_SC->CLKSRCSEL & 0x03) {
+            case 0:                           /* Internal RC oscillator => PLL0     */
+            case 3:                           /* Reserved, default to Internal RC   */
+                    SystemFrequency = (IRC_OSC *
+                              (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+                              (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
+                              ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+                    break;
+            case 1:                           /* Main oscillator => PLL0            */
+                    SystemFrequency = (OSC_CLK *
+                              (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+                              (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
+                              ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+                    break;
+            case 2:                           /* RTC oscillator => PLL0             */
+                    SystemFrequency = (RTC_CLK *
+                              (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+                              (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
+                              ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+                    break;
+        }
+    } else {
+        switch (LPC_SC->CLKSRCSEL & 0x03) {
+            case 0:                           /* Internal RC oscillator => PLL0     */
+            case 3:                           /* Reserved, default to Internal RC   */
+                    SystemFrequency = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+                    break;
+            case 1:                           /* Main oscillator => PLL0            */
+                    SystemFrequency = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+                    break;
+            case 2:                           /* RTC oscillator => PLL0             */
+                    SystemFrequency = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+                    break;
+        }
+      }
+
+    #if (FLASH_SETUP == 1)                  /* Flash Accelerator Setup            */
+      LPC_SC->FLASHCFG  = FLASHCFG_Val;
+    #endif
+
+    /* Configure the LEDs. */
+    vParTestInitialise();
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
+{
+    /* This function will get called if a task overflows its stack. */
+
+    ( void ) pxTask;
+    ( void ) pcTaskName;
+    for( ;; );
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
+void vConfigureTimerForRunTimeStats( void ){
+    const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
+
+    /* This function configures a timer that is used as the time base when collecting run time
+     *  statistical information - basically the percentage     of CPU time that each task is utilizing.
+     *  It is called automatically when the scheduler is started
+     *  (assuming configGENERATE_RUN_TIME_STATS is set to 1). */
+
+    /* Power up and feed the timer. */
+    LPC_SC->PCONP |= 0x02UL;
+    LPC_SC->PCLKSEL0 = (LPC_SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
+
+    /* Reset Timer 0 */
+    LPC_TIM0->TCR = TCR_COUNT_RESET;
+
+    /* Just count up. */
+    LPC_TIM0->CTCR = CTCR_CTM_TIMER;
+
+    /* Prescale to a frequency that is good enough to get a decent resolution,
+    but not too fast so as to overflow all the time. */
+    LPC_TIM0->PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
+
+    /* Start the counter. */
+    LPC_TIM0->TCR = TCR_COUNT_ENABLE;
+}
+/*----------------------------------------------------------------------------------------------------------*/
+
diff -r 000000000000 -r d4960fcea8ff syscalls.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syscalls.c	Sat Jan 01 11:17:45 2011 +0000
@@ -0,0 +1,91 @@
+/* Don't need anything here. */
+
+#include <stdlib.h>
+#if 0
+#include <sys/stat.h>
+#else
+
+#endif
+
+//---------------------------------
+// from types.h
+typedef    char *    caddr_t;
+//----------------------------------
+
+int _read_r (struct _reent *r, int file, char * ptr, int len)
+{
+    ( void ) r;
+    ( void ) file;
+    ( void ) ptr;
+    ( void ) len;
+    return -1;
+}
+
+/***************************************************************************/
+
+int _lseek_r (struct _reent *r, int file, int ptr, int dir)
+{
+    ( void ) r;
+    ( void ) file;
+    ( void ) ptr;
+    ( void ) dir;
+    
+    return 0;
+}
+
+/***************************************************************************/
+
+int _write_r (struct _reent *r, int file, char * ptr, int len)
+{  
+    ( void ) r;
+    ( void ) file;
+    ( void ) ptr;
+    ( void ) len;
+    
+    return 0;
+}
+
+/***************************************************************************/
+
+int _close_r (struct _reent *r, int file)
+{
+    ( void ) r;
+    ( void ) file;
+
+    return 0;
+}
+
+/***************************************************************************/
+
+caddr_t _sbrk_r (struct _reent *r, int incr)
+{
+    ( void ) r;
+    ( void ) incr;
+    
+    return 0;
+}
+
+/***************************************************************************/
+
+int _fstat_r (struct _reent *r, int file, struct stat * st)
+{
+    ( void ) r;
+    ( void ) file;
+    ( void ) st;
+    
+    return 0;
+}
+
+/***************************************************************************/
+
+int _isatty_r(struct _reent *r, int fd)
+{
+    ( void ) r;
+    ( void ) fd;
+    
+    return 0;
+}
+
+
+
+