/*\r
- FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
-\r
- This file is part of the FreeRTOS.org distribution.\r
-\r
- FreeRTOS.org is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; either version 2 of the License, or\r
- (at your option) any later version.\r
-\r
- FreeRTOS.org is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with FreeRTOS.org; if not, write to the Free Software\r
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-\r
- A special exception to the GPL can be applied should you wish to distribute\r
- a combined work that includes FreeRTOS.org, without being obliged to provide\r
- the source code for any proprietary components. See the licensing section\r
- of http://www.FreeRTOS.org for full details of how and when the exception\r
- can be applied.\r
+ FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
\r
- ***************************************************************************\r
***************************************************************************\r
* *\r
- * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *\r
- * and even write all or part of your application on your behalf. *\r
- * See http://www.OpenRTOS.com for details of the services we provide to *\r
- * expedite your project. *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS books - available as PDF or paperback *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\r
* *\r
- ***************************************************************************\r
***************************************************************************\r
\r
- Please ensure to read the configuration and relevant port sections of the\r
- online documentation.\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public \r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "#include FreeRTOS.h" must appear in source files before "#include queue.h"\r
+#endif\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and \r
- contact details.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety \r
- critical systems.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting, \r
- licensing and training services.\r
-*/\r
\r
#ifndef QUEUE_H\r
#define QUEUE_H\r
#ifdef __cplusplus\r
extern "C" {\r
#endif\r
+\r
+\r
+#include "mpu_wrappers.h"\r
+\r
+\r
typedef void * xQueueHandle;\r
\r
+\r
/* For internal use only. */\r
#define queueSEND_TO_BACK ( 0 )\r
#define queueSEND_TO_FRONT ( 1 )\r
* queue. h\r
* <pre>\r
xQueueHandle xQueueCreate(\r
- unsigned portBASE_TYPE uxQueueLength,\r
- unsigned portBASE_TYPE uxItemSize\r
- );\r
+ unsigned portBASE_TYPE uxQueueLength,\r
+ unsigned portBASE_TYPE uxItemSize\r
+ );\r
* </pre>\r
*\r
* Creates a new queue instance. This allocates the storage required by the\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
};\r
\r
void vATask( void *pvParameters )\r
{\r
xQueueHandle xQueue1, xQueue2;\r
\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
- if( xQueue1 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue2 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // ... Rest of task code.\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+ if( xQueue1 == 0 )\r
+ {\r
+ // Queue was not created and must not be used.\r
+ }\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue2 == 0 )\r
+ {\r
+ // Queue was not created and must not be used.\r
+ }\r
+\r
+ // ... Rest of task code.\r
}\r
</pre>\r
* \defgroup xQueueCreate xQueueCreate\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSendToToFront(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
* </pre>\r
*\r
* This is a macro that calls xQueueGenericSend().\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0. The\r
- * time is defined in tick periods so the constant portTICK_RATE_MS\r
- * should be used to convert to real time if this is required.\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
*\r
* @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
*\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
- unsigned portLONG ulVar = 10UL;\r
+ unsigned long ulVar = 10UL;\r
\r
void vATask( void *pvParameters )\r
{\r
xQueueHandle xQueue1, xQueue2;\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSendToBack(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
* </pre>\r
*\r
* This is a macro that calls xQueueGenericSend().\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0. The\r
- * time is defined in tick periods so the constant portTICK_RATE_MS\r
- * should be used to convert to real time if this is required.\r
+ * be full. The call will return immediately if this is set to 0 and the queue\r
+ * is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
*\r
* @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
*\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
- unsigned portLONG ulVar = 10UL;\r
+ unsigned long ulVar = 10UL;\r
\r
void vATask( void *pvParameters )\r
{\r
xQueueHandle xQueue1, xQueue2;\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSend(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
* </pre>\r
*\r
* This is a macro that calls xQueueGenericSend(). It is included for\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0. The\r
- * time is defined in tick periods so the constant portTICK_RATE_MS\r
- * should be used to convert to real time if this is required.\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
*\r
* @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
*\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
- unsigned portLONG ulVar = 10UL;\r
+ unsigned long ulVar = 10UL;\r
\r
void vATask( void *pvParameters )\r
{\r
xQueueHandle xQueue1, xQueue2;\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
\r
// ... Rest of task code.\r
}\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0. The\r
- * time is defined in tick periods so the constant portTICK_RATE_MS\r
- * should be used to convert to real time if this is required.\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
*\r
* @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
* item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
- unsigned portLONG ulVar = 10UL;\r
+ unsigned long ulVar = 10UL;\r
\r
void vATask( void *pvParameters )\r
{\r
xQueueHandle xQueue1, xQueue2;\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );\r
- }\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* \defgroup xQueueSend xQueueSend\r
* \ingroup QueueManagement\r
*/\r
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
\r
/**\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueuePeek(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- );</pre>\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ );</pre>\r
*\r
* This is a macro that calls the xQueueGenericReceive() function.\r
*\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
+ * of the call. The time is defined in tick periods so the constant\r
* portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue\r
+ * is empty.\r
*\r
* @return pdTRUE if an item was successfully received from the queue,\r
* otherwise pdFALSE.\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
xQueueHandle xQueue;\r
{\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
\r
- // ...\r
+ // ...\r
\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
\r
// ... Rest of task code.\r
}\r
{\r
struct AMessage *pxRxedMessage;\r
\r
- if( xQueue != 0 )\r
- {\r
- // Peek a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask, but the item still remains on the queue.\r
- }\r
- }\r
+ if( xQueue != 0 )\r
+ {\r
+ // Peek a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask, but the item still remains on the queue.\r
+ }\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueReceive(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- );</pre>\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ );</pre>\r
*\r
* This is a macro that calls the xQueueGenericReceive() function.\r
*\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ * of the call. xQueueReceive() will return immediately if xTicksToWait\r
+ * is zero and the queue is empty. The time is defined in tick periods so the\r
+ * constant portTICK_RATE_MS should be used to convert to real time if this is\r
+ * required.\r
*\r
* @return pdTRUE if an item was successfully received from the queue,\r
* otherwise pdFALSE.\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
xQueueHandle xQueue;\r
{\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
\r
- // ...\r
+ // ...\r
\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
\r
// ... Rest of task code.\r
}\r
{\r
struct AMessage *pxRxedMessage;\r
\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
+ if( xQueue != 0 )\r
+ {\r
+ // Receive a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask.\r
+ }\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueGenericReceive(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- portBASE_TYPE xJustPeek\r
- );</pre>\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ portBASE_TYPE xJustPeek\r
+ );</pre>\r
*\r
* It is preferred that the macro xQueueReceive() be used rather than calling\r
* this function directly.\r
*\r
* @param xTicksToWait The maximum amount of time the task should block\r
* waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
+ * of the call. The time is defined in tick periods so the constant\r
* portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ * xQueueGenericReceive() will return immediately if the queue is empty and\r
+ * xTicksToWait is 0.\r
*\r
* @param xJustPeek When set to true, the item received from the queue is not\r
* actually removed from the queue - meaning a subsequent call to\r
<pre>\r
struct AMessage\r
{\r
- portCHAR ucMessageID;\r
- portCHAR ucData[ 20 ];\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
} xMessage;\r
\r
xQueueHandle xQueue;\r
{\r
struct AMessage *pxMessage;\r
\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
\r
- // ...\r
+ // ...\r
\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
\r
// ... Rest of task code.\r
}\r
{\r
struct AMessage *pxRxedMessage;\r
\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
+ if( xQueue != 0 )\r
+ {\r
+ // Receive a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask.\r
+ }\r
+ }\r
\r
// ... Rest of task code.\r
}\r
* \page vQueueDelete vQueueDelete\r
* \ingroup QueueManagement\r
*/\r
-void vQueueDelete( xQueueHandle xQueue );\r
+void vQueueDelete( xQueueHandle pxQueue );\r
\r
/**\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSendToFrontFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
</pre>\r
*\r
* This is a macro that calls xQueueGenericSendFromISR().\r
<pre>\r
void vBufferISR( void )\r
{\r
- portCHAR cIn;\r
+ char cIn;\r
portBASE_TYPE xHigherPrioritTaskWoken;\r
\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); \r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
\r
- // Post the byte. \r
- xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+ // Post the byte.\r
+ xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ taskYIELD ();\r
+ }\r
}\r
</pre>\r
*\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSendToBackFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
</pre>\r
*\r
* This is a macro that calls xQueueGenericSendFromISR().\r
<pre>\r
void vBufferISR( void )\r
{\r
- portCHAR cIn;\r
+ char cIn;\r
portBASE_TYPE xHigherPriorityTaskWoken;\r
\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); \r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
\r
- // Post the byte.\r
- xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+ // Post the byte.\r
+ xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ taskYIELD ();\r
+ }\r
}\r
</pre>\r
*\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueSendFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
</pre>\r
*\r
* This is a macro that calls xQueueGenericSendFromISR(). It is included\r
<pre>\r
void vBufferISR( void )\r
{\r
- portCHAR cIn;\r
+ char cIn;\r
portBASE_TYPE xHigherPriorityTaskWoken;\r
\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); \r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
\r
- // Post the byte. \r
- xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+ // Post the byte.\r
+ xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- // Actual macro used here is port specific.\r
- taskYIELD_FROM_ISR ();\r
- }\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ // Actual macro used here is port specific.\r
+ taskYIELD_FROM_ISR ();\r
+ }\r
}\r
</pre>\r
*\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueGenericSendFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken,\r
- portBASE_TYPE xCopyPosition\r
- );\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken,\r
+ portBASE_TYPE xCopyPosition\r
+ );\r
</pre>\r
*\r
* It is preferred that the macros xQueueSendFromISR(),\r
<pre>\r
void vBufferISR( void )\r
{\r
- portCHAR cIn;\r
+ char cIn;\r
portBASE_TYPE xHigherPriorityTaskWokenByPost;\r
\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWokenByPost = pdFALSE;\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWokenByPost = pdFALSE;\r
\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); \r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
\r
- // Post each byte.\r
- xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );\r
+ // Post each byte.\r
+ xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );\r
\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
\r
- // Now the buffer is empty we can switch context if necessary. Note that the\r
- // name of the yield function required is port specific.\r
- if( xHigherPriorityTaskWokenByPost )\r
- {\r
- taskYIELD_YIELD_FROM_ISR();\r
- }\r
+ // Now the buffer is empty we can switch context if necessary. Note that the\r
+ // name of the yield function required is port specific.\r
+ if( xHigherPriorityTaskWokenByPost )\r
+ {\r
+ taskYIELD_YIELD_FROM_ISR();\r
+ }\r
}\r
</pre>\r
*\r
* queue. h\r
* <pre>\r
portBASE_TYPE xQueueReceiveFromISR(\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portBASE_TYPE *pxTaskWoken\r
- );\r
+ xQueueHandle pxQueue,\r
+ void *pvBuffer,\r
+ portBASE_TYPE *pxTaskWoken\r
+ );\r
* </pre>\r
*\r
* Receive an item from a queue. It is safe to use this function from within an\r
// Function to create a queue and post some values.\r
void vAFunction( void *pvParameters )\r
{\r
- portCHAR cValueToPost;\r
+ char cValueToPost;\r
const portTickType xBlockTime = ( portTickType )0xff;\r
\r
- // Create a queue capable of containing 10 characters.\r
- xQueue = xQueueCreate( 10, sizeof( portCHAR ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
+ // Create a queue capable of containing 10 characters.\r
+ xQueue = xQueueCreate( 10, sizeof( char ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
\r
- // ...\r
+ // ...\r
\r
- // Post some characters that will be used within an ISR. If the queue\r
- // is full then this task will block for xBlockTime ticks.\r
- cValueToPost = 'a';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
- cValueToPost = 'b';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ // Post some characters that will be used within an ISR. If the queue\r
+ // is full then this task will block for xBlockTime ticks.\r
+ cValueToPost = 'a';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ cValueToPost = 'b';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
\r
- // ... keep posting characters ... this task may block when the queue\r
- // becomes full.\r
+ // ... keep posting characters ... this task may block when the queue\r
+ // becomes full.\r
\r
- cValueToPost = 'c';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ cValueToPost = 'c';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
}\r
\r
// ISR that outputs all the characters received on the queue.\r
void vISR_Routine( void )\r
{\r
portBASE_TYPE xTaskWokenByReceive = pdFALSE;\r
- portCHAR cRxedChar;\r
-\r
- while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
- {\r
- // A character was received. Output the character now.\r
- vOutputCharacter( cRxedChar );\r
-\r
- // If removing the character from the queue woke the task that was\r
- // posting onto the queue cTaskWokenByReceive will have been set to\r
- // pdTRUE. No matter how many times this loop iterates only one\r
- // task will be woken.\r
- }\r
-\r
- if( cTaskWokenByPost != ( portCHAR ) pdFALSE;\r
- {\r
- taskYIELD ();\r
- }\r
+ char cRxedChar;\r
+\r
+ while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
+ {\r
+ // A character was received. Output the character now.\r
+ vOutputCharacter( cRxedChar );\r
+\r
+ // If removing the character from the queue woke the task that was\r
+ // posting onto the queue cTaskWokenByReceive will have been set to\r
+ // pdTRUE. No matter how many times this loop iterates only one\r
+ // task will be woken.\r
+ }\r
+\r
+ if( cTaskWokenByPost != ( char ) pdFALSE;\r
+ {\r
+ taskYIELD ();\r
+ }\r
}\r
</pre>\r
* \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );\r
\r
\r
-/* \r
+/*\r
* xQueueAltGenericSend() is an alternative version of xQueueGenericSend().\r
* Likewise xQueueAltGenericReceive() is an alternative version of\r
* xQueueGenericReceive().\r
*\r
- * The source code that implements the alternative (Alt) API is much \r
- * simpler because it executes everything from within a critical section. \r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
- * preferred fully featured API too. The fully featured API has more \r
- * complex code that takes longer to execute, but makes much less use of \r
- * critical sections. Therefore the alternative API sacrifices interrupt \r
+ * The source code that implements the alternative (Alt) API is much\r
+ * simpler because it executes everything from within a critical section.\r
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
+ * preferred fully featured API too. The fully featured API has more\r
+ * complex code that takes longer to execute, but makes much less use of\r
+ * critical sections. Therefore the alternative API sacrifices interrupt\r
* responsiveness to gain execution speed, whereas the fully featured API\r
* sacrifices execution speed to ensure better interrupt responsiveness.\r
*/\r
* For internal use only. Use xSemaphoreTakeMutexRecursive() or\r
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly.\r
*/\r
-portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );\r
-portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );\r
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime );\r
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );\r
+\r
+/*\r
+ * The registry is provided as a means for kernel aware debuggers to\r
+ * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add\r
+ * a queue, semaphore or mutex handle to the registry if you want the handle\r
+ * to be available to a kernel aware debugger. If you are not using a kernel\r
+ * aware debugger then this function can be ignored.\r
+ *\r
+ * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the\r
+ * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0\r
+ * within FreeRTOSConfig.h for the registry to be available. Its value\r
+ * does not effect the number of queues, semaphores and mutexes that can be\r
+ * created - just the number that the registry can hold.\r
+ *\r
+ * @param xQueue The handle of the queue being added to the registry. This\r
+ * is the handle returned by a call to xQueueCreate(). Semaphore and mutex\r
+ * handles can also be passed in here.\r
+ *\r
+ * @param pcName The name to be associated with the handle. This is the\r
+ * name that the kernel aware debugger will display.\r
+ */\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+ void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );\r
+#endif\r
+\r
+\r
\r
\r
#ifdef __cplusplus\r