--- /dev/null
+/*\r
+ FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ 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
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license\r
+ and contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under\r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/*\r
+ * Demonstrates the creation an use of queue sets.\r
+ *\r
+ * A receive task creates a number of queues and adds them to a queue set before\r
+ * blocking on a queue set receive. A transmit task repeatedly unblocks the\r
+ * receive task by sending messages to the queues in a pseudo random order.\r
+ * The receive task removes the messages from the queues and flags an error if\r
+ * the received message does not match that expected.\r
+ */\r
+\r
+/* Kernel includes. */\r
+#include <FreeRTOS.h>\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Demo includes. */\r
+#include "QueueSet.h"\r
+\r
+/* The number of queues that are created and added to the queue set. */\r
+#define queuesetNUM_QUEUES_IN_SET 3\r
+\r
+/* The length of each created queue. */\r
+#define queuesetQUEUE_LENGTH 3\r
+\r
+/* Block times used in this demo. A block time or 0 means "don't block". */\r
+#define queuesetSHORT_DELAY 200\r
+#define queuesetDONT_BLOCK 0\r
+\r
+/*\r
+ * The task that periodically sends to the queue set.\r
+ */\r
+static void prvQueueSetSendingTask( void *pvParameters );\r
+\r
+/*\r
+ * The task that reads from the queue set.\r
+ */\r
+static void prvQueueSetReceivingTask( void *pvParameters );\r
+\r
+/* The queues that are added to the set. */\r
+static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };\r
+\r
+/* The handle of the queue set to which the queues are added. */\r
+static xQueueSetHandle xQueueSet;\r
+\r
+/* If the prvQueueSetReceivingTask() task has not detected any errors then\r
+it increments ulCycleCounter on each iteration.\r
+xAreQueueSetTasksStillRunning() returns pdPASS if the value of\r
+ulCycleCounter has changed between consecutive calls, and pdFALSE if\r
+ulCycleCounter has stopped incrementing (indicating an error condition). */\r
+volatile unsigned long ulCycleCounter = 0UL;\r
+\r
+/* Set to pdFAIL if an error is detected by any queue set task.\r
+ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */\r
+volatile portBASE_TYPE xQueueSetTasksStatus = pdPASS;\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xTaskHandle xQueueSetSendingTask;\r
+\r
+ /* Create the two queues. The handle of the sending task is passed into\r
+ the receiving task using the task parameter. The receiving task uses the\r
+ handle to resume the sending task after it has created the queues. */\r
+ xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xQueueSetSendingTask );\r
+ xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, uxPriority, NULL );\r
+\r
+ /* It is important that the sending task does not attempt to write to a\r
+ queue before the queue has been created. It is therefore placed into the\r
+ suspended state before the scheduler has started. It is resumed by the\r
+ receiving task after the receiving task has created the queues and added the\r
+ queues to the queue set. */\r
+ vTaskSuspend( xQueueSetSendingTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xAreQueueSetTasksStillRunning( void )\r
+{\r
+static unsigned long ulLastCycleCounter;\r
+portBASE_TYPE xReturn;\r
+\r
+ if( ulLastCycleCounter == ulCycleCounter )\r
+ {\r
+ /* The cycle counter is no longer being incremented. Either one of the\r
+ tasks is stalled or an error has been detected. */\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueSetSendingTask( void *pvParameters )\r
+{\r
+unsigned long ulTxValue = 0;\r
+portBASE_TYPE xQueueToWriteTo;\r
+\r
+ /* Remove compiler warning about the unused parameter. */\r
+ ( void ) pvParameters;\r
+\r
+ srand( ( unsigned int ) &ulTxValue );\r
+\r
+ for( ;; )\r
+ {\r
+ /* Generate the index for the queue to which a value is to be sent. */\r
+ xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;\r
+ if( xQueueSendToBack( xQueues[ xQueueToWriteTo ], &ulTxValue, portMAX_DELAY ) != pdPASS )\r
+ {\r
+ /* The send should always pass as an infinite block time was\r
+ used. */\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+\r
+ ulTxValue++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueSetReceivingTask( void *pvParameters )\r
+{\r
+unsigned long ulReceived, ulLastReceived = ~0UL;\r
+xQueueHandle xActivatedQueue;\r
+portBASE_TYPE x;\r
+xTaskHandle xQueueSetSendingTask;\r
+\r
+ /* The handle to the sending task is passed in using the task parameter. */\r
+ xQueueSetSendingTask = ( xTaskHandle ) pvParameters;\r
+\r
+ /* Ensure the queues are created and the queue set configured before the\r
+ sending task is unsuspended.\r
+\r
+ First Create the queue set such that it will be able to hold a message for\r
+ every space in every queue in the set. */\r
+ xQueueSet = xQueueSetCreate( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH );\r
+\r
+ for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )\r
+ {\r
+ /* Create the queue and add it to the set. */\r
+ xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );\r
+ configASSERT( xQueues[ x ] );\r
+ if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdPASS )\r
+ {\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+\r
+ /* The queue has now been added to the queue set and cannot be added to\r
+ another. */\r
+ if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdFAIL )\r
+ {\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+ }\r
+\r
+ /* The task that sends to the queues is not running yet, so attempting to\r
+ read from the queue set should fail, resulting in xActivatedQueue being set\r
+ to NULL. */\r
+ xActivatedQueue = xQueueReadMultiple( xQueueSet, queuesetSHORT_DELAY );\r
+ configASSERT( xActivatedQueue == NULL );\r
+\r
+ /* Resume the task that writes to the queues. */\r
+ vTaskResume( xQueueSetSendingTask );\r
+\r
+ for( ;; )\r
+ {\r
+ /* Wait for a message to arrive on one of the queues in the set. */\r
+ xActivatedQueue = xQueueReadMultiple( xQueueSet, portMAX_DELAY );\r
+ configASSERT( xActivatedQueue );\r
+\r
+ if( xActivatedQueue == NULL )\r
+ {\r
+ /* This should not happen as an infinite delay was used. */\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ /* Reading from the queue should pass with a zero block time as\r
+ this task will only run when something has been posted to a task\r
+ in the queue set. */\r
+ if( xQueueReceive( xActivatedQueue, &ulReceived, queuesetDONT_BLOCK ) != pdPASS )\r
+ {\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+\r
+ /* It is always expected that the received value will be one\r
+ greater than the previously received value. */\r
+ configASSERT( ulReceived == ( ulLastReceived + 1 ) );\r
+ if( ulReceived != ( ulLastReceived + 1 ) )\r
+ {\r
+ xQueueSetTasksStatus = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ ulLastReceived = ulReceived;\r
+ }\r
+ }\r
+\r
+ if( xQueueSetTasksStatus == pdPASS )\r
+ {\r
+ ulCycleCounter++;\r
+ }\r
+ }\r
+}\r
+\r
*/\r
\r
/*\r
- * This version of integer. c is for use on systems that have limited stack\r
- * space and no display facilities. The complete version can be found in\r
- * the Demo/Common/Full directory.\r
- *\r
- * As with the full version, the tasks created in this file are a good test \r
- * of the scheduler context switch mechanism. The processor has to access \r
- * 32bit variables in two or four chunks (depending on the processor). The low \r
- * priority of these tasks means there is a high probability that a context \r
- * switch will occur mid calculation. See flop. c documentation for \r
- * more information.\r
- *\r
+ * Creates one or more tasks that repeatedly perform a set of integer\r
+ * calculations. The result of each run-time calculation is compared to the \r
+ * known expected result - with a mismatch being indicative of an error in the\r
+ * context switch mechanism.\r
*/\r
\r
-/*\r
-Changes from V1.2.1\r
-\r
- + The constants used in the calculations are larger to ensure the\r
- optimiser does not truncate them to 16 bits.\r
-\r
-Changes from V1.2.3\r
-\r
- + uxTaskCheck is now just used as a boolean. Instead of incrementing\r
- the variable each cycle of the task, the variable is simply set to\r
- true. sAreIntegerMathsTaskStillRunning() sets it back to false and\r
- expects it to have been set back to true by the time it is called\r
- again.\r
- + A division has been included in the calculation.\r
-*/\r
-\r
#include <stdlib.h>\r
\r
/* Scheduler include files. */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT \r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ 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
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license \r
+ and contact details. \r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef QUEUE_WAIT_MULTIPLE_H\r
+#define QUEUE_WAIT_MULTIPLE_H\r
+\r
+void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreQueueSetTasksStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
#define configUSE_APPLICATION_TASK_TAG 0\r
#define configUSE_COUNTING_SEMAPHORES 1\r
#define configUSE_ALTERNATIVE_API 1\r
+#define configUSE_QUEUE_SETS 1\r
\r
#define configUSE_TIMERS 1\r
#define configTIMER_TASK_PRIORITY 2\r
/* Set the following definitions to 1 to include the API function, or zero\r
to exclude the API function. */\r
\r
-#define INCLUDE_vTaskPrioritySet 1\r
-#define INCLUDE_uxTaskPriorityGet 1\r
-#define INCLUDE_vTaskDelete 1\r
-#define INCLUDE_vTaskCleanUpResources 0\r
-#define INCLUDE_vTaskSuspend 1\r
-#define INCLUDE_vTaskDelayUntil 1\r
-#define INCLUDE_vTaskDelay 1\r
-#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
-#define INCLUDE_xTaskGetSchedulerState 1\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 1\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+#define INCLUDE_xTaskGetSchedulerState 1\r
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1\r
-#define INCLUDE_xTaskGetIdleTaskHandle 1\r
-#define INCLUDE_pcTaskGetTaskName 1\r
-#define INCLUDE_eTaskStateGet 1\r
+#define INCLUDE_xTaskGetIdleTaskHandle 1\r
+#define INCLUDE_pcTaskGetTaskName 1\r
+#define INCLUDE_eTaskGetState 1\r
\r
extern void vAssertCalled( void );\r
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()\r
version. */\r
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1\r
\r
-#define configUSE_QUEUE_SETS 1\r
\r
#endif /* FREERTOS_CONFIG_H */\r
<ClCompile Include="..\Common\Minimal\integer.c" />\r
<ClCompile Include="..\Common\Minimal\PollQ.c" />\r
<ClCompile Include="..\Common\Minimal\QPeek.c" />\r
+ <ClCompile Include="..\Common\Minimal\QueueSet.c" />\r
<ClCompile Include="..\Common\Minimal\semtest.c" />\r
<ClCompile Include="..\Common\Minimal\timerdemo.c" />\r
<ClCompile Include="DemosModifiedForLowTickRate\recmutex.c" />\r
<ClCompile Include="..\Common\Minimal\dynamic.c">\r
<Filter>Demo App Source\Common Demo Tasks</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\Common\Minimal\QueueSet.c">\r
+ <Filter>Demo App Source\Common Demo Tasks</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="FreeRTOSConfig.h">\r
#include "countsem.h"\r
#include "death.h"\r
#include "dynamic.h"\r
+#include "QueueSet.h"\r
\r
/* Priorities at which the tasks are created. */\r
-#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )\r
-#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
-#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
-#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
-#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
-#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
-#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
-#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
-#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
-#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )\r
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
+#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainQUEUE_SET_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
\r
#define mainTIMER_TEST_PERIOD ( 50 )\r
\r
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );\r
vStartCountingSemaphoreTasks();\r
vStartDynamicPriorityTasks();\r
+ vStartQueueSetTasks( mainQUEUE_SET_TASK_PRIORITY );\r
\r
/* The suicide tasks must be created last as they need to know how many\r
tasks were running prior to their creation. This then allows them to \r
{\r
pcStatusMessage = "Error: Dynamic\r\n";\r
}\r
+ else if( xAreQueueSetTasksStillRunning() != pdPASS )\r
+ {\r
+ pcStatusMessage = "Error: Queue set\r\n";\r
+ }\r
\r
/* This is the only task that uses stdout so its ok to call printf() \r
directly. */\r
\r
/* For backward compatability. */\r
#define eTaskStateGet eTaskGetState\r
-#define INCLUDE_eTaskStateGet INCLUDE_eTaskGetState\r
\r
#endif /* INC_FREERTOS_H */\r
\r
/*\r
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
\r
- FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT \r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
***************************************************************************\r
FreeRTOS WEB site.\r
\r
1 tab == 4 spaces!\r
- \r
+\r
***************************************************************************\r
* *\r
* Having a problem? Start by reading the FAQ "My application does *\r
* *\r
***************************************************************************\r
\r
- \r
- http://www.FreeRTOS.org - Documentation, training, latest versions, license \r
- and contact details. \r
- \r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license\r
+ and contact details.\r
+\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool.\r
\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
+ provide a safety engineered and independently SIL3 certified version under\r
the SafeRTOS brand: http://www.SafeRTOS.com.\r
*/\r
\r
#include "mpu_wrappers.h"\r
\r
/**\r
- * Type by which queues are referenced. For example, a call to xQueueCreate\r
- * returns (via a pointer parameter) an xQueueHandle variable that can then\r
- * be used as a parameter to xQueueSend(), xQueueReceive(), etc.\r
+ * Type by which queues are referenced. For example, a call to xQueueCreate()\r
+ * returns an xQueueHandle variable that can then be used as a parameter to\r
+ * xQueueSend(), xQueueReceive(), etc.\r
*/\r
typedef void * xQueueHandle;\r
\r
+/**\r
+ * Type by which queue sets are referenced. For example, a call to\r
+ * xQueueSetCreate() returns an xQueueSet variable that can then be used as a\r
+ * parameter to xQueueReadMultiple(), xQueueAddToQueueSet(), etc.\r
+ */\r
+typedef void * xQueueSetHandle;\r
\r
/* For internal use only. */\r
#define queueSEND_TO_BACK ( 0 )\r
signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
\r
/*\r
- * For internal use only. Use xSemaphoreCreateMutex(), \r
- * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling \r
+ * For internal use only. Use xSemaphoreCreateMutex(),\r
+ * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling\r
* these functions directly.\r
*/\r
xQueueHandle xQueueCreateMutex( unsigned char ucQueueType );\r
#endif\r
\r
/*\r
- * Generic version of the queue creation function, which is in turn called by \r
+ * Generic version of the queue creation function, which is in turn called by\r
* any queue, semaphore or mutex creation function or macro.\r
*/\r
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );\r
\r
+/*\r
+ * Queue sets provide a mechanism to allow a task to block (pend) on a read\r
+ * operation from multiple queues or semaphores simultaneously.\r
+ *\r
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
+ * function.\r
+ *\r
+ * A queue set must be explicitly created using a call to xQueueSetCreate()\r
+ * before it can be used. Once created, standard FreeRTOS queues and semaphores\r
+ * can be added to the set using calls to xQueueAddToQueueSet().\r
+ * xQueueReadMultiple() is then used to determine which, if any, of the queues\r
+ * or semaphores contained in the set is in a state where a queue read or\r
+ * semaphore take operation would be successful.\r
+ *\r
+ * Note 1: See the documentation on http://wwwFreeRTOS.org for reasons why\r
+ * queue sets are very rarely needed in practice as there are simpler\r
+ * alternatives. Queue sets are provided to allow FreeRTOS to be integrated\r
+ * with legacy third party driver code.\r
+ *\r
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the\r
+ * mutex holder to inherit the priority of the blocked task.\r
+ *\r
+ * Note 3: An additional 4 bytes of RAM is required for each space in a every\r
+ * queue added to a queue set. Therefore counting semaphores with large maximum\r
+ * counts should not be added to queue sets.\r
+ *\r
+ * @param uxEventQueueLength Queue sets themselves queue events that occur on\r
+ * the queues and semaphores contained in the set. uxEventQueueLength specifies\r
+ * the maximum number of events that can be queued at once. To be absolutely\r
+ * certain that events are not lost uxEventQueueLength should be set to the\r
+ * total sum of the length of the queues added to the set, where binary\r
+ * semaphores and mutexes have a length of 1, and counting semaphores have a\r
+ * length set by their maximum count value. Examples:\r
+ * + If a queue set is to hold a queue of length 5, another queue of length 12,\r
+ * and a binary semaphore, then uxEventQueueLength should be set to\r
+ * (5 + 12 + 1), or 18.\r
+ * + If a queue set is to hold three binary semaphores then uxEventQueueLength\r
+ * should be set to (1 + 1 + 1 ), or 3.\r
+ * + If a queue set is to hold a counting semaphore that has a maximum count of\r
+ * 5, and a counting semaphore that has a maximum count of 3, then\r
+ * uxEventQueueLength should be set to (5 + 3), or 8.\r
+ *\r
+ * @return If the queue set is created successfully then a handle to the created\r
+ * queue set is returned. Otherwise NULL is returned.\r
+ */\r
+xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );\r
+\r
+/*\r
+ * Adds a queue or semaphore to a queue set that was previously created by a\r
+ * call to xQueueSetCreate().\r
+ *\r
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
+ * function.\r
+ *\r
+ * @param xQueue The handle of the queue or semaphore being added to the\r
+ * queue set. Variables of type xSemaphoreHandle can be safely added to a\r
+ * queue set but may require casting to an xQueueHandle type to avoid compiler\r
+ * warnings.\r
+ *\r
+ * @param xQueueSet The handle of the queue set to which the queue or semaphore\r
+ * is being added.\r
+ *\r
+ * @return If the queue or semaphore was successfully added to the queue set \r
+ * then pdPASS is returned. If the queue could not be successfully added to the \r
+ * queue set because it is already a member of a different queue set then pdFAIL \r
+ * is returned.\r
+ */\r
+portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet );\r
+\r
+/*\r
+ * Removes a queue or semaphore from a queue set.\r
+ *\r
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
+ * function.\r
+ *\r
+ * @param xQueue The handle of the queue or semaphore being removed from the\r
+ * queue set. Variables of type xSemaphoreHandle can be safely used but may \r
+ * require casting to an xQueueHandle type to avoid compiler warnings.\r
+ *\r
+ * @param xQueueSet The handle of the queue set in which the queue or semaphore\r
+ * is included.\r
+ *\r
+ * @return If the queue or semaphore was successfully removed from the queue set \r
+ * then pdPASS is returned. If the queue was not in the queue set then pdFAIL\r
+ * is returned.\r
+ */\r
+portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue );\r
+\r
+/*\r
+ * xQueueReadMultiple() allows a task to block (pend) on a read operation on\r
+ * all the queues and semaphores in a queue set simultaneously.\r
+ *\r
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
+ * function.\r
+ *\r
+ * Note 1: See the documentation on http://wwwFreeRTOS.org for reasons why\r
+ * queue sets are very rarely needed in practice as there are simpler\r
+ * alternatives. Queue sets are provided to allow FreeRTOS to be integrated\r
+ * with legacy third party driver code.\r
+ *\r
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the\r
+ * mutex holder to inherit the priority of the blocked task.\r
+ *\r
+ * @param xQueueSet The queue set on which the task will (potentially) block.\r
+ *\r
+ * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will\r
+ * remain in the Blocked state (with other tasks executing) to wait for a member\r
+ * of the queue set to be ready for a successful queue read or semaphore take\r
+ * operation.\r
+ *\r
+ * @return xQueueReadMultiple() will return the handle of a queue contained \r
+ * in the queue set that contains data, or the handle of a semaphore contained\r
+ * in the queue set that is available, or NULL if no such queue or semaphore \r
+ * exists before before the specified block time expires.\r
+ */\r
+xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );\r
+\r
/* Not public API functions. */\r
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );\r
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );\r
\r
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
\r
-/*-----------------------------------------------------------\r
- * PUBLIC LIST API documented in list.h\r
- *----------------------------------------------------------*/\r
-\r
/* Constants used with the cRxLock and xTxLock structure members. */\r
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )\r
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )\r
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
+#define queueQUEUE_TYPE_SET ( 5U )\r
\r
/*\r
* Definition of the queue used by the scheduler.\r
*/\r
typedef struct QueueDefinition\r
{\r
- signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
- 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. */\r
+ signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
+ 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. */\r
\r
- signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
- signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
+ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
+ signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
\r
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */\r
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */\r
unsigned char ucQueueType;\r
#endif\r
\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ struct QueueDefinition *pxQueueSetContainer;\r
+ #endif\r
+\r
} xQUEUE;\r
/*-----------------------------------------------------------*/\r
\r
* pointer to void.\r
*/\r
typedef xQUEUE * xQueueHandle;\r
+typedef xQUEUE * xQueueSetHandle;\r
\r
/*\r
- * Prototypes for public functions are included here so we don't have to\r
- * include the API header file (as it defines xQueueHandle differently). These\r
- * functions are documented in the API header file.\r
+ * In order to implement strict data hiding, the queue.h header file defines \r
+ * xQueueHandle and xQueueSetHandle as pointers to void. In this file\r
+ * xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.\r
+ * Therefore the queue.h header file cannot be included in this source file,\r
+ * and the function prototypes are provided directly.\r
*/\r
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;\r
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;\r
+xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Co-routine queue functions differ from task queue functions. Co-routines are\r
* an optional component.\r
*/\r
-#if configUSE_CO_ROUTINES == 1\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
* The queue registry is just a means for kernel aware debuggers to locate\r
* queue structures. It has no other purpose so is an optional component.\r
*/\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
/* The type stored within the queue registry array. This allows a name\r
to be assigned to each queue making kernel aware debugging a little\r
* Copies an item out of a queue.\r
*/\r
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+ /*\r
+ * Checks to see if a queue is a member of a queue set, and if so, notifies\r
+ * the queue set that the queue contains data.\r
+ */\r
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );\r
+#endif\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
taskEXIT_CRITICAL()\r
/*-----------------------------------------------------------*/\r
\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC QUEUE MANAGEMENT API documented in queue.h\r
- *----------------------------------------------------------*/\r
-\r
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
{\r
configASSERT( pxQueue );\r
pxNewQueue->uxLength = uxQueueLength;\r
pxNewQueue->uxItemSize = uxItemSize;\r
xQueueGenericReset( pxNewQueue, pdTRUE );\r
+ \r
#if ( configUSE_TRACE_FACILITY == 1 )\r
{\r
pxNewQueue->ucQueueType = ucQueueType;\r
}\r
#endif /* configUSE_TRACE_FACILITY */\r
\r
+ #if( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ pxNewQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+\r
traceQUEUE_CREATE( pxNewQueue );\r
xReturn = pxNewQueue;\r
}\r
}\r
#endif\r
\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ pxNewQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ #endif\r
+\r
/* Ensure the event queues start with the correct state. */\r
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
#endif /* configUSE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xQueueGetMutexHolder == 1 ) )\r
+#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )\r
\r
void* xQueueGetMutexHolder( xQueueHandle xSemaphore )\r
{\r
#endif /* configUSE_RECURSIVE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_RECURSIVE_MUTEXES == 1\r
+#if ( configUSE_RECURSIVE_MUTEXES == 1 )\r
\r
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )\r
{\r
#endif /* configUSE_RECURSIVE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_COUNTING_SEMAPHORES == 1\r
+#if ( configUSE_COUNTING_SEMAPHORES == 1 )\r
\r
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
{\r
portYIELD_WITHIN_API();\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( prvCheckForMembershipOfQueueSet( pxQueue, xCopyPosition ) == pdTRUE )\r
+ {\r
+ /* The queue is a member of a queue set, and posting to\r
+ the queue set caused a higher priority task to unblock.\r
+ A context switch is required. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
\r
taskEXIT_CRITICAL();\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_ALTERNATIVE_API == 1\r
+#if ( configUSE_ALTERNATIVE_API == 1 )\r
\r
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
{\r
#endif /* configUSE_ALTERNATIVE_API */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_ALTERNATIVE_API == 1\r
+#if ( configUSE_ALTERNATIVE_API == 1 )\r
\r
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
{\r
}\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK );\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
}\r
else\r
{\r
{\r
traceQUEUE_PEEK( pxQueue );\r
\r
- /* We are not removing the data, so reset our read\r
+ /* The data is not being removed, so reset the read \r
pointer. */\r
pxQueue->pcReadFrom = pcOriginalReadPosition;\r
\r
portYIELD_WITHIN_API();\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xQueueGenericSend( pxQueue->pxQueueSetContainer, &pxQueue, 0, queueSEND_TO_BACK );\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
}\r
\r
taskEXIT_CRITICAL();\r
return pxQueue->ucQueueNumber;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
pxQueue->ucQueueNumber = ucQueueNumber;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
return pxQueue->ucQueueType;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
context switch is required. */\r
vTaskMissedYield();\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, &xHigherPriorityTaskWoken, queueSEND_TO_BACK );\r
+ if( xHigherPriorityTaskWoken != pdFALSE )\r
+ {\r
+ vTaskMissedYield();\r
+ }\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
\r
--( pxQueue->xTxLock );\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* If the queue is already full we may have to block. A critical section\r
- is required to prevent an interrupt removing something from the queue\r
- between the check to see if the queue is full and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
+ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
{\r
- if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
+ signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already full we may have to block. A critical section\r
+ is required to prevent an interrupt removing something from the queue\r
+ between the check to see if the queue is full and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* The queue is full - do we want to block or just leave without\r
- posting? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
- {\r
- /* As this is called from a coroutine we cannot block directly, but\r
- return indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
{\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
+ /* The queue is full - do we want to block or just leave without\r
+ posting? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is called from a coroutine we cannot block directly, but\r
+ return indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
}\r
}\r
- }\r
- portENABLE_INTERRUPTS();\r
+ portENABLE_INTERRUPTS();\r
\r
- portNOP();\r
+ portNOP();\r
\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* There is room in the queue, copy the data into the queue. */\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
- xReturn = pdPASS;\r
-\r
- /* Were any co-routines waiting for data to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ /* There is room in the queue, copy the data into the queue. */\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+ xReturn = pdPASS;\r
+\r
+ /* Were any co-routines waiting for data to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
- /* The co-routine waiting has a higher priority so record\r
- that a yield might be appropriate. */\r
- xReturn = errQUEUE_YIELD;\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The co-routine waiting has a higher priority so record\r
+ that a yield might be appropriate. */\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
}\r
}\r
+ else\r
+ {\r
+ xReturn = errQUEUE_FULL;\r
+ }\r
}\r
- else\r
- {\r
- xReturn = errQUEUE_FULL;\r
- }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
}\r
- portENABLE_INTERRUPTS();\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* If the queue is already empty we may have to block. A critical section\r
- is required to prevent an interrupt adding something to the queue\r
- between the check to see if the queue is empty and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
+ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
{\r
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
+ signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already empty we may have to block. A critical section\r
+ is required to prevent an interrupt adding something to the queue\r
+ between the check to see if the queue is empty and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* There are no messages in the queue, do we want to block or just\r
- leave with nothing? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
+ if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
{\r
- /* As this is a co-routine we cannot block directly, but return\r
- indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
- {\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
+ /* There are no messages in the queue, do we want to block or just\r
+ leave with nothing? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is a co-routine we cannot block directly, but return\r
+ indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
}\r
}\r
- }\r
- portENABLE_INTERRUPTS();\r
+ portENABLE_INTERRUPTS();\r
\r
- portNOP();\r
+ portNOP();\r
\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* Data is available from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ /* Data is available from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
\r
- xReturn = pdPASS;\r
+ xReturn = pdPASS;\r
\r
- /* Were any co-routines waiting for space to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ /* Were any co-routines waiting for space to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
- xReturn = errQUEUE_YIELD;\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
}\r
}\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
}\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
}\r
- portENABLE_INTERRUPTS();\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
-{\r
- /* Cannot block within an ISR so if there is no space on the queue then\r
- exit without doing anything. */\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
{\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
-\r
- /* We only want to wake one co-routine per ISR, so check that a\r
- co-routine has not already been woken. */\r
- if( xCoRoutinePreviouslyWoken == pdFALSE )\r
+ /* Cannot block within an ISR so if there is no space on the queue then\r
+ exit without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+\r
+ /* We only want to wake one co-routine per ISR, so check that a\r
+ co-routine has not already been woken. */\r
+ if( xCoRoutinePreviouslyWoken == pdFALSE )\r
{\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
- return pdTRUE;\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ return pdTRUE;\r
+ }\r
}\r
}\r
}\r
+\r
+ return xCoRoutinePreviouslyWoken;\r
}\r
\r
- return xCoRoutinePreviouslyWoken;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* We cannot block from an ISR, so check there is data available. If\r
- not then just leave without doing anything. */\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
{\r
- /* Copy the data from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ signed portBASE_TYPE xReturn;\r
\r
- if( ( *pxCoRoutineWoken ) == pdFALSE )\r
+ /* We cannot block from an ISR, so check there is data available. If\r
+ not then just leave without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ /* Copy the data from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
{\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+\r
+ if( ( *pxCoRoutineWoken ) == pdFALSE )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
- *pxCoRoutineWoken = pdTRUE;\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ *pxCoRoutineWoken = pdTRUE;\r
+ }\r
}\r
}\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
}\r
\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
+ return xReturn;\r
}\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )\r
{\r
}\r
}\r
\r
-#endif\r
+#endif /* configQUEUE_REGISTRY_SIZE */\r
/*-----------------------------------------------------------*/\r
\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
static void vQueueUnregisterQueue( xQueueHandle xQueue )\r
{\r
\r
}\r
\r
-#endif\r
+#endif /* configQUEUE_REGISTRY_SIZE */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_TIMERS == 1\r
+#if ( configUSE_TIMERS == 1 )\r
\r
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )\r
{\r
prvUnlockQueue( pxQueue );\r
}\r
\r
-#endif\r
+#endif /* configUSE_TIMERS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )\r
+ {\r
+ xQUEUE *pxQueue;\r
+\r
+ pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET );\r
+\r
+ return ( xQueueSetHandle ) pxQueue;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ if( xQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xQueue->pxQueueSetContainer = xQueueSet;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ if( xQueue->pxQueueSetContainer != xQueueSet )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )\r
+ {\r
+ xQueueHandle xReturn = NULL;\r
+ \r
+ xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )\r
+ {\r
+ xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;\r
+ portBASE_TYPE xReturn = pdFALSE;\r
+\r
+ if( pxQueueSetContainer != NULL )\r
+ {\r
+ if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )\r
+ {\r
+ prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+ if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority */\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
\r
\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 0\r
+#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )\r
\r
/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is\r
performed in a generic way that is not optimised to any particular\r
\r
/*lint +e956 */\r
\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CREATION API documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
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 )\r
{\r
signed portBASE_TYPE xReturn;\r
/* Check the alignment of the calculated top of stack is correct. */\r
configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
}\r
- #else\r
+ #else /* portSTACK_GROWTH */\r
{\r
pxTopOfStack = pxNewTCB->pxStack;\r
\r
other extreme of the stack space. */\r
pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
}\r
- #endif\r
+ #endif /* portSTACK_GROWTH */\r
\r
/* Setup the newly allocated TCB with the initial state of the task. */\r
prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );\r
{\r
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
}\r
- #else\r
+ #else /* portUSING_MPU_WRAPPERS */\r
{\r
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );\r
}\r
- #endif\r
+ #endif /* portUSING_MPU_WRAPPERS */\r
\r
/* Check the alignment of the initialised stack. */\r
portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
/* Add a counter into the TCB for tracing only. */\r
pxNewTCB->uxTCBNumber = uxTaskNumber;\r
}\r
- #endif\r
+ #endif /* configUSE_TRACE_FACILITY */\r
uxTaskNumber++;\r
traceTASK_CREATE( pxNewTCB );\r
\r
}\r
}\r
\r
-#endif\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CONTROL API documented in task.h\r
- *----------------------------------------------------------*/\r
+#endif /* INCLUDE_vTaskDelete */\r
+/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskDelayUntil == 1 )\r
\r
}\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskDelayUntil */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskDelay == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskDelay */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_eTaskGetState == 1 )\r
return eReturn;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_eTaskGetState */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_uxTaskPriorityGet == 1 )\r
return uxReturn;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_uxTaskPriorityGet */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskPrioritySet == 1 )\r
( void ) uxPriorityUsedOnEntry;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskPrioritySet */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskSuspend */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
return xReturn;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskSuspend */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_vTaskSuspend */\r
\r
/*-----------------------------------------------------------*/\r
\r
return xYieldRequired;\r
}\r
\r
-#endif\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC SCHEDULER CONTROL documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
+#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */\r
+/*-----------------------------------------------------------*/\r
\r
void vTaskStartScheduler( void )\r
{\r
/* Create the idle task without storing its handle. */\r
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );\r
}\r
- #endif\r
+ #endif /* INCLUDE_xTaskGetIdleTaskHandle */\r
\r
#if ( configUSE_TIMERS == 1 )\r
{\r
xReturn = xTimerCreateTimerTask();\r
}\r
}\r
- #endif\r
+ #endif /* configUSE_TIMERS */\r
\r
if( xReturn == pdPASS )\r
{\r
}\r
}\r
\r
- /* This line will only be reached if the kernel could not be started. */\r
+ /* This line will only be reached if the kernel could not be started, or\r
+ vTaskEndScheduler() was called (vTaskEndScheduler() is not implemented for\r
+ most ports). */\r
configASSERT( xReturn );\r
}\r
/*-----------------------------------------------------------*/\r
return xReturn;\r
}\r
\r
-#endif /* configUSE_TICKLESS_IDLE != 0 */\r
+#endif /* configUSE_TICKLESS_IDLE */\r
/*----------------------------------------------------------*/\r
\r
signed portBASE_TYPE xTaskResumeAll( void )\r
\r
return xAlreadyYielded;\r
}\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC TASK UTILITIES documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-\r
+/*-----------------------------------------------------------*/\r
\r
portTickType xTaskGetTickCount( void )\r
{\r
return &( pxTCB->pcTaskName[ 0 ] );\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_pcTaskGetTaskName */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
xTaskResumeAll();\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*----------------------------------------------------------*/\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
xTaskResumeAll();\r
}\r
\r
-#endif\r
+#endif /* configGENERATE_RUN_TIME_STATS */\r
/*----------------------------------------------------------*/\r
\r
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
return xIdleTaskHandle;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_xTaskGetIdleTaskHandle */\r
/*----------------------------------------------------------*/\r
\r
/* This conditional compilation should use inequality to 0, not equality to 1.\r
xTickCount += xTicksToJump;\r
}\r
\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
- * documented in task.h\r
- *----------------------------------------------------------*/\r
+#endif /* configUSE_TICKLESS_IDLE */\r
+/*----------------------------------------------------------*/\r
\r
void vTaskIncrementTick( void )\r
{\r
vApplicationTickHook();\r
}\r
}\r
- #endif\r
+ #endif /* configUSE_TICK_HOOK */\r
}\r
/*-----------------------------------------------------------*/\r
\r
taskEXIT_CRITICAL();\r
}\r
\r
-#endif\r
+#endif /* configUSE_APPLICATION_TASK_TAG */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
return xReturn;\r
}\r
\r
-#endif\r
+#endif /* configUSE_APPLICATION_TASK_TAG */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
return xReturn;\r
}\r
\r
-#endif\r
+#endif /* configUSE_APPLICATION_TASK_TAG */\r
/*-----------------------------------------------------------*/\r
\r
void vTaskSwitchContext( void )\r
pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
ulTaskSwitchedInTime = ulTotalRunTime;\r
}\r
- #endif\r
+ #endif /* configGENERATE_RUN_TIME_STATS */\r
\r
taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
}\r
- #else\r
+ #else /* INCLUDE_vTaskSuspend */\r
{\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
- #endif\r
+ #endif /* INCLUDE_vTaskSuspend */\r
}\r
/*-----------------------------------------------------------*/\r
\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask )\r
{\r
unsigned portBASE_TYPE uxReturn;\r
\r
return uxReturn;\r
}\r
-#endif\r
+\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )\r
{\r
tskTCB *pxTCB;\r
pxTCB->uxTaskNumber = uxHandle;\r
}\r
}\r
-#endif\r
\r
+#endif /* configUSE_TRACE_FACILITY */\r
\r
/*\r
* -----------------------------------------------------------\r
will automatically get the processor anyway. */\r
taskYIELD();\r
}\r
- #endif\r
+ #endif /* configUSE_PREEMPTION */\r
\r
#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )\r
{\r
taskYIELD();\r
}\r
}\r
- #endif\r
+ #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */\r
\r
#if ( configUSE_IDLE_HOOK == 1 )\r
{\r
CALL A FUNCTION THAT MIGHT BLOCK. */\r
vApplicationIdleHook();\r
}\r
- #endif\r
+ #endif /* configUSE_IDLE_HOOK */\r
\r
/* This conditional compilation should use inequality to 0, not equality\r
to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when\r
xTaskResumeAll();\r
}\r
}\r
- #endif\r
+ #endif /* configUSE_TICKLESS_IDLE */\r
}\r
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * File private functions documented at the top of the file.\r
- *----------------------------------------------------------*/\r
-\r
-\r
+/*-----------------------------------------------------------*/\r
\r
static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )\r
{\r
/* Don't bring strncpy into the build unnecessarily. */\r
strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );\r
}\r
- #endif\r
+ #endif /* configMAX_TASK_NAME_LEN */\r
pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';\r
\r
/* This is used as an array index so must ensure it's not too large. First\r
{\r
pxTCB->uxBasePriority = uxPriority;\r
}\r
- #endif\r
+ #endif /* configUSE_MUTEXES */\r
\r
vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
{\r
pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U;\r
}\r
- #endif\r
+ #endif /* portCRITICAL_NESTING_IN_TCB */\r
\r
#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
{\r
pxTCB->pxTaskTag = NULL;\r
}\r
- #endif\r
+ #endif /* configUSE_APPLICATION_TASK_TAG */\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
{\r
pxTCB->ulRunTimeCounter = 0UL;\r
}\r
- #endif\r
+ #endif /* configGENERATE_RUN_TIME_STATS */\r
\r
#if ( portUSING_MPU_WRAPPERS == 1 )\r
{\r
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );\r
}\r
- #else\r
+ #else /* portUSING_MPU_WRAPPERS */\r
{\r
( void ) xRegions;\r
( void ) usStackDepth;\r
}\r
- #endif\r
+ #endif /* portUSING_MPU_WRAPPERS */\r
}\r
/*-----------------------------------------------------------*/\r
\r
\r
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );\r
}\r
- /*-----------------------------------------------------------*/\r
-#endif\r
+ \r
+#endif /* portUSING_MPU_WRAPPERS */\r
+/*-----------------------------------------------------------*/\r
\r
static void prvInitialiseTaskLists( void )\r
{\r
{\r
vListInitialise( ( xList * ) &xTasksWaitingTermination );\r
}\r
- #endif\r
+ #endif /* INCLUDE_vTaskDelete */\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
{\r
vListInitialise( ( xList * ) &xSuspendedTaskList );\r
}\r
- #endif\r
+ #endif /* INCLUDE_vTaskSuspend */\r
\r
/* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList\r
using list2. */\r
}\r
}\r
}\r
- #endif\r
+ #endif /* vTaskDelete */\r
}\r
/*-----------------------------------------------------------*/\r
\r
} while( pxNextTCB != pxFirstTCB );\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
} while( pxNextTCB != pxFirstTCB );\r
}\r
\r
-#endif\r
+#endif /* configGENERATE_RUN_TIME_STATS */\r
/*-----------------------------------------------------------*/\r
\r
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
return usCount;\r
}\r
\r
-#endif\r
+#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
return uxReturn;\r
}\r
\r
-#endif\r
+#endif /* INCLUDE_uxTaskGetStackHighWaterMark */\r
/*-----------------------------------------------------------*/\r
\r
#if ( INCLUDE_vTaskDelete == 1 )\r
vPortFree( pxTCB );\r
}\r
\r
-#endif\r
-\r
-\r
+#endif /* INCLUDE_vTaskDelete */\r
/*-----------------------------------------------------------*/\r
\r
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )\r
return xReturn;\r
}\r
\r
-#endif\r
-\r
+#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */\r
/*-----------------------------------------------------------*/\r
\r
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
return xReturn;\r
}\r
\r
-#endif\r
+#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_MUTEXES == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* configUSE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_MUTEXES == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* configUSE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
}\r
}\r
\r
-#endif\r
+#endif /* portCRITICAL_NESTING_IN_TCB */\r
/*-----------------------------------------------------------*/\r
\r
#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
}\r
}\r
}\r
- }\r
+ } \r
\r
-#endif\r
+#endif /* portCRITICAL_NESTING_IN_TCB */\r
/*-----------------------------------------------------------*/\r
\r
\r