summaryrefslogtreecommitdiff
path: root/FreeRTOS
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-02-07 15:10:25 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-02-07 15:10:25 +0000
commit3a8eab2f341c6b06ccf9c06ddd56b86bd8ab0eff (patch)
treea082c50affa7fd301c92693a638b967411c74086 /FreeRTOS
parent87bdff7c6c8f2a3e02853f869ce0f718fcb62d23 (diff)
downloadfreertos-3a8eab2f341c6b06ccf9c06ddd56b86bd8ab0eff.tar.gz
Next revision of queue set implementation.
Make conditional compilation syntax and commenting consistent. Add common demo tasks to demonstrate queue sets. git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@1817 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'FreeRTOS')
-rw-r--r--FreeRTOS/Demo/Common/Minimal/QueueSet.c276
-rw-r--r--FreeRTOS/Demo/Common/Minimal/integer.c31
-rw-r--r--FreeRTOS/Demo/Common/include/QueueSet.h77
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h26
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/WIN32.suobin55296 -> 62464 bytes
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj1
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters3
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/main.c27
-rw-r--r--FreeRTOS/Source/include/FreeRTOS.h1
-rw-r--r--FreeRTOS/Source/include/queue.h153
-rw-r--r--FreeRTOS/Source/queue.c553
-rw-r--r--FreeRTOS/Source/tasks.c189
12 files changed, 974 insertions, 363 deletions
diff --git a/FreeRTOS/Demo/Common/Minimal/QueueSet.c b/FreeRTOS/Demo/Common/Minimal/QueueSet.c
new file mode 100644
index 000000000..ef06c9be0
--- /dev/null
+++ b/FreeRTOS/Demo/Common/Minimal/QueueSet.c
@@ -0,0 +1,276 @@
+/*
+ FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
+
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ ***************************************************************************
+ * *
+ * FreeRTOS tutorial books are available in pdf and paperback. *
+ * Complete, revised, and edited pdf reference manuals are also *
+ * available. *
+ * *
+ * Purchasing FreeRTOS documentation will not only help you, by *
+ * ensuring you get running as quickly as possible and with an *
+ * in-depth knowledge of how to use FreeRTOS, it will also help *
+ * the FreeRTOS project to continue with its mission of providing *
+ * professional grade, cross platform, de facto standard solutions *
+ * for microcontrollers - completely free of charge! *
+ * *
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
+ * *
+ * Thank you for using FreeRTOS, and thank you for your support! *
+ * *
+ ***************************************************************************
+
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+ >>>NOTE<<< The modification to the GPL is included to allow you to
+ distribute a combined work that includes FreeRTOS without being obliged to
+ provide the source code for proprietary components outside of the FreeRTOS
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License and the FreeRTOS license exception along with FreeRTOS; if not it
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained
+ by writing to Richard Barry, contact details for whom are available on the
+ FreeRTOS WEB site.
+
+ 1 tab == 4 spaces!
+
+ ***************************************************************************
+ * *
+ * Having a problem? Start by reading the FAQ "My application does *
+ * not run, what could be wrong?" *
+ * *
+ * http://www.FreeRTOS.org/FAQHelp.html *
+ * *
+ ***************************************************************************
+
+
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license
+ and contact details.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool.
+
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
+ the code with commercial support, indemnification, and middleware, under
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
+ provide a safety engineered and independently SIL3 certified version under
+ the SafeRTOS brand: http://www.SafeRTOS.com.
+*/
+
+/*
+ * Demonstrates the creation an use of queue sets.
+ *
+ * A receive task creates a number of queues and adds them to a queue set before
+ * blocking on a queue set receive. A transmit task repeatedly unblocks the
+ * receive task by sending messages to the queues in a pseudo random order.
+ * The receive task removes the messages from the queues and flags an error if
+ * the received message does not match that expected.
+ */
+
+/* Kernel includes. */
+#include <FreeRTOS.h>
+#include "task.h"
+#include "queue.h"
+
+/* Demo includes. */
+#include "QueueSet.h"
+
+/* The number of queues that are created and added to the queue set. */
+#define queuesetNUM_QUEUES_IN_SET 3
+
+/* The length of each created queue. */
+#define queuesetQUEUE_LENGTH 3
+
+/* Block times used in this demo. A block time or 0 means "don't block". */
+#define queuesetSHORT_DELAY 200
+#define queuesetDONT_BLOCK 0
+
+/*
+ * The task that periodically sends to the queue set.
+ */
+static void prvQueueSetSendingTask( void *pvParameters );
+
+/*
+ * The task that reads from the queue set.
+ */
+static void prvQueueSetReceivingTask( void *pvParameters );
+
+/* The queues that are added to the set. */
+static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
+
+/* The handle of the queue set to which the queues are added. */
+static xQueueSetHandle xQueueSet;
+
+/* If the prvQueueSetReceivingTask() task has not detected any errors then
+it increments ulCycleCounter on each iteration.
+xAreQueueSetTasksStillRunning() returns pdPASS if the value of
+ulCycleCounter has changed between consecutive calls, and pdFALSE if
+ulCycleCounter has stopped incrementing (indicating an error condition). */
+volatile unsigned long ulCycleCounter = 0UL;
+
+/* Set to pdFAIL if an error is detected by any queue set task.
+ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
+volatile portBASE_TYPE xQueueSetTasksStatus = pdPASS;
+
+
+/*-----------------------------------------------------------*/
+
+void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority )
+{
+xTaskHandle xQueueSetSendingTask;
+
+ /* Create the two queues. The handle of the sending task is passed into
+ the receiving task using the task parameter. The receiving task uses the
+ handle to resume the sending task after it has created the queues. */
+ xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xQueueSetSendingTask );
+ xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, uxPriority, NULL );
+
+ /* It is important that the sending task does not attempt to write to a
+ queue before the queue has been created. It is therefore placed into the
+ suspended state before the scheduler has started. It is resumed by the
+ receiving task after the receiving task has created the queues and added the
+ queues to the queue set. */
+ vTaskSuspend( xQueueSetSendingTask );
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xAreQueueSetTasksStillRunning( void )
+{
+static unsigned long ulLastCycleCounter;
+portBASE_TYPE xReturn;
+
+ if( ulLastCycleCounter == ulCycleCounter )
+ {
+ /* The cycle counter is no longer being incremented. Either one of the
+ tasks is stalled or an error has been detected. */
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueSetSendingTask( void *pvParameters )
+{
+unsigned long ulTxValue = 0;
+portBASE_TYPE xQueueToWriteTo;
+
+ /* Remove compiler warning about the unused parameter. */
+ ( void ) pvParameters;
+
+ srand( ( unsigned int ) &ulTxValue );
+
+ for( ;; )
+ {
+ /* Generate the index for the queue to which a value is to be sent. */
+ xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;
+ if( xQueueSendToBack( xQueues[ xQueueToWriteTo ], &ulTxValue, portMAX_DELAY ) != pdPASS )
+ {
+ /* The send should always pass as an infinite block time was
+ used. */
+ xQueueSetTasksStatus = pdFAIL;
+ }
+
+ ulTxValue++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueSetReceivingTask( void *pvParameters )
+{
+unsigned long ulReceived, ulLastReceived = ~0UL;
+xQueueHandle xActivatedQueue;
+portBASE_TYPE x;
+xTaskHandle xQueueSetSendingTask;
+
+ /* The handle to the sending task is passed in using the task parameter. */
+ xQueueSetSendingTask = ( xTaskHandle ) pvParameters;
+
+ /* Ensure the queues are created and the queue set configured before the
+ sending task is unsuspended.
+
+ First Create the queue set such that it will be able to hold a message for
+ every space in every queue in the set. */
+ xQueueSet = xQueueSetCreate( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH );
+
+ for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
+ {
+ /* Create the queue and add it to the set. */
+ xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );
+ configASSERT( xQueues[ x ] );
+ if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdPASS )
+ {
+ xQueueSetTasksStatus = pdFAIL;
+ }
+
+ /* The queue has now been added to the queue set and cannot be added to
+ another. */
+ if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdFAIL )
+ {
+ xQueueSetTasksStatus = pdFAIL;
+ }
+ }
+
+ /* The task that sends to the queues is not running yet, so attempting to
+ read from the queue set should fail, resulting in xActivatedQueue being set
+ to NULL. */
+ xActivatedQueue = xQueueReadMultiple( xQueueSet, queuesetSHORT_DELAY );
+ configASSERT( xActivatedQueue == NULL );
+
+ /* Resume the task that writes to the queues. */
+ vTaskResume( xQueueSetSendingTask );
+
+ for( ;; )
+ {
+ /* Wait for a message to arrive on one of the queues in the set. */
+ xActivatedQueue = xQueueReadMultiple( xQueueSet, portMAX_DELAY );
+ configASSERT( xActivatedQueue );
+
+ if( xActivatedQueue == NULL )
+ {
+ /* This should not happen as an infinite delay was used. */
+ xQueueSetTasksStatus = pdFAIL;
+ }
+ else
+ {
+ /* Reading from the queue should pass with a zero block time as
+ this task will only run when something has been posted to a task
+ in the queue set. */
+ if( xQueueReceive( xActivatedQueue, &ulReceived, queuesetDONT_BLOCK ) != pdPASS )
+ {
+ xQueueSetTasksStatus = pdFAIL;
+ }
+
+ /* It is always expected that the received value will be one
+ greater than the previously received value. */
+ configASSERT( ulReceived == ( ulLastReceived + 1 ) );
+ if( ulReceived != ( ulLastReceived + 1 ) )
+ {
+ xQueueSetTasksStatus = pdFAIL;
+ }
+ else
+ {
+ ulLastReceived = ulReceived;
+ }
+ }
+
+ if( xQueueSetTasksStatus == pdPASS )
+ {
+ ulCycleCounter++;
+ }
+ }
+}
+
diff --git a/FreeRTOS/Demo/Common/Minimal/integer.c b/FreeRTOS/Demo/Common/Minimal/integer.c
index 5d689c6ae..b441500a9 100644
--- a/FreeRTOS/Demo/Common/Minimal/integer.c
+++ b/FreeRTOS/Demo/Common/Minimal/integer.c
@@ -67,35 +67,12 @@
*/
/*
- * This version of integer. c is for use on systems that have limited stack
- * space and no display facilities. The complete version can be found in
- * the Demo/Common/Full directory.
- *
- * As with the full version, the tasks created in this file are a good test
- * of the scheduler context switch mechanism. The processor has to access
- * 32bit variables in two or four chunks (depending on the processor). The low
- * priority of these tasks means there is a high probability that a context
- * switch will occur mid calculation. See flop. c documentation for
- * more information.
- *
+ * Creates one or more tasks that repeatedly perform a set of integer
+ * calculations. The result of each run-time calculation is compared to the
+ * known expected result - with a mismatch being indicative of an error in the
+ * context switch mechanism.
*/
-/*
-Changes from V1.2.1
-
- + The constants used in the calculations are larger to ensure the
- optimiser does not truncate them to 16 bits.
-
-Changes from V1.2.3
-
- + uxTaskCheck is now just used as a boolean. Instead of incrementing
- the variable each cycle of the task, the variable is simply set to
- true. sAreIntegerMathsTaskStillRunning() sets it back to false and
- expects it to have been set back to true by the time it is called
- again.
- + A division has been included in the calculation.
-*/
-
#include <stdlib.h>
/* Scheduler include files. */
diff --git a/FreeRTOS/Demo/Common/include/QueueSet.h b/FreeRTOS/Demo/Common/include/QueueSet.h
new file mode 100644
index 000000000..107b7a8bc
--- /dev/null
+++ b/FreeRTOS/Demo/Common/include/QueueSet.h
@@ -0,0 +1,77 @@
+/*
+ FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
+
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ ***************************************************************************
+ * *
+ * FreeRTOS tutorial books are available in pdf and paperback. *
+ * Complete, revised, and edited pdf reference manuals are also *
+ * available. *
+ * *
+ * Purchasing FreeRTOS documentation will not only help you, by *
+ * ensuring you get running as quickly as possible and with an *
+ * in-depth knowledge of how to use FreeRTOS, it will also help *
+ * the FreeRTOS project to continue with its mission of providing *
+ * professional grade, cross platform, de facto standard solutions *
+ * for microcontrollers - completely free of charge! *
+ * *
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
+ * *
+ * Thank you for using FreeRTOS, and thank you for your support! *
+ * *
+ ***************************************************************************
+
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+ >>>NOTE<<< The modification to the GPL is included to allow you to
+ distribute a combined work that includes FreeRTOS without being obliged to
+ provide the source code for proprietary components outside of the FreeRTOS
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License and the FreeRTOS license exception along with FreeRTOS; if not it
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained
+ by writing to Richard Barry, contact details for whom are available on the
+ FreeRTOS WEB site.
+
+ 1 tab == 4 spaces!
+
+ ***************************************************************************
+ * *
+ * Having a problem? Start by reading the FAQ "My application does *
+ * not run, what could be wrong?" *
+ * *
+ * http://www.FreeRTOS.org/FAQHelp.html *
+ * *
+ ***************************************************************************
+
+
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license
+ and contact details.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool.
+
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
+ the code with commercial support, indemnification, and middleware, under
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
+ provide a safety engineered and independently SIL3 certified version under
+ the SafeRTOS brand: http://www.SafeRTOS.com.
+*/
+
+#ifndef QUEUE_WAIT_MULTIPLE_H
+#define QUEUE_WAIT_MULTIPLE_H
+
+void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority );
+portBASE_TYPE xAreQueueSetTasksStillRunning( void );
+
+#endif
+
+
diff --git a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
index deb4a3c36..0c548e3d5 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
@@ -100,6 +100,7 @@
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 1
+#define configUSE_QUEUE_SETS 1
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 2
@@ -117,19 +118,19 @@
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 0
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_uxTaskGetStackHighWaterMark 1
-#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 0
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
-#define INCLUDE_xTaskGetIdleTaskHandle 1
-#define INCLUDE_pcTaskGetTaskName 1
-#define INCLUDE_eTaskStateGet 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_pcTaskGetTaskName 1
+#define INCLUDE_eTaskGetState 1
extern void vAssertCalled( void );
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
@@ -139,6 +140,5 @@ version of the Win32 simulator projects. It will be ignored in the GCC
version. */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
-#define configUSE_QUEUE_SETS 1
#endif /* FREERTOS_CONFIG_H */
diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.suo b/FreeRTOS/Demo/WIN32-MSVC/WIN32.suo
index 1c3bbaa14..e48277fab 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.suo
+++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.suo
Binary files differ
diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
index 9944c4b78..87c8fb15d 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
+++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
@@ -137,6 +137,7 @@
<ClCompile Include="..\Common\Minimal\integer.c" />
<ClCompile Include="..\Common\Minimal\PollQ.c" />
<ClCompile Include="..\Common\Minimal\QPeek.c" />
+ <ClCompile Include="..\Common\Minimal\QueueSet.c" />
<ClCompile Include="..\Common\Minimal\semtest.c" />
<ClCompile Include="..\Common\Minimal\timerdemo.c" />
<ClCompile Include="DemosModifiedForLowTickRate\recmutex.c" />
diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
index e32e36837..bc0d07c7d 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
+++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
@@ -94,6 +94,9 @@
<ClCompile Include="..\Common\Minimal\dynamic.c">
<Filter>Demo App Source\Common Demo Tasks</Filter>
</ClCompile>
+ <ClCompile Include="..\Common\Minimal\QueueSet.c">
+ <Filter>Demo App Source\Common Demo Tasks</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FreeRTOSConfig.h">
diff --git a/FreeRTOS/Demo/WIN32-MSVC/main.c b/FreeRTOS/Demo/WIN32-MSVC/main.c
index 85b09edfb..fa0eadbda 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/main.c
+++ b/FreeRTOS/Demo/WIN32-MSVC/main.c
@@ -117,18 +117,20 @@
#include "countsem.h"
#include "death.h"
#include "dynamic.h"
+#include "QueueSet.h"
/* Priorities at which the tasks are created. */
-#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
-#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
-#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
-#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
-#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
-#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
-#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
-#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
+#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
+#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
+#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
+#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
+#define mainQUEUE_SET_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainTIMER_TEST_PERIOD ( 50 )
@@ -165,6 +167,7 @@ int main( void )
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks();
+ vStartQueueSetTasks( mainQUEUE_SET_TASK_PRIORITY );
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation. This then allows them to
@@ -250,6 +253,10 @@ const portTickType xCycleFrequency = 1000 / portTICK_RATE_MS;
{
pcStatusMessage = "Error: Dynamic\r\n";
}
+ else if( xAreQueueSetTasksStillRunning() != pdPASS )
+ {
+ pcStatusMessage = "Error: Queue set\r\n";
+ }
/* This is the only task that uses stdout so its ok to call printf()
directly. */
diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h
index 93a8e1499..a84be03c0 100644
--- a/FreeRTOS/Source/include/FreeRTOS.h
+++ b/FreeRTOS/Source/include/FreeRTOS.h
@@ -560,7 +560,6 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
/* For backward compatability. */
#define eTaskStateGet eTaskGetState
-#define INCLUDE_eTaskStateGet INCLUDE_eTaskGetState
#endif /* INC_FREERTOS_H */
diff --git a/FreeRTOS/Source/include/queue.h b/FreeRTOS/Source/include/queue.h
index 40562cfc0..b9452662c 100644
--- a/FreeRTOS/Source/include/queue.h
+++ b/FreeRTOS/Source/include/queue.h
@@ -1,7 +1,7 @@
/*
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
- FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
@@ -42,7 +42,7 @@
FreeRTOS WEB site.
1 tab == 4 spaces!
-
+
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
@@ -52,17 +52,17 @@
* *
***************************************************************************
-
- http://www.FreeRTOS.org - Documentation, training, latest versions, license
- and contact details.
-
+
+ http://www.FreeRTOS.org - Documentation, training, latest versions, license
+ and contact details.
+
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
- the code with commercial support, indemnification, and middleware, under
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
+ the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
- provide a safety engineered and independently SIL3 certified version under
+ provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
@@ -82,12 +82,18 @@ extern "C" {
#include "mpu_wrappers.h"
/**
- * Type by which queues are referenced. For example, a call to xQueueCreate
- * returns (via a pointer parameter) an xQueueHandle variable that can then
- * be used as a parameter to xQueueSend(), xQueueReceive(), etc.
+ * Type by which queues are referenced. For example, a call to xQueueCreate()
+ * returns an xQueueHandle variable that can then be used as a parameter to
+ * xQueueSend(), xQueueReceive(), etc.
*/
typedef void * xQueueHandle;
+/**
+ * Type by which queue sets are referenced. For example, a call to
+ * xQueueSetCreate() returns an xQueueSet variable that can then be used as a
+ * parameter to xQueueReadMultiple(), xQueueAddToQueueSet(), etc.
+ */
+typedef void * xQueueSetHandle;
/* For internal use only. */
#define queueSEND_TO_BACK ( 0 )
@@ -1236,8 +1242,8 @@ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQue
signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
/*
- * For internal use only. Use xSemaphoreCreateMutex(),
- * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
+ * For internal use only. Use xSemaphoreCreateMutex(),
+ * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
* these functions directly.
*/
xQueueHandle xQueueCreateMutex( unsigned char ucQueueType );
@@ -1284,11 +1290,128 @@ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );
#endif
/*
- * Generic version of the queue creation function, which is in turn called by
+ * Generic version of the queue creation function, which is in turn called by
* any queue, semaphore or mutex creation function or macro.
*/
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );
+/*
+ * Queue sets provide a mechanism to allow a task to block (pend) on a read
+ * operation from multiple queues or semaphores simultaneously.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * A queue set must be explicitly created using a call to xQueueSetCreate()
+ * before it can be used. Once created, standard FreeRTOS queues and semaphores
+ * can be added to the set using calls to xQueueAddToQueueSet().
+ * xQueueReadMultiple() is then used to determine which, if any, of the queues
+ * or semaphores contained in the set is in a state where a queue read or
+ * semaphore take operation would be successful.
+ *
+ * Note 1: See the documentation on http://wwwFreeRTOS.org for reasons why
+ * queue sets are very rarely needed in practice as there are simpler
+ * alternatives. Queue sets are provided to allow FreeRTOS to be integrated
+ * with legacy third party driver code.
+ *
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the
+ * mutex holder to inherit the priority of the blocked task.
+ *
+ * Note 3: An additional 4 bytes of RAM is required for each space in a every
+ * queue added to a queue set. Therefore counting semaphores with large maximum
+ * counts should not be added to queue sets.
+ *
+ * @param uxEventQueueLength Queue sets themselves queue events that occur on
+ * the queues and semaphores contained in the set. uxEventQueueLength specifies
+ * the maximum number of events that can be queued at once. To be absolutely
+ * certain that events are not lost uxEventQueueLength should be set to the
+ * total sum of the length of the queues added to the set, where binary
+ * semaphores and mutexes have a length of 1, and counting semaphores have a
+ * length set by their maximum count value. Examples:
+ * + If a queue set is to hold a queue of length 5, another queue of length 12,
+ * and a binary semaphore, then uxEventQueueLength should be set to
+ * (5 + 12 + 1), or 18.
+ * + If a queue set is to hold three binary semaphores then uxEventQueueLength
+ * should be set to (1 + 1 + 1 ), or 3.
+ * + If a queue set is to hold a counting semaphore that has a maximum count of
+ * 5, and a counting semaphore that has a maximum count of 3, then
+ * uxEventQueueLength should be set to (5 + 3), or 8.
+ *
+ * @return If the queue set is created successfully then a handle to the created
+ * queue set is returned. Otherwise NULL is returned.
+ */
+xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
+
+/*
+ * Adds a queue or semaphore to a queue set that was previously created by a
+ * call to xQueueSetCreate().
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * @param xQueue The handle of the queue or semaphore being added to the
+ * queue set. Variables of type xSemaphoreHandle can be safely added to a
+ * queue set but may require casting to an xQueueHandle type to avoid compiler
+ * warnings.
+ *
+ * @param xQueueSet The handle of the queue set to which the queue or semaphore
+ * is being added.
+ *
+ * @return If the queue or semaphore was successfully added to the queue set
+ * then pdPASS is returned. If the queue could not be successfully added to the
+ * queue set because it is already a member of a different queue set then pdFAIL
+ * is returned.
+ */
+portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet );
+
+/*
+ * Removes a queue or semaphore from a queue set.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * @param xQueue The handle of the queue or semaphore being removed from the
+ * queue set. Variables of type xSemaphoreHandle can be safely used but may
+ * require casting to an xQueueHandle type to avoid compiler warnings.
+ *
+ * @param xQueueSet The handle of the queue set in which the queue or semaphore
+ * is included.
+ *
+ * @return If the queue or semaphore was successfully removed from the queue set
+ * then pdPASS is returned. If the queue was not in the queue set then pdFAIL
+ * is returned.
+ */
+portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue );
+
+/*
+ * xQueueReadMultiple() allows a task to block (pend) on a read operation on
+ * all the queues and semaphores in a queue set simultaneously.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * Note 1: See the documentation on http://wwwFreeRTOS.org for reasons why
+ * queue sets are very rarely needed in practice as there are simpler
+ * alternatives. Queue sets are provided to allow FreeRTOS to be integrated
+ * with legacy third party driver code.
+ *
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the
+ * mutex holder to inherit the priority of the blocked task.
+ *
+ * @param xQueueSet The queue set on which the task will (potentially) block.
+ *
+ * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will
+ * remain in the Blocked state (with other tasks executing) to wait for a member
+ * of the queue set to be ready for a successful queue read or semaphore take
+ * operation.
+ *
+ * @return xQueueReadMultiple() will return the handle of a queue contained
+ * in the queue set that contains data, or the handle of a semaphore contained
+ * in the queue set that is available, or NULL if no such queue or semaphore
+ * exists before before the specified block time expires.
+ */
+xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
+
/* Not public API functions. */
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );
diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c
index c4e371229..db21c3c07 100644
--- a/FreeRTOS/Source/queue.c
+++ b/FreeRTOS/Source/queue.c
@@ -83,10 +83,6 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
-/*-----------------------------------------------------------
- * PUBLIC LIST API documented in list.h
- *----------------------------------------------------------*/
-
/* Constants used with the cRxLock and xTxLock structure members. */
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
@@ -115,6 +111,7 @@ zero. */
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )
+#define queueQUEUE_TYPE_SET ( 5U )
/*
* Definition of the queue used by the scheduler.
@@ -122,11 +119,11 @@ zero. */
*/
typedef struct QueueDefinition
{
- signed char *pcHead; /*< Points to the beginning of the queue storage area. */
- signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
+ signed char *pcHead; /*< Points to the beginning of the queue storage area. */
+ signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
- signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
- signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
+ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
+ signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
@@ -143,6 +140,10 @@ typedef struct QueueDefinition
unsigned char ucQueueType;
#endif
+ #if ( configUSE_QUEUE_SETS == 1 )
+ struct QueueDefinition *pxQueueSetContainer;
+ #endif
+
} xQUEUE;
/*-----------------------------------------------------------*/
@@ -152,11 +153,14 @@ typedef struct QueueDefinition
* pointer to void.
*/
typedef xQUEUE * xQueueHandle;
+typedef xQUEUE * xQueueSetHandle;
/*
- * Prototypes for public functions are included here so we don't have to
- * include the API header file (as it defines xQueueHandle differently). These
- * functions are documented in the API header file.
+ * In order to implement strict data hiding, the queue.h header file defines
+ * xQueueHandle and xQueueSetHandle as pointers to void. In this file
+ * xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.
+ * Therefore the queue.h header file cannot be included in this source file,
+ * and the function prototypes are provided directly.
*/
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
@@ -180,12 +184,16 @@ void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) P
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
+xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
+xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
/*
* Co-routine queue functions differ from task queue functions. Co-routines are
* an optional component.
*/
-#if configUSE_CO_ROUTINES == 1
+#if ( configUSE_CO_ROUTINES == 1 )
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
@@ -196,7 +204,7 @@ xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
* The queue registry is just a means for kernel aware debuggers to locate
* queue structures. It has no other purpose so is an optional component.
*/
-#if configQUEUE_REGISTRY_SIZE > 0
+#if ( configQUEUE_REGISTRY_SIZE > 0 )
/* The type stored within the queue registry array. This allows a name
to be assigned to each queue making kernel aware debugging a little
@@ -252,6 +260,15 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
* Copies an item out of a queue.
*/
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
+
+#if ( configUSE_QUEUE_SETS == 1 )
+ /*
+ * Checks to see if a queue is a member of a queue set, and if so, notifies
+ * the queue set that the queue contains data.
+ */
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );
+#endif
+
/*-----------------------------------------------------------*/
/*
@@ -273,11 +290,6 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
taskEXIT_CRITICAL()
/*-----------------------------------------------------------*/
-
-/*-----------------------------------------------------------
- * PUBLIC QUEUE MANAGEMENT API documented in queue.h
- *----------------------------------------------------------*/
-
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )
{
configASSERT( pxQueue );
@@ -349,12 +361,19 @@ xQueueHandle xReturn = NULL;
pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize;
xQueueGenericReset( pxNewQueue, pdTRUE );
+
#if ( configUSE_TRACE_FACILITY == 1 )
{
pxNewQueue->ucQueueType = ucQueueType;
}
#endif /* configUSE_TRACE_FACILITY */
+ #if( configUSE_QUEUE_SETS == 1 )
+ {
+ pxNewQueue->pxQueueSetContainer = NULL;
+ }
+ #endif /* configUSE_QUEUE_SETS */
+
traceQUEUE_CREATE( pxNewQueue );
xReturn = pxNewQueue;
}
@@ -410,6 +429,12 @@ xQueueHandle xReturn = NULL;
}
#endif
+ #if ( configUSE_QUEUE_SETS == 1 )
+ {
+ pxNewQueue->pxQueueSetContainer = NULL;
+ }
+ #endif
+
/* Ensure the event queues start with the correct state. */
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
@@ -431,7 +456,7 @@ xQueueHandle xReturn = NULL;
#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
-#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xQueueGetMutexHolder == 1 ) )
+#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
void* xQueueGetMutexHolder( xQueueHandle xSemaphore )
{
@@ -510,7 +535,7 @@ xQueueHandle xReturn = NULL;
#endif /* configUSE_RECURSIVE_MUTEXES */
/*-----------------------------------------------------------*/
-#if configUSE_RECURSIVE_MUTEXES == 1
+#if ( configUSE_RECURSIVE_MUTEXES == 1 )
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )
{
@@ -550,7 +575,7 @@ xQueueHandle xReturn = NULL;
#endif /* configUSE_RECURSIVE_MUTEXES */
/*-----------------------------------------------------------*/
-#if configUSE_COUNTING_SEMAPHORES == 1
+#if ( configUSE_COUNTING_SEMAPHORES == 1 )
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
{
@@ -611,6 +636,20 @@ xTimeOutType xTimeOut;
portYIELD_WITHIN_API();
}
}
+ else
+ {
+ #if ( configUSE_QUEUE_SETS == 1 )
+ {
+ if( prvCheckForMembershipOfQueueSet( pxQueue, xCopyPosition ) == pdTRUE )
+ {
+ /* The queue is a member of a queue set, and posting to
+ the queue set caused a higher priority task to unblock.
+ A context switch is required. */
+ portYIELD_WITHIN_API();
+ }
+ }
+ #endif /* configUSE_QUEUE_SETS */
+ }
taskEXIT_CRITICAL();
@@ -695,7 +734,7 @@ xTimeOutType xTimeOut;
}
/*-----------------------------------------------------------*/
-#if configUSE_ALTERNATIVE_API == 1
+#if ( configUSE_ALTERNATIVE_API == 1 )
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{
@@ -772,7 +811,7 @@ xTimeOutType xTimeOut;
#endif /* configUSE_ALTERNATIVE_API */
/*-----------------------------------------------------------*/
-#if configUSE_ALTERNATIVE_API == 1
+#if ( configUSE_ALTERNATIVE_API == 1 )
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
{
@@ -940,6 +979,17 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
}
}
}
+ else
+ {
+ #if ( configUSE_QUEUE_SETS == 1 )
+ {
+ if( pxQueue->pxQueueSetContainer != NULL )
+ {
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK );
+ }
+ }
+ #endif /* configUSE_QUEUE_SETS */
+ }
}
else
{
@@ -1018,7 +1068,7 @@ signed char *pcOriginalReadPosition;
{
traceQUEUE_PEEK( pxQueue );
- /* We are not removing the data, so reset our read
+ /* The data is not being removed, so reset the read
pointer. */
pxQueue->pcReadFrom = pcOriginalReadPosition;
@@ -1034,6 +1084,17 @@ signed char *pcOriginalReadPosition;
portYIELD_WITHIN_API();
}
}
+ else
+ {
+ #if ( configUSE_QUEUE_SETS == 1 )
+ {
+ if( pxQueue->pxQueueSetContainer != NULL )
+ {
+ xQueueGenericSend( pxQueue->pxQueueSetContainer, &pxQueue, 0, queueSEND_TO_BACK );
+ }
+ }
+ #endif /* configUSE_QUEUE_SETS */
+ }
}
taskEXIT_CRITICAL();
@@ -1212,7 +1273,7 @@ void vQueueDelete( xQueueHandle pxQueue )
return pxQueue->ucQueueNumber;
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
@@ -1222,7 +1283,7 @@ void vQueueDelete( xQueueHandle pxQueue )
pxQueue->ucQueueNumber = ucQueueNumber;
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
@@ -1232,7 +1293,7 @@ void vQueueDelete( xQueueHandle pxQueue )
return pxQueue->ucQueueType;
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
@@ -1312,6 +1373,22 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
context switch is required. */
vTaskMissedYield();
}
+ else
+ {
+ #if ( configUSE_QUEUE_SETS == 1 )
+ {
+ if( pxQueue->pxQueueSetContainer != NULL )
+ {
+ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, &xHigherPriorityTaskWoken, queueSEND_TO_BACK );
+ if( xHigherPriorityTaskWoken != pdFALSE )
+ {
+ vTaskMissedYield();
+ }
+ }
+ }
+ #endif /* configUSE_QUEUE_SETS */
+ }
--( pxQueue->xTxLock );
}
@@ -1397,219 +1474,225 @@ signed portBASE_TYPE xReturn;
}
/*-----------------------------------------------------------*/
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
-{
-signed portBASE_TYPE xReturn;
+#if ( configUSE_CO_ROUTINES == 1 )
- /* If the queue is already full we may have to block. A critical section
- is required to prevent an interrupt removing something from the queue
- between the check to see if the queue is full and blocking on the queue. */
- portDISABLE_INTERRUPTS();
+ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
{
- if( prvIsQueueFull( pxQueue ) != pdFALSE )
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already full we may have to block. A critical section
+ is required to prevent an interrupt removing something from the queue
+ between the check to see if the queue is full and blocking on the queue. */
+ portDISABLE_INTERRUPTS();
{
- /* The queue is full - do we want to block or just leave without
- posting? */
- if( xTicksToWait > ( portTickType ) 0 )
- {
- /* As this is called from a coroutine we cannot block directly, but
- return indicating that we need to block. */
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
- portENABLE_INTERRUPTS();
- return errQUEUE_BLOCKED;
- }
- else
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )
{
- portENABLE_INTERRUPTS();
- return errQUEUE_FULL;
+ /* The queue is full - do we want to block or just leave without
+ posting? */
+ if( xTicksToWait > ( portTickType ) 0 )
+ {
+ /* As this is called from a coroutine we cannot block directly, but
+ return indicating that we need to block. */
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
+ portENABLE_INTERRUPTS();
+ return errQUEUE_BLOCKED;
+ }
+ else
+ {
+ portENABLE_INTERRUPTS();
+ return errQUEUE_FULL;
+ }
}
}
- }
- portENABLE_INTERRUPTS();
+ portENABLE_INTERRUPTS();
- portNOP();
+ portNOP();
- portDISABLE_INTERRUPTS();
- {
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+ portDISABLE_INTERRUPTS();
{
- /* There is room in the queue, copy the data into the queue. */
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
- xReturn = pdPASS;
-
- /* Were any co-routines waiting for data to become available? */
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
- /* In this instance the co-routine could be placed directly
- into the ready list as we are within a critical section.
- Instead the same pending ready list mechanism is used as if
- the event were caused from within an interrupt. */
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ /* There is room in the queue, copy the data into the queue. */
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
+ xReturn = pdPASS;
+
+ /* Were any co-routines waiting for data to become available? */
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
- /* The co-routine waiting has a higher priority so record
- that a yield might be appropriate. */
- xReturn = errQUEUE_YIELD;
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechanism is used as if
+ the event were caused from within an interrupt. */
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ {
+ /* The co-routine waiting has a higher priority so record
+ that a yield might be appropriate. */
+ xReturn = errQUEUE_YIELD;
+ }
}
}
+ else
+ {
+ xReturn = errQUEUE_FULL;
+ }
}
- else
- {
- xReturn = errQUEUE_FULL;
- }
+ portENABLE_INTERRUPTS();
+
+ return xReturn;
}
- portENABLE_INTERRUPTS();
- return xReturn;
-}
-#endif
+#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
-{
-signed portBASE_TYPE xReturn;
+#if ( configUSE_CO_ROUTINES == 1 )
- /* If the queue is already empty we may have to block. A critical section
- is required to prevent an interrupt adding something to the queue
- between the check to see if the queue is empty and blocking on the queue. */
- portDISABLE_INTERRUPTS();
+ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
{
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already empty we may have to block. A critical section
+ is required to prevent an interrupt adding something to the queue
+ between the check to see if the queue is empty and blocking on the queue. */
+ portDISABLE_INTERRUPTS();
{
- /* There are no messages in the queue, do we want to block or just
- leave with nothing? */
- if( xTicksToWait > ( portTickType ) 0 )
+ if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{
- /* As this is a co-routine we cannot block directly, but return
- indicating that we need to block. */
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
- portENABLE_INTERRUPTS();
- return errQUEUE_BLOCKED;
- }
- else
- {
- portENABLE_INTERRUPTS();
- return errQUEUE_FULL;
+ /* There are no messages in the queue, do we want to block or just
+ leave with nothing? */
+ if( xTicksToWait > ( portTickType ) 0 )
+ {
+ /* As this is a co-routine we cannot block directly, but return
+ indicating that we need to block. */
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
+ portENABLE_INTERRUPTS();
+ return errQUEUE_BLOCKED;
+ }
+ else
+ {
+ portENABLE_INTERRUPTS();
+ return errQUEUE_FULL;
+ }
}
}
- }
- portENABLE_INTERRUPTS();
+ portENABLE_INTERRUPTS();
- portNOP();
+ portNOP();
- portDISABLE_INTERRUPTS();
- {
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+ portDISABLE_INTERRUPTS();
{
- /* Data is available from the queue. */
- pxQueue->pcReadFrom += pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
- pxQueue->pcReadFrom = pxQueue->pcHead;
- }
- --( pxQueue->uxMessagesWaiting );
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+ /* Data is available from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )
+ {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --( pxQueue->uxMessagesWaiting );
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
- xReturn = pdPASS;
+ xReturn = pdPASS;
- /* Were any co-routines waiting for space to become available? */
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
- {
- /* In this instance the co-routine could be placed directly
- into the ready list as we are within a critical section.
- Instead the same pending ready list mechanism is used as if
- the event were caused from within an interrupt. */
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+ /* Were any co-routines waiting for space to become available? */
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
- xReturn = errQUEUE_YIELD;
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechanism is used as if
+ the event were caused from within an interrupt. */
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+ {
+ xReturn = errQUEUE_YIELD;
+ }
}
}
+ else
+ {
+ xReturn = pdFAIL;
+ }
}
- else
- {
- xReturn = pdFAIL;
- }
+ portENABLE_INTERRUPTS();
+
+ return xReturn;
}
- portENABLE_INTERRUPTS();
- return xReturn;
-}
-#endif
+#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
+#if ( configUSE_CO_ROUTINES == 1 )
-
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
-{
- /* Cannot block within an ISR so if there is no space on the queue then
- exit without doing anything. */
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
+ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
{
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
-
- /* We only want to wake one co-routine per ISR, so check that a
- co-routine has not already been woken. */
- if( xCoRoutinePreviouslyWoken == pdFALSE )
+ /* Cannot block within an ISR so if there is no space on the queue then
+ exit without doing anything. */
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
+
+ /* We only want to wake one co-routine per ISR, so check that a
+ co-routine has not already been woken. */
+ if( xCoRoutinePreviouslyWoken == pdFALSE )
{
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
- return pdTRUE;
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ {
+ return pdTRUE;
+ }
}
}
}
+
+ return xCoRoutinePreviouslyWoken;
}
- return xCoRoutinePreviouslyWoken;
-}
-#endif
+#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
-{
-signed portBASE_TYPE xReturn;
+#if ( configUSE_CO_ROUTINES == 1 )
- /* We cannot block from an ISR, so check there is data available. If
- not then just leave without doing anything. */
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
+ signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
{
- /* Copy the data from the queue. */
- pxQueue->pcReadFrom += pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )
- {
- pxQueue->pcReadFrom = pxQueue->pcHead;
- }
- --( pxQueue->uxMessagesWaiting );
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+ signed portBASE_TYPE xReturn;
- if( ( *pxCoRoutineWoken ) == pdFALSE )
+ /* We cannot block from an ISR, so check there is data available. If
+ not then just leave without doing anything. */
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
+ /* Copy the data from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )
{
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --( pxQueue->uxMessagesWaiting );
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
+
+ if( ( *pxCoRoutineWoken ) == pdFALSE )
+ {
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
- *pxCoRoutineWoken = pdTRUE;
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+ {
+ *pxCoRoutineWoken = pdTRUE;
+ }
}
}
+
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
}
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
+ return xReturn;
}
- return xReturn;
-}
-#endif
+#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
-#if configQUEUE_REGISTRY_SIZE > 0
+#if ( configQUEUE_REGISTRY_SIZE > 0 )
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
{
@@ -1629,10 +1712,10 @@ signed portBASE_TYPE xReturn;
}
}
-#endif
+#endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/
-#if configQUEUE_REGISTRY_SIZE > 0
+#if ( configQUEUE_REGISTRY_SIZE > 0 )
static void vQueueUnregisterQueue( xQueueHandle xQueue )
{
@@ -1652,10 +1735,10 @@ signed portBASE_TYPE xReturn;
}
-#endif
+#endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/
-#if configUSE_TIMERS == 1
+#if ( configUSE_TIMERS == 1 )
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )
{
@@ -1682,5 +1765,113 @@ signed portBASE_TYPE xReturn;
prvUnlockQueue( pxQueue );
}
-#endif
+#endif /* configUSE_TIMERS */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_QUEUE_SETS == 1 )
+
+ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )
+ {
+ xQUEUE *pxQueue;
+
+ pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET );
+
+ return ( xQueueSetHandle ) pxQueue;
+ }
+
+#endif /* configUSE_QUEUE_SETS */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_QUEUE_SETS == 1 )
+
+ portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet )
+ {
+ portBASE_TYPE xReturn;
+
+ if( xQueue->pxQueueSetContainer != NULL )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ taskENTER_CRITICAL();
+ {
+ xQueue->pxQueueSetContainer = xQueueSet;
+ }
+ taskEXIT_CRITICAL();
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+ }
+
+#endif /* configUSE_QUEUE_SETS */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_QUEUE_SETS == 1 )
+
+ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue )
+ {
+ portBASE_TYPE xReturn;
+
+ if( xQueue->pxQueueSetContainer != xQueueSet )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ taskENTER_CRITICAL();
+ {
+ xQueue->pxQueueSetContainer = NULL;
+ }
+ taskEXIT_CRITICAL();
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+ }
+
+#endif /* configUSE_QUEUE_SETS */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_QUEUE_SETS == 1 )
+
+ xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
+ {
+ xQueueHandle xReturn = NULL;
+
+ xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );
+ return xReturn;
+ }
+
+#endif /* configUSE_QUEUE_SETS */
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_QUEUE_SETS == 1 )
+
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
+ {
+ xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
+ portBASE_TYPE xReturn = pdFALSE;
+
+ if( pxQueueSetContainer != NULL )
+ {
+ if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
+ {
+ prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
+ if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
+ {
+ if( xTaskRemoveFromEventList( &( pxQueue->pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
+ {
+ /* The task waiting has a higher priority */
+ xReturn = pdTRUE;
+ }
+ }
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* configUSE_QUEUE_SETS */
diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c
index ab95fbd68..6284a56ff 100644
--- a/FreeRTOS/Source/tasks.c
+++ b/FreeRTOS/Source/tasks.c
@@ -214,7 +214,7 @@ PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTic
/*-----------------------------------------------------------*/
-#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 0
+#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
performed in a generic way that is not optimised to any particular
@@ -478,12 +478,6 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
/*lint +e956 */
-
-
-/*-----------------------------------------------------------
- * TASK CREATION API documented in task.h
- *----------------------------------------------------------*/
-
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )
{
signed portBASE_TYPE xReturn;
@@ -526,7 +520,7 @@ tskTCB * pxNewTCB;
/* Check the alignment of the calculated top of stack is correct. */
configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
}
- #else
+ #else /* portSTACK_GROWTH */
{
pxTopOfStack = pxNewTCB->pxStack;
@@ -538,7 +532,7 @@ tskTCB * pxNewTCB;
other extreme of the stack space. */
pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
}
- #endif
+ #endif /* portSTACK_GROWTH */
/* Setup the newly allocated TCB with the initial state of the task. */
prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
@@ -551,11 +545,11 @@ tskTCB * pxNewTCB;
{
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
}
- #else
+ #else /* portUSING_MPU_WRAPPERS */
{
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
}
- #endif
+ #endif /* portUSING_MPU_WRAPPERS */
/* Check the alignment of the initialised stack. */
portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
@@ -613,7 +607,7 @@ tskTCB * pxNewTCB;
/* Add a counter into the TCB for tracing only. */
pxNewTCB->uxTCBNumber = uxTaskNumber;
}
- #endif
+ #endif /* configUSE_TRACE_FACILITY */
uxTaskNumber++;
traceTASK_CREATE( pxNewTCB );
@@ -705,16 +699,8 @@ tskTCB * pxNewTCB;
}
}
-#endif
-
-
-
-
-
-
-/*-----------------------------------------------------------
- * TASK CONTROL API documented in task.h
- *----------------------------------------------------------*/
+#endif /* INCLUDE_vTaskDelete */
+/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelayUntil == 1 )
@@ -785,7 +771,7 @@ tskTCB * pxNewTCB;
}
}
-#endif
+#endif /* INCLUDE_vTaskDelayUntil */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelay == 1 )
@@ -837,7 +823,7 @@ tskTCB * pxNewTCB;
}
}
-#endif
+#endif /* INCLUDE_vTaskDelay */
/*-----------------------------------------------------------*/
#if ( INCLUDE_eTaskGetState == 1 )
@@ -899,7 +885,7 @@ tskTCB * pxNewTCB;
return eReturn;
}
-#endif
+#endif /* INCLUDE_eTaskGetState */
/*-----------------------------------------------------------*/
#if ( INCLUDE_uxTaskPriorityGet == 1 )
@@ -921,7 +907,7 @@ tskTCB * pxNewTCB;
return uxReturn;
}
-#endif
+#endif /* INCLUDE_uxTaskPriorityGet */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskPrioritySet == 1 )
@@ -1039,7 +1025,7 @@ tskTCB * pxNewTCB;
( void ) uxPriorityUsedOnEntry;
}
-#endif
+#endif /* INCLUDE_vTaskPrioritySet */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskSuspend == 1 )
@@ -1106,7 +1092,7 @@ tskTCB * pxNewTCB;
}
}
-#endif
+#endif /* INCLUDE_vTaskSuspend */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskSuspend == 1 )
@@ -1140,7 +1126,7 @@ tskTCB * pxNewTCB;
return xReturn;
}
-#endif
+#endif /* INCLUDE_vTaskSuspend */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskSuspend == 1 )
@@ -1184,7 +1170,7 @@ tskTCB * pxNewTCB;
}
}
-#endif
+#endif /* INCLUDE_vTaskSuspend */
/*-----------------------------------------------------------*/
@@ -1226,15 +1212,8 @@ tskTCB * pxNewTCB;
return xYieldRequired;
}
-#endif
-
-
-
-
-/*-----------------------------------------------------------
- * PUBLIC SCHEDULER CONTROL documented in task.h
- *----------------------------------------------------------*/
-
+#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */
+/*-----------------------------------------------------------*/
void vTaskStartScheduler( void )
{
@@ -1252,7 +1231,7 @@ portBASE_TYPE xReturn;
/* Create the idle task without storing its handle. */
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );
}
- #endif
+ #endif /* INCLUDE_xTaskGetIdleTaskHandle */
#if ( configUSE_TIMERS == 1 )
{
@@ -1261,7 +1240,7 @@ portBASE_TYPE xReturn;
xReturn = xTimerCreateTimerTask();
}
}
- #endif
+ #endif /* configUSE_TIMERS */
if( xReturn == pdPASS )
{
@@ -1296,7 +1275,9 @@ portBASE_TYPE xReturn;
}
}
- /* This line will only be reached if the kernel could not be started. */
+ /* This line will only be reached if the kernel could not be started, or
+ vTaskEndScheduler() was called (vTaskEndScheduler() is not implemented for
+ most ports). */
configASSERT( xReturn );
}
/*-----------------------------------------------------------*/
@@ -1345,7 +1326,7 @@ void vTaskSuspendAll( void )
return xReturn;
}
-#endif /* configUSE_TICKLESS_IDLE != 0 */
+#endif /* configUSE_TICKLESS_IDLE */
/*----------------------------------------------------------*/
signed portBASE_TYPE xTaskResumeAll( void )
@@ -1423,17 +1404,7 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
return xAlreadyYielded;
}
-
-
-
-
-
-
-/*-----------------------------------------------------------
- * PUBLIC TASK UTILITIES documented in task.h
- *----------------------------------------------------------*/
-
-
+/*-----------------------------------------------------------*/
portTickType xTaskGetTickCount( void )
{
@@ -1483,7 +1454,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
return &( pxTCB->pcTaskName[ 0 ] );
}
-#endif
+#endif /* INCLUDE_pcTaskGetTaskName */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
@@ -1546,7 +1517,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
xTaskResumeAll();
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*----------------------------------------------------------*/
#if ( configGENERATE_RUN_TIME_STATS == 1 )
@@ -1621,7 +1592,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
xTaskResumeAll();
}
-#endif
+#endif /* configGENERATE_RUN_TIME_STATS */
/*----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
@@ -1634,7 +1605,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
return xIdleTaskHandle;
}
-#endif
+#endif /* INCLUDE_xTaskGetIdleTaskHandle */
/*----------------------------------------------------------*/
/* This conditional compilation should use inequality to 0, not equality to 1.
@@ -1649,12 +1620,8 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
xTickCount += xTicksToJump;
}
-#endif
-
-/*-----------------------------------------------------------
- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
- * documented in task.h
- *----------------------------------------------------------*/
+#endif /* configUSE_TICKLESS_IDLE */
+/*----------------------------------------------------------*/
void vTaskIncrementTick( void )
{
@@ -1726,7 +1693,7 @@ tskTCB * pxTCB;
vApplicationTickHook();
}
}
- #endif
+ #endif /* configUSE_TICK_HOOK */
}
/*-----------------------------------------------------------*/
@@ -1753,7 +1720,7 @@ tskTCB * pxTCB;
taskEXIT_CRITICAL();
}
-#endif
+#endif /* configUSE_APPLICATION_TASK_TAG */
/*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
@@ -1782,7 +1749,7 @@ tskTCB * pxTCB;
return xReturn;
}
-#endif
+#endif /* configUSE_APPLICATION_TASK_TAG */
/*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
@@ -1814,7 +1781,7 @@ tskTCB * pxTCB;
return xReturn;
}
-#endif
+#endif /* configUSE_APPLICATION_TASK_TAG */
/*-----------------------------------------------------------*/
void vTaskSwitchContext( void )
@@ -1845,7 +1812,7 @@ void vTaskSwitchContext( void )
pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
ulTaskSwitchedInTime = ulTotalRunTime;
}
- #endif
+ #endif /* configGENERATE_RUN_TIME_STATS */
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
@@ -1898,14 +1865,14 @@ portTickType xTimeToWake;
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
}
- #else
+ #else /* INCLUDE_vTaskSuspend */
{
/* Calculate the time at which the task should be woken if the event does
not occur. This may overflow but this doesn't matter. */
xTimeToWake = xTickCount + xTicksToWait;
prvAddCurrentTaskToDelayedList( xTimeToWake );
}
- #endif
+ #endif /* INCLUDE_vTaskSuspend */
}
/*-----------------------------------------------------------*/
@@ -2062,6 +2029,7 @@ void vTaskMissedYield( void )
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
+
unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask )
{
unsigned portBASE_TYPE uxReturn;
@@ -2079,10 +2047,12 @@ void vTaskMissedYield( void )
return uxReturn;
}
-#endif
+
+#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
+
void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )
{
tskTCB *pxTCB;
@@ -2093,8 +2063,8 @@ void vTaskMissedYield( void )
pxTCB->uxTaskNumber = uxHandle;
}
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*
* -----------------------------------------------------------
@@ -2125,7 +2095,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
will automatically get the processor anyway. */
taskYIELD();
}
- #endif
+ #endif /* configUSE_PREEMPTION */
#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
{
@@ -2143,7 +2113,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
taskYIELD();
}
}
- #endif
+ #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
#if ( configUSE_IDLE_HOOK == 1 )
{
@@ -2156,7 +2126,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationIdleHook();
}
- #endif
+ #endif /* configUSE_IDLE_HOOK */
/* This conditional compilation should use inequality to 0, not equality
to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
@@ -2190,21 +2160,10 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
xTaskResumeAll();
}
}
- #endif
+ #endif /* configUSE_TICKLESS_IDLE */
}
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
-
-
-
-
-
-
-
-/*-----------------------------------------------------------
- * File private functions documented at the top of the file.
- *----------------------------------------------------------*/
-
-
+/*-----------------------------------------------------------*/
static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )
{
@@ -2214,7 +2173,7 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
/* Don't bring strncpy into the build unnecessarily. */
strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );
}
- #endif
+ #endif /* configMAX_TASK_NAME_LEN */
pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';
/* This is used as an array index so must ensure it's not too large. First
@@ -2229,7 +2188,7 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
{
pxTCB->uxBasePriority = uxPriority;
}
- #endif
+ #endif /* configUSE_MUTEXES */
vListInitialiseItem( &( pxTCB->xGenericListItem ) );
vListInitialiseItem( &( pxTCB->xEventListItem ) );
@@ -2246,30 +2205,30 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
{
pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U;
}
- #endif
+ #endif /* portCRITICAL_NESTING_IN_TCB */
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
{
pxTCB->pxTaskTag = NULL;
}
- #endif
+ #endif /* configUSE_APPLICATION_TASK_TAG */
#if ( configGENERATE_RUN_TIME_STATS == 1 )
{
pxTCB->ulRunTimeCounter = 0UL;
}
- #endif
+ #endif /* configGENERATE_RUN_TIME_STATS */
#if ( portUSING_MPU_WRAPPERS == 1 )
{
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
}
- #else
+ #else /* portUSING_MPU_WRAPPERS */
{
( void ) xRegions;
( void ) usStackDepth;
}
- #endif
+ #endif /* portUSING_MPU_WRAPPERS */
}
/*-----------------------------------------------------------*/
@@ -2289,8 +2248,9 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
}
- /*-----------------------------------------------------------*/
-#endif
+
+#endif /* portUSING_MPU_WRAPPERS */
+/*-----------------------------------------------------------*/
static void prvInitialiseTaskLists( void )
{
@@ -2309,13 +2269,13 @@ unsigned portBASE_TYPE uxPriority;
{
vListInitialise( ( xList * ) &xTasksWaitingTermination );
}
- #endif
+ #endif /* INCLUDE_vTaskDelete */
#if ( INCLUDE_vTaskSuspend == 1 )
{
vListInitialise( ( xList * ) &xSuspendedTaskList );
}
- #endif
+ #endif /* INCLUDE_vTaskSuspend */
/* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
using list2. */
@@ -2355,7 +2315,7 @@ static void prvCheckTasksWaitingTermination( void )
}
}
}
- #endif
+ #endif /* vTaskDelete */
}
/*-----------------------------------------------------------*/
@@ -2446,7 +2406,7 @@ tskTCB *pxNewTCB;
} while( pxNextTCB != pxFirstTCB );
}
-#endif
+#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configGENERATE_RUN_TIME_STATS == 1 )
@@ -2517,7 +2477,7 @@ tskTCB *pxNewTCB;
} while( pxNextTCB != pxFirstTCB );
}
-#endif
+#endif /* configGENERATE_RUN_TIME_STATS */
/*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
@@ -2537,7 +2497,7 @@ tskTCB *pxNewTCB;
return usCount;
}
-#endif
+#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
@@ -2565,7 +2525,7 @@ tskTCB *pxNewTCB;
return uxReturn;
}
-#endif
+#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelete == 1 )
@@ -2583,9 +2543,7 @@ tskTCB *pxNewTCB;
vPortFree( pxTCB );
}
-#endif
-
-
+#endif /* INCLUDE_vTaskDelete */
/*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
@@ -2602,8 +2560,7 @@ tskTCB *pxNewTCB;
return xReturn;
}
-#endif
-
+#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
@@ -2631,7 +2588,7 @@ tskTCB *pxNewTCB;
return xReturn;
}
-#endif
+#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MUTEXES == 1 )
@@ -2673,7 +2630,7 @@ tskTCB *pxNewTCB;
}
}
-#endif
+#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( configUSE_MUTEXES == 1 )
@@ -2703,7 +2660,7 @@ tskTCB *pxNewTCB;
}
}
-#endif
+#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
@@ -2718,7 +2675,7 @@ tskTCB *pxNewTCB;
}
}
-#endif
+#endif /* portCRITICAL_NESTING_IN_TCB */
/*-----------------------------------------------------------*/
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
@@ -2737,9 +2694,9 @@ tskTCB *pxNewTCB;
}
}
}
- }
+ }
-#endif
+#endif /* portCRITICAL_NESTING_IN_TCB */
/*-----------------------------------------------------------*/