Feature/multiple direct to task notifications (#63)

Description
Before this change each task had a single direct to task notification value and state as described here: https://www.FreeRTOS.org/RTOS-task-notifications.html. After this change each task has an array of task notifications, so more than one task notification value and state per task. The new FreeRTOSConfig.h compile time constant configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the array.

Each notification within the array operates independently - a task can only block on one notification within the array at a time and will not be unblocked by a notification sent to any other array index.

Task notifications were introduced as a light weight method for peripheral drivers to pass data and events to tasks without the need for an intermediary object such as a semaphore - for example, to unblock a task from an ISR when the operation of a peripheral completed. That use case only requires a single notification value. Their popularity and resultant expanded use cases have since made the single value a limitation - especially as FreeRTOS stream and message buffers themselves use the notification mechanism. This change resolves that limitation. Stream and message buffers still use the task notification at array index 0, but now application writers can avoid any conflict that might have with their own use of task notifications by using notifications at array indexes other than 0.

The pre-existing task notification API functions work in a backward compatible way by always using the task notification at array index 0. For each such function there is now an equivalent that is postfixed "Indexed" and takes an additional parameter to specify which index within the array it should operate upon. For example, xTaskNotify() is the original that only operates on array index 0. xTaskNotifyIndexed() is the new function that can operate on any array index.

Test Steps
The update is tested using the Win32 demo (PR to be created in the FreeRTOS/FreeRTOS github repo), which has been updated to build and run a new test file FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c. The tests in that file are in addition to, not a replacement for those in FreeRTOS/Demo/Common/Minimal/TaskNotify.c.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 5a1a497..530a237 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -834,6 +834,14 @@
 	#define configUSE_TASK_NOTIFICATIONS 1

 #endif

 

+#ifndef configTASK_NOTIFICATION_ARRAY_ENTRIES

+	#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1

+#endif

+

+#if configTASK_NOTIFICATION_ARRAY_ENTRIES < 1

+	#error configTASK_NOTIFICATION_ARRAY_ENTRIES must be at least 1

+#endif

+

 #ifndef configUSE_POSIX_ERRNO

 	#define configUSE_POSIX_ERRNO 0

 #endif

@@ -1144,8 +1152,8 @@
 		struct	_reent	xDummy17;

 	#endif

 	#if ( configUSE_TASK_NOTIFICATIONS == 1 )

-		uint32_t 		ulDummy18;

-		uint8_t 		ucDummy19;

+		uint32_t 		ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];

+		uint8_t 		ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];

 	#endif

 	#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )

 		uint8_t			uxDummy20;

diff --git a/include/task.h b/include/task.h
index fe2a767..3eaf6ee 100644
--- a/include/task.h
+++ b/include/task.h
@@ -56,6 +56,13 @@
 #define tskMPU_REGION_NORMAL_MEMORY		( 1UL << 3UL )

 #define tskMPU_REGION_DEVICE_MEMORY		( 1UL << 4UL )

 

+/* The direct to task notification feature used to have only a single notification

+per task.  Now there is an array of notifications per task that is dimensioned by

+configTASK_NOTIFICATION_ARRAY_ENTRIES.  For backward compatibility, any use of the

+original direct to task notification defaults to using the first index in the

+array. */

+#define tskDEFAULT_INDEX_TO_NOTIFY 	( 0 )

+

 /**

  * task. h

  *

@@ -1773,13 +1780,22 @@
 

 /**

  * task. h

+ * <PRE>BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>

  * <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>

  *

- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this

- * function to be available.

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these

+ * functions to be available.

+ *

+ * Sends a direct to task notification to a task, with an optional value and

+ * action.

+ *

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -1787,28 +1803,46 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

- * A notification sent to a task will remain pending until it is cleared by the

- * task calling xTaskNotifyWait() or ulTaskNotifyTake().  If the task was

- * already in the Blocked state to wait for a notification when the notification

- * arrives then the task will automatically be removed from the Blocked state

- * (unblocked) and the notification cleared.

- *

- * A task can use xTaskNotifyWait() to [optionally] block to wait for a

- * notification to be pending, or ulTaskNotifyTake() to [optionally] block

- * to wait for its notification value to have a non-zero value.  The task does

+ * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a

+ * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block

+ * to wait for a notification value to have a non-zero value.  The task does

  * not consume any CPU time while it is in the Blocked state.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ * A notification sent to a task will remain pending until it is cleared by the

+ * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their

+ * un-indexed equivalents).  If the task was already in the Blocked state to

+ * wait for a notification when the notification arrives then the task will

+ * automatically be removed from the Blocked state (unblocked) and the

+ * notification cleared.

+ *

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotify() is the original API function, and remains backward

+ * compatible by always operating on the notification value at index 0 in the

+ * array. Calling xTaskNotify() is equivalent to calling xTaskNotifyIndexed()

+ * with the uxIndexToNotify parameter set to 0.

  *

  * @param xTaskToNotify The handle of the task being notified.  The handle to a

  * task can be returned from the xTaskCreate() API function used to create the

  * task, and the handle of the currently running task can be obtained by calling

  * xTaskGetCurrentTaskHandle().

  *

+ * @param uxIndexToNotify The index within the target task's array of

+ * notification values to which the notification is to be sent.  uxIndexToNotify

+ * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.  xTaskNotify() does

+ * not have this parameter and always sends notifications to index 0.

+ *

  * @param ulValue Data that can be sent with the notification.  How the data is

  * used depends on the value of the eAction parameter.

  *

@@ -1816,56 +1850,88 @@
  * value, if at all.  Valid values for eAction are as follows:

  *

  * eSetBits -

- * The task's notification value is bitwise ORed with ulValue.  xTaskNofify()

- * always returns pdPASS in this case.

+ * The target notification value is bitwise ORed with ulValue.

+ * xTaskNofifyIndexed() always returns pdPASS in this case.

  *

  * eIncrement -

- * The task's notification value is incremented.  ulValue is not used and

- * xTaskNotify() always returns pdPASS in this case.

+ * The target notification value is incremented.  ulValue is not used and

+ * xTaskNotifyIndexed() always returns pdPASS in this case.

  *

  * eSetValueWithOverwrite -

- * The task's notification value is set to the value of ulValue, even if the

- * task being notified had not yet processed the previous notification (the

- * task already had a notification pending).  xTaskNotify() always returns

- * pdPASS in this case.

+ * The target notification value is set to the value of ulValue, even if the

+ * task being notified had not yet processed the previous notification at the

+ * same array index (the task already had a notification pending at that index).

+ * xTaskNotifyIndexed() always returns pdPASS in this case.

  *

  * eSetValueWithoutOverwrite -

- * If the task being notified did not already have a notification pending then

- * the task's notification value is set to ulValue and xTaskNotify() will

- * return pdPASS.  If the task being notified already had a notification

- * pending then no action is performed and pdFAIL is returned.

+ * If the task being notified did not already have a notification pending at the

+ * same array index then the target notification value is set to ulValue and

+ * xTaskNotifyIndexed() will return pdPASS.  If the task being notified already

+ * had a notification pending at the same array index then no action is

+ * performed and pdFAIL is returned.

  *

  * eNoAction -

- * The task receives a notification without its notification value being

- * updated.  ulValue is not used and xTaskNotify() always returns pdPASS in

- * this case.

+ * The task receives a notification at the specified array index without the

+ * notification value at that index being updated.  ulValue is not used and

+ * xTaskNotifyIndexed() always returns pdPASS in this case.

  *

- *  pulPreviousNotificationValue -

- *  Can be used to pass out the subject task's notification value before any

- *  bits are modified by the notify function.

+ * pulPreviousNotificationValue -

+ * Can be used to pass out the subject task's notification value before any

+ * bits are modified by the notify function.

  *

  * @return Dependent on the value of eAction.  See the description of the

  * eAction parameter.

  *

- * \defgroup xTaskNotify xTaskNotify

+ * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed

  * \ingroup TaskNotifications

  */

-BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;

-#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )

-#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )

+BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;

+#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL )

+#define xTaskNotifyIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL )

 

 /**

  * task. h

+ * <PRE>BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue );</PRE>

+ * <PRE>BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue );</PRE>

+ *

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ *

+ * xTaskNotifyAndQueryIndexed() performs the same operation as

+ * xTaskNotifyIndexed() with the addition that it also returns the subject

+ * task's prior notification value (the notification value at the time the

+ * function is called rather than when the function returns) in the additional

+ * pulPreviousNotifyValue parameter.

+ *

+ * xTaskNotifyAndQuery() performs the same operation as xTaskNotify() with the

+ * addition that it also returns the subject task's prior notification value

+ * (the notification value as it was at the time the function is called, rather

+ * than when the function returns) in the additional pulPreviousNotifyValue

+ * parameter.

+ *

+ * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed

+ * \ingroup TaskNotifications

+ */

+#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )

+#define xTaskNotifyAndQueryIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )

+

+/**

+ * task. h

+ * <PRE>BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );</PRE>

  * <PRE>BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );</PRE>

  *

- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this

- * function to be available.

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these

+ * functions to be available.

  *

- * A version of xTaskNotify() that can be used from an interrupt service routine

- * (ISR).

+ * A version of xTaskNotifyIndexed() that can be used from an interrupt service

+ * routine (ISR).

+ *

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -1873,22 +1939,40 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

- * A notification sent to a task will remain pending until it is cleared by the

- * task calling xTaskNotifyWait() or ulTaskNotifyTake().  If the task was

- * already in the Blocked state to wait for a notification when the notification

- * arrives then the task will automatically be removed from the Blocked state

- * (unblocked) and the notification cleared.

- *

- * A task can use xTaskNotifyWait() to [optionally] block to wait for a

- * notification to be pending, or ulTaskNotifyTake() to [optionally] block

- * to wait for its notification value to have a non-zero value.  The task does

+ * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a

+ * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block

+ * to wait for a notification value to have a non-zero value.  The task does

  * not consume any CPU time while it is in the Blocked state.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ * A notification sent to a task will remain pending until it is cleared by the

+ * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their

+ * un-indexed equivalents).  If the task was already in the Blocked state to

+ * wait for a notification when the notification arrives then the task will

+ * automatically be removed from the Blocked state (unblocked) and the

+ * notification cleared.

+ *

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotifyFromISR() is the original API function, and remains

+ * backward compatible by always operating on the notification value at index 0

+ * within the array. Calling xTaskNotifyFromISR() is equivalent to calling

+ * xTaskNotifyIndexedFromISR() with the uxIndexToNotify parameter set to 0.

+ *

+ * @param uxIndexToNotify The index within the target task's array of

+ * notification values to which the notification is to be sent.  uxIndexToNotify

+ * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.  xTaskNotifyFromISR()

+ * does not have this parameter and always sends notifications to index 0.

  *

  * @param xTaskToNotify The handle of the task being notified.  The handle to a

  * task can be returned from the xTaskCreate() API function used to create the

@@ -1938,22 +2022,56 @@
  * @return Dependent on the value of eAction.  See the description of the

  * eAction parameter.

  *

- * \defgroup xTaskNotify xTaskNotify

+ * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR

  * \ingroup TaskNotifications

  */

-BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;

-#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )

-#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )

+BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;

+#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )

+#define xTaskNotifyIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )

 

 /**

  * task. h

+ * <PRE>BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken );</PRE>

+ * <PRE>BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken );</PRE>

+ *

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ *

+ * xTaskNotifyAndQueryIndexedFromISR() performs the same operation as

+ * xTaskNotifyIndexedFromISR() with the addition that it also returns the

+ * subject task's prior notification value (the notification value at the time

+ * the function is called rather than at the time the function returns) in the

+ * additional pulPreviousNotifyValue parameter.

+ *

+ * xTaskNotifyAndQueryFromISR() performs the same operation as

+ * xTaskNotifyFromISR() with the addition that it also returns the subject

+ * task's prior notification value (the notification value at the time the

+ * function is called rather than at the time the function returns) in the

+ * additional pulPreviousNotifyValue parameter.

+ *

+ * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR

+ * \ingroup TaskNotifications

+ */

+#define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )

+#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )

+

+/**

+ * task. h

+ * <PRE>BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );</pre>

  * <PRE>BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );</pre>

  *

+ * Waits for a direct to task notification to be pending at a given index within

+ * an array of direct to task notifications.

+ *

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ *

  * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this

  * function to be available.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -1961,22 +2079,41 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

  * A notification sent to a task will remain pending until it is cleared by the

- * task calling xTaskNotifyWait() or ulTaskNotifyTake().  If the task was

- * already in the Blocked state to wait for a notification when the notification

- * arrives then the task will automatically be removed from the Blocked state

- * (unblocked) and the notification cleared.

+ * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their

+ * un-indexed equivalents).  If the task was already in the Blocked state to

+ * wait for a notification when the notification arrives then the task will

+ * automatically be removed from the Blocked state (unblocked) and the

+ * notification cleared.

  *

- * A task can use xTaskNotifyWait() to [optionally] block to wait for a

- * notification to be pending, or ulTaskNotifyTake() to [optionally] block

- * to wait for its notification value to have a non-zero value.  The task does

+ * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a

+ * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block

+ * to wait for a notification value to have a non-zero value.  The task does

  * not consume any CPU time while it is in the Blocked state.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotifyWait() is the original API function, and remains backward

+ * compatible by always operating on the notification value at index 0 in the

+ * array. Calling xTaskNotifyWait() is equivalent to calling

+ * xTaskNotifyWaitIndexed() with the uxIndexToWaitOn parameter set to 0.

+ *

+ * @param uxIndexToWaitOn The index within the calling task's array of

+ * notification values on which the calling task will wait for a notification to

+ * be received.  uxIndexToWaitOn must be less than

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES.  xTaskNotifyWait() does

+ * not have this parameter and always waits for notifications on index 0.

  *

  * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value

  * will be cleared in the calling task's notification value before the task

@@ -2015,20 +2152,31 @@
  * already pending when xTaskNotifyWait was called) then pdPASS is

  * returned.  Otherwise pdFAIL is returned.

  *

- * \defgroup xTaskNotifyWait xTaskNotifyWait

+ * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed

  * \ingroup TaskNotifications

  */

-BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

+BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

+#define xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) )

+#define xTaskNotifyWaitIndexed( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) )

 

 /**

  * task. h

+ * <PRE>BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify );</PRE>

  * <PRE>BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );</PRE>

  *

- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro

- * to be available.

+ * Sends a direct to task notification to a particular index in the target

+ * task's notification array in a manner similar to giving a counting semaphore.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.

+ *

+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these

+ * macros to be available.

+ *

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -2036,48 +2184,72 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

- * xTaskNotifyGive() is a helper macro intended for use when task notifications

- * are used as light weight and faster binary or counting semaphore equivalents.

- * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function,

- * the equivalent action that instead uses a task notification is

- * xTaskNotifyGive().

+ * xTaskNotifyGiveIndexed() is a helper macro intended for use when task

+ * notifications are used as light weight and faster binary or counting

+ * semaphore equivalents.  Actual FreeRTOS semaphores are given using the

+ * xSemaphoreGive() API function, the equivalent action that instead uses a task

+ * notification is xTaskNotifyGiveIndexed().

  *

  * When task notifications are being used as a binary or counting semaphore

  * equivalent then the task being notified should wait for the notification

- * using the ulTaskNotificationTake() API function rather than the

- * xTaskNotifyWait() API function.

+ * using the ulTaskNotificationTakeIndexed() API function rather than the

+ * xTaskNotifyWaitIndexed() API function.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotifyGive() is the original API function, and remains backward

+ * compatible by always operating on the notification value at index 0 in the

+ * array. Calling xTaskNotifyGive() is equivalent to calling

+ * xTaskNotifyGiveIndexed() with the uxIndexToNotify parameter set to 0.

  *

  * @param xTaskToNotify The handle of the task being notified.  The handle to a

  * task can be returned from the xTaskCreate() API function used to create the

  * task, and the handle of the currently running task can be obtained by calling

  * xTaskGetCurrentTaskHandle().

  *

+ * @param uxIndexToNotify The index within the target task's array of

+ * notification values to which the notification is to be sent.  uxIndexToNotify

+ * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.  xTaskNotifyGive()

+ * does not have this parameter and always sends notifications to index 0.

+ *

  * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the

  * eAction parameter set to eIncrement - so pdPASS is always returned.

  *

- * \defgroup xTaskNotifyGive xTaskNotifyGive

+ * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed

  * \ingroup TaskNotifications

  */

-#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL )

+#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( 0 ), eIncrement, NULL )

+#define xTaskNotifyGiveIndexed( xTaskToNotify, uxIndexToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL )

 

 /**

  * task. h

+ * <PRE>void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken );

  * <PRE>void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );

  *

+ * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt

+ * service routine (ISR).

+ *

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.

+ *

  * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro

  * to be available.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

- *

- * A version of xTaskNotifyGive() that can be called from an interrupt service

- * routine (ISR).

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -2085,28 +2257,46 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

- * vTaskNotifyGiveFromISR() is intended for use when task notifications are

- * used as light weight and faster binary or counting semaphore equivalents.

+ * vTaskNotifyGiveIndexedFromISR() is intended for use when task notifications

+ * are used as light weight and faster binary or counting semaphore equivalents.

  * Actual FreeRTOS semaphores are given from an ISR using the

  * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses

- * a task notification is vTaskNotifyGiveFromISR().

+ * a task notification is vTaskNotifyGiveIndexedFromISR().

  *

  * When task notifications are being used as a binary or counting semaphore

  * equivalent then the task being notified should wait for the notification

- * using the ulTaskNotificationTake() API function rather than the

- * xTaskNotifyWait() API function.

+ * using the ulTaskNotificationTakeIndexed() API function rather than the

+ * xTaskNotifyWaitIndexed() API function.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotifyFromISR() is the original API function, and remains

+ * backward compatible by always operating on the notification value at index 0

+ * within the array. Calling xTaskNotifyGiveFromISR() is equivalent to calling

+ * xTaskNotifyGiveIndexedFromISR() with the uxIndexToNotify parameter set to 0.

  *

  * @param xTaskToNotify The handle of the task being notified.  The handle to a

  * task can be returned from the xTaskCreate() API function used to create the

  * task, and the handle of the currently running task can be obtained by calling

  * xTaskGetCurrentTaskHandle().

  *

+ * @param uxIndexToNotify The index within the target task's array of

+ * notification values to which the notification is to be sent.  uxIndexToNotify

+ * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.

+ * xTaskNotifyGiveFromISR() does not have this parameter and always sends

+ * notifications to index 0.

+ *

  * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set

  * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the

  * task to which the notification was sent to leave the Blocked state, and the

@@ -2116,20 +2306,31 @@
  * requested from an ISR is dependent on the port - see the documentation page

  * for the port in use.

  *

- * \defgroup xTaskNotifyWait xTaskNotifyWait

+ * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR

  * \ingroup TaskNotifications

  */

-void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;

+void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;

+#define vTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( pxHigherPriorityTaskWoken ) );

+#define vTaskNotifyGiveIndexedFromISR( xTaskToNotify, uxIndexToNotify, pxHigherPriorityTaskWoken ) vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) );

 

 /**

  * task. h

+ * <PRE>uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait );</pre>

  * <PRE>uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );</pre>

  *

+ * Waits for a direct to task notification on a particular index in the calling

+ * task's notification array in a manner similar to taking a counting semaphore.

+ *

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ *

  * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this

  * function to be available.

  *

- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private

- * "notification value", which is a 32-bit unsigned integer (uint32_t).

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

  *

  * Events can be sent to a task using an intermediary object.  Examples of such

  * objects are queues, semaphores, mutexes and event groups.  Task notifications

@@ -2137,35 +2338,54 @@
  * an intermediary object.

  *

  * A notification sent to a task can optionally perform an action, such as

- * update, overwrite or increment the task's notification value.  In that way

- * task notifications can be used to send data to a task, or be used as light

- * weight and fast binary or counting semaphores.

+ * update, overwrite or increment one of the task's notification values.  In

+ * that way task notifications can be used to send data to a task, or be used as

+ * light weight and fast binary or counting semaphores.

  *

- * ulTaskNotifyTake() is intended for use when a task notification is used as a

- * faster and lighter weight binary or counting semaphore alternative.  Actual

- * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the

- * equivalent action that instead uses a task notification is

- * ulTaskNotifyTake().

+ * ulTaskNotifyTakeIndexed() is intended for use when a task notification is

+ * used as a faster and lighter weight binary or counting semaphore alternative.

+ * Actual FreeRTOS semaphores are taken using the xSemaphoreTake() API function,

+ * the equivalent action that instead uses a task notification is

+ * ulTaskNotifyTakeIndexed().

  *

  * When a task is using its notification value as a binary or counting semaphore

- * other tasks should send notifications to it using the xTaskNotifyGive()

- * macro, or xTaskNotify() function with the eAction parameter set to

+ * other tasks should send notifications to it using the xTaskNotifyGiveIndexed()

+ * macro, or xTaskNotifyIndex() function with the eAction parameter set to

  * eIncrement.

  *

- * ulTaskNotifyTake() can either clear the task's notification value to

- * zero on exit, in which case the notification value acts like a binary

- * semaphore, or decrement the task's notification value on exit, in which case

- * the notification value acts like a counting semaphore.

+ * ulTaskNotifyTakeIndexed() can either clear the task's notification value at

+ * the array index specified by the uxIndexToWaitOn parameter to zero on exit,

+ * in which case the notification value acts like a binary semaphore, or

+ * decrement the notification value on exit, in which case the notification

+ * value acts like a counting semaphore.

  *

- * A task can use ulTaskNotifyTake() to [optionally] block to wait for a

+ * A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for

  * the task's notification value to be non-zero.  The task does not consume any

  * CPU time while it is in the Blocked state.

  *

- * Where as xTaskNotifyWait() will return when a notification is pending,

- * ulTaskNotifyTake() will return when the task's notification value is

+ * Where as xTaskNotifyWaitIndexed() will return when a notification is pending,

+ * ulTaskNotifyTakeIndexed() will return when the task's notification value is

  * not zero.

  *

- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ * **NOTE** Each notification within the array operates independently - a task

+ * can only block on one notification within the array at a time and will not be

+ * unblocked by a notification sent to any other array index.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  ulTaskNotifyTake() is the original API function, and remains backward

+ * compatible by always operating on the notification value at index 0 in the

+ * array. Calling ulTaskNotifyTake() is equivalent to calling

+ * ulTaskNotifyTakeIndexed() with the uxIndexToWaitOn parameter set to 0.

+ *

+ * @param uxIndexToWaitOn The index within the calling task's array of

+ * notification values on which the calling task will wait for a notification to

+ * be non-zero.  uxIndexToWaitOn must be less than

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES.  xTaskNotifyTake() does

+ * not have this parameter and always waits for notifications on index 0.

  *

  * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's

  * notification value is decremented when the function exits.  In this way the

@@ -2185,40 +2405,113 @@
  * @return The task's notification count before it is either cleared to zero or

  * decremented (see the xClearCountOnExit parameter).

  *

- * \defgroup ulTaskNotifyTake ulTaskNotifyTake

+ * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed

  * \ingroup TaskNotifications

  */

-uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

+uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

+#define ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ) ulTaskGenericNotifyTake( ( tskDEFAULT_INDEX_TO_NOTIFY ), ( xClearCountOnExit ), ( xTicksToWait ) )

+#define ulTaskNotifyTakeIndexed( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ) ulTaskGenericNotifyTake( ( uxIndexToNotify ), ( xClearCountOnExit ), ( xTicksToWait ) )

 

 /**

  * task. h

+ * <PRE>BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear );</pre>

  * <PRE>BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );</pre>

  *

- * If the notification state of the task referenced by the handle xTask is

- * eNotified, then set the task's notification state to eNotWaitingNotification.

- * The task's notification value is not altered.  Set xTask to NULL to clear the

- * notification state of the calling task.

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

+ *

+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these

+ * functions to be available.

+ *

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

+ *

+ * If a notification is sent to an index within the array of notifications then

+ * the notification at that index is said to be 'pending' until it is read or

+ * explicitly cleared by the receiving task.  xTaskNotifyStateClearIndexed()

+ * is the function that clears a pending notification without reading the

+ * notification value.  The notification value at the same array index is not

+ * altered.  Set xTask to NULL to clear the notification state of the calling

+ * task.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  xTaskNotifyStateClear() is the original API function, and remains

+ * backward compatible by always operating on the notification value at index 0

+ * within the array. Calling xTaskNotifyStateClear() is equivalent to calling

+ * xTaskNotifyStateClearIndexed() with the uxIndexToNotify parameter set to 0.

+ *

+ * @param xTask The handle of the RTOS task that will have a notification state

+ * cleared.  Set xTask to NULL to clear a notification state in the calling

+ * task.  To obtain a task's handle create the task using xTaskCreate() and

+ * make use of the pxCreatedTask parameter, or create the task using

+ * xTaskCreateStatic() and store the returned value, or use the task's name in

+ * a call to xTaskGetHandle().

+ *

+ * @param uxIndexToClear The index within the target task's array of

+ * notification values to act upon.  For example, setting uxIndexToClear to 1

+ * will clear the state of the notification at index 1 within the array.

+ * uxIndexToClear must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.

+ * ulTaskNotifyStateClear() does not have this parameter and always acts on the

+ * notification at index 0.

  *

  * @return pdTRUE if the task's notification state was set to

  * eNotWaitingNotification, otherwise pdFALSE.

- * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear

+ *

+ * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed

  * \ingroup TaskNotifications

  */

-BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );

+BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) PRIVILEGED_FUNCTION;

+#define xTaskNotifyStateClear( xTask ) xTaskGenericNotifyStateClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ) )

+#define xTaskNotifyStateClearIndexed( xTask, uxIndexToClear ) xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) )

 

 /**

  * task. h

+ * <PRE>uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear );</pre>

  * <PRE>uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear );</pre>

  *

- * Clears the bits specified by the ulBitsToClear bit mask in the notification

- * value of the task referenced by xTask.

+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.

  *

- * @param xTask The handle of the RTOS task that will have bits in its notification

- * value cleared. Set xTask to NULL to clear bits in the notification value of the

- * calling task.  To obtain a task's handle create the task using xTaskCreate() and

- * make use of the pxCreatedTask parameter, or create the task using

- * xTaskCreateStatic() and store the returned value, or use the task's name in a call

- * to xTaskGetHandle().

+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these

+ * functions to be available.

+ *

+ * Each task has a private array of "notification values" (or 'notifications'),

+ * each of which is a 32-bit unsigned integer (uint32_t).  The constant

+ * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the

+ * array, and (for backward compatibility) defaults to 1 if left undefined.

+ * Prior to FreeRTOS V10.4.0 there was only one notification value per task.

+ *

+ * ulTaskNotifyValueClearIndexed() clears the bits specified by the

+ * ulBitsToClear bit mask in the notification value at array index uxIndexToClear

+ * of the task referenced by xTask.

+ *

+ * Backward compatibility information:

+ * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and

+ * all task notification API functions operated on that value. Replacing the

+ * single notification value with an array of notification values necessitated a

+ * new set of API functions that could address specific notifications within the

+ * array.  ulTaskNotifyValueClear() is the original API function, and remains

+ * backward compatible by always operating on the notification value at index 0

+ * within the array. Calling ulTaskNotifyValueClear() is equivalent to calling

+ * ulTaskNotifyValueClearIndexed() with the uxIndexToClear parameter set to 0.

+ *

+ * @param xTask The handle of the RTOS task that will have bits in one of its

+ * notification values cleared. Set xTask to NULL to clear bits in a

+ * notification value of the calling task.  To obtain a task's handle create the

+ * task using xTaskCreate() and make use of the pxCreatedTask parameter, or

+ * create the task using xTaskCreateStatic() and store the returned value, or

+ * use the task's name in a call to xTaskGetHandle().

+ *

+ * @param uxIndexToClear The index within the target task's array of

+ * notification values in which to clear the bits.  uxIndexToClear

+ * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES.

+ * ulTaskNotifyValueClear() does not have this parameter and always clears bits

+ * in the notification value at index 0.

  *

  * @param ulBitsToClear Bit mask of the bits to clear in the notification value of

  * xTask. Set a bit to 1 to clear the corresponding bits in the task's notification

@@ -2232,7 +2525,9 @@
  * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear

  * \ingroup TaskNotifications

  */

-uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;

+uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;

+#define ulTaskNotifyValueClear( xTask, ulBitsToClear ) ulTaskGenericNotifyValueClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulBitsToClear ) )

+#define ulTaskNotifyValueClearIndexed( xTask, uxIndexToClear, ulBitsToClear ) ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) )

 

 /**

  * task.h

diff --git a/queue.c b/queue.c
index 14ad01e..8b46da0 100644
--- a/queue.c
+++ b/queue.c
@@ -1082,7 +1082,7 @@
 					{

 						mtCOVERAGE_TEST_MARKER();

 					}

-					

+

 					/* Not used in this path. */

 					( void ) uxPreviousMessagesWaiting;

 				}

diff --git a/tasks.c b/tasks.c
index c057973..67b7de2 100644
--- a/tasks.c
+++ b/tasks.c
@@ -65,7 +65,7 @@
 #endif

 

 /* Values that can be assigned to the ucNotifyState member of the TCB. */

-#define taskNOT_WAITING_NOTIFICATION	( ( uint8_t ) 0 )

+#define taskNOT_WAITING_NOTIFICATION	( ( uint8_t ) 0 ) /* Must be zero as it is the initialised value. */

 #define taskWAITING_NOTIFICATION		( ( uint8_t ) 1 )

 #define taskNOTIFICATION_RECEIVED		( ( uint8_t ) 2 )

 

@@ -308,8 +308,8 @@
 	#endif

 

 	#if( configUSE_TASK_NOTIFICATIONS == 1 )

-		volatile uint32_t ulNotifiedValue;

-		volatile uint8_t ucNotifyState;

+		volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];

+		volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];

 	#endif

 

 	/* See the comments in FreeRTOS.h with the definition of

@@ -980,17 +980,14 @@
 

 	#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )

 	{

-		for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )

-		{

-			pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL;

-		}

+		memset( ( void * ) &( pxNewTCB->pvThreadLocalStoragePointers[ 0 ] ), 0x00, sizeof( pxNewTCB->pvThreadLocalStoragePointers ) );

 	}

 	#endif

 

 	#if ( configUSE_TASK_NOTIFICATIONS == 1 )

 	{

-		pxNewTCB->ulNotifiedValue = 0;

-		pxNewTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;

+		memset( ( void * ) &( pxNewTCB->ulNotifiedValue[ 0 ] ), 0x00, sizeof( pxNewTCB->ulNotifiedValue ) );

+		memset( ( void * ) &( pxNewTCB->ucNotifyState[ 0 ] ), 0x00, sizeof( pxNewTCB->ucNotifyState ) );

 	}

 	#endif

 

@@ -1423,17 +1420,21 @@
 					{

 						#if( configUSE_TASK_NOTIFICATIONS == 1 )

 						{

+							BaseType_t x;

+

 							/* The task does not appear on the event list item of

 							and of the RTOS objects, but could still be in the

 							blocked state if it is waiting on its notification

-							rather than waiting on an object. */

-							if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION )

+							rather than waiting on an object.  If not, is

+							suspended. */

+							eReturn = eSuspended;

+							for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ )

 							{

-								eReturn = eBlocked;

-							}

-							else

-							{

-								eReturn = eSuspended;

+								if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION )

+								{

+									eReturn = eBlocked;

+									break;

+								}

 							}

 						}

 						#else

@@ -1738,11 +1739,16 @@
 

 			#if( configUSE_TASK_NOTIFICATIONS == 1 )

 			{

-				if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION )

+				BaseType_t x;

+

+				for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ )

 				{

-					/* The task was blocked to wait for a notification, but is

-					now suspended, so no notification was received. */

-					pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;

+					if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION )

+					{

+						/* The task was blocked to wait for a notification, but is

+						now suspended, so no notification was received. */

+						pxTCB->ucNotifyState[ x ] = taskNOT_WAITING_NOTIFICATION;

+					}

 				}

 			}

 			#endif

@@ -4635,17 +4641,19 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )

+	uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWait, BaseType_t xClearCountOnExit, TickType_t xTicksToWait )

 	{

 	uint32_t ulReturn;

 

+		configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES );

+

 		taskENTER_CRITICAL();

 		{

 			/* Only block if the notification count is not already non-zero. */

-			if( pxCurrentTCB->ulNotifiedValue == 0UL )

+			if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] == 0UL )

 			{

 				/* Mark this task as waiting for a notification. */

-				pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION;

+				pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION;

 

 				if( xTicksToWait > ( TickType_t ) 0 )

 				{

@@ -4672,18 +4680,18 @@
 

 		taskENTER_CRITICAL();

 		{

-			traceTASK_NOTIFY_TAKE();

-			ulReturn = pxCurrentTCB->ulNotifiedValue;

+			traceTASK_NOTIFY_TAKE( uxIndexToWait );

+			ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ];

 

 			if( ulReturn != 0UL )

 			{

 				if( xClearCountOnExit != pdFALSE )

 				{

-					pxCurrentTCB->ulNotifiedValue = 0UL;

+					pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = 0UL;

 				}

 				else

 				{

-					pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1;

+					pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = ulReturn - ( uint32_t ) 1;

 				}

 			}

 			else

@@ -4691,7 +4699,7 @@
 				mtCOVERAGE_TEST_MARKER();

 			}

 

-			pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;

+			pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION;

 		}

 		taskEXIT_CRITICAL();

 

@@ -4703,22 +4711,28 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )

+	BaseType_t xTaskGenericNotifyWait( 	UBaseType_t uxIndexToWait,

+										uint32_t ulBitsToClearOnEntry,

+										uint32_t ulBitsToClearOnExit,

+										uint32_t *pulNotificationValue,

+										TickType_t xTicksToWait )

 	{

 	BaseType_t xReturn;

 

+		configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES );

+

 		taskENTER_CRITICAL();

 		{

 			/* Only block if a notification is not already pending. */

-			if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED )

+			if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED )

 			{

 				/* Clear bits in the task's notification value as bits may get

 				set	by the notifying task or interrupt.  This can be used to

 				clear the value to zero. */

-				pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;

+				pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry;

 

 				/* Mark this task as waiting for a notification. */

-				pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION;

+				pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION;

 

 				if( xTicksToWait > ( TickType_t ) 0 )

 				{

@@ -4745,20 +4759,20 @@
 

 		taskENTER_CRITICAL();

 		{

-			traceTASK_NOTIFY_WAIT();

+			traceTASK_NOTIFY_WAIT( uxIndexToWait );

 

 			if( pulNotificationValue != NULL )

 			{

 				/* Output the current notification value, which may or may not

 				have changed. */

-				*pulNotificationValue = pxCurrentTCB->ulNotifiedValue;

+				*pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ];

 			}

 

 			/* If ucNotifyValue is set then either the task never entered the

 			blocked state (because a notification was already pending) or the

 			task unblocked because of a notification.  Otherwise the task

 			unblocked because of a timeout. */

-			if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED )

+			if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED )

 			{

 				/* A notification was not received. */

 				xReturn = pdFALSE;

@@ -4767,11 +4781,11 @@
 			{

 				/* A notification was already pending or a notification was

 				received while the task was waiting. */

-				pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;

+				pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnExit;

 				xReturn = pdTRUE;

 			}

 

-			pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;

+			pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION;

 		}

 		taskEXIT_CRITICAL();

 

@@ -4783,12 +4797,17 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )

+	BaseType_t xTaskGenericNotify(	TaskHandle_t xTaskToNotify,

+									UBaseType_t uxIndexToNotify,

+									uint32_t ulValue,

+									eNotifyAction eAction,

+									uint32_t *pulPreviousNotificationValue )

 	{

 	TCB_t * pxTCB;

 	BaseType_t xReturn = pdPASS;

 	uint8_t ucOriginalNotifyState;

 

+		configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );

 		configASSERT( xTaskToNotify );

 		pxTCB = xTaskToNotify;

 

@@ -4796,31 +4815,31 @@
 		{

 			if( pulPreviousNotificationValue != NULL )

 			{

-				*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;

+				*pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];

 			}

 

-			ucOriginalNotifyState = pxTCB->ucNotifyState;

+			ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];

 

-			pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;

+			pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;

 

 			switch( eAction )

 			{

 				case eSetBits	:

-					pxTCB->ulNotifiedValue |= ulValue;

+					pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue;

 					break;

 

 				case eIncrement	:

-					( pxTCB->ulNotifiedValue )++;

+					( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;

 					break;

 

 				case eSetValueWithOverwrite	:

-					pxTCB->ulNotifiedValue = ulValue;

+					pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;

 					break;

 

 				case eSetValueWithoutOverwrite :

 					if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )

 					{

-						pxTCB->ulNotifiedValue = ulValue;

+						pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;

 					}

 					else

 					{

@@ -4838,7 +4857,7 @@
 					/* Should not get here if all enums are handled.

 					Artificially force an assert by testing a value the

 					compiler can't assume is const. */

-					configASSERT( pxTCB->ulNotifiedValue == ~0UL );

+					configASSERT( pxTCB->ulNotifiedValue[ uxIndexToNotify ] == ~0UL );

 

 					break;

 			}

@@ -4897,7 +4916,12 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken )

+	BaseType_t xTaskGenericNotifyFromISR(	TaskHandle_t xTaskToNotify,

+											UBaseType_t uxIndexToNotify,

+											uint32_t ulValue,

+											eNotifyAction eAction,

+											uint32_t *pulPreviousNotificationValue,

+											BaseType_t *pxHigherPriorityTaskWoken )

 	{

 	TCB_t * pxTCB;

 	uint8_t ucOriginalNotifyState;

@@ -4905,6 +4929,7 @@
 	UBaseType_t uxSavedInterruptStatus;

 

 		configASSERT( xTaskToNotify );

+		configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );

 

 		/* RTOS ports that support interrupt nesting have the concept of a

 		maximum	system call (or maximum API call) interrupt priority.

@@ -4930,30 +4955,30 @@
 		{

 			if( pulPreviousNotificationValue != NULL )

 			{

-				*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;

+				*pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];

 			}

 

-			ucOriginalNotifyState = pxTCB->ucNotifyState;

-			pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;

+			ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];

+			pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;

 

 			switch( eAction )

 			{

 				case eSetBits	:

-					pxTCB->ulNotifiedValue |= ulValue;

+					pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue;

 					break;

 

 				case eIncrement	:

-					( pxTCB->ulNotifiedValue )++;

+					( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;

 					break;

 

 				case eSetValueWithOverwrite	:

-					pxTCB->ulNotifiedValue = ulValue;

+					pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;

 					break;

 

 				case eSetValueWithoutOverwrite :

 					if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )

 					{

-						pxTCB->ulNotifiedValue = ulValue;

+						pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;

 					}

 					else

 					{

@@ -4971,7 +4996,7 @@
 					/* Should not get here if all enums are handled.

 					Artificially force an assert by testing a value the

 					compiler can't assume is const. */

-					configASSERT( pxTCB->ulNotifiedValue == ~0UL );

+					configASSERT( pxTCB->ulNotifiedValue[ uxIndexToNotify ] == ~0UL );

 					break;

 			}

 

@@ -5026,13 +5051,14 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )

+	void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken )

 	{

 	TCB_t * pxTCB;

 	uint8_t ucOriginalNotifyState;

 	UBaseType_t uxSavedInterruptStatus;

 

 		configASSERT( xTaskToNotify );

+		configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );

 

 		/* RTOS ports that support interrupt nesting have the concept of a

 		maximum	system call (or maximum API call) interrupt priority.

@@ -5056,12 +5082,12 @@
 

 		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();

 		{

-			ucOriginalNotifyState = pxTCB->ucNotifyState;

-			pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;

+			ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];

+			pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;

 

 			/* 'Giving' is equivalent to incrementing a count in a counting

 			semaphore. */

-			( pxTCB->ulNotifiedValue )++;

+			( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;

 

 			traceTASK_NOTIFY_GIVE_FROM_ISR();

 

@@ -5112,20 +5138,22 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask )

+	BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear )

 	{

 	TCB_t *pxTCB;

 	BaseType_t xReturn;

 

+		configASSERT( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES );

+

 		/* If null is passed in here then it is the calling task that is having

 		its notification state cleared. */

 		pxTCB = prvGetTCBFromHandle( xTask );

 

 		taskENTER_CRITICAL();

 		{

-			if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED )

+			if( pxTCB->ucNotifyState[ uxIndexToClear ] == taskNOTIFICATION_RECEIVED )

 			{

-				pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;

+				pxTCB->ucNotifyState[ uxIndexToClear ] = taskNOT_WAITING_NOTIFICATION;

 				xReturn = pdPASS;

 			}

 			else

@@ -5143,7 +5171,7 @@
 

 #if( configUSE_TASK_NOTIFICATIONS == 1 )

 

-	uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear )

+	uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear )

 	{

 	TCB_t *pxTCB;

 	uint32_t ulReturn;

@@ -5156,8 +5184,8 @@
 		{

 			/* Return the notification as it was before the bits were cleared,

 			then clear the bit mask. */

-			ulReturn = pxCurrentTCB->ulNotifiedValue;

-			pxTCB->ulNotifiedValue &= ~ulBitsToClear;

+			ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToClear ];

+			pxTCB->ulNotifiedValue[ uxIndexToClear ] &= ~ulBitsToClear;

 		}

 		taskEXIT_CRITICAL();