+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+\r
+#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+TickType_t uxTaskResetEventItemValue( void )\r
+{\r
+TickType_t uxReturn;\r
+\r
+ uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) );\r
+\r
+ /* Reset the event list item to its normal value - so it can be used with\r
+ queues and semaphores. */\r
+ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
+\r
+ return uxReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 )\r
+\r
+ void *pvTaskIncrementMutexHeldCount( void )\r
+ {\r
+ /* If xSemaphoreCreateMutex() is called before any tasks have been created\r
+ then pxCurrentTCB will be NULL. */\r
+ if( pxCurrentTCB != NULL )\r
+ {\r
+ ( pxCurrentTCB->uxMutexesHeld )++;\r
+ }\r
+\r
+ return pxCurrentTCB;\r
+ }\r
+\r
+#endif /* configUSE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configUSE_TASK_NOTIFICATIONS == 1 )\r
+\r
+ uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )\r
+ {\r
+ TickType_t xTimeToWake;\r
+ uint32_t ulReturn;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Only block if the notification count is not already non-zero. */\r
+ if( pxCurrentTCB->ulNotifiedValue == 0UL )\r
+ {\r
+ /* Mark this task as waiting for a notification. */\r
+ pxCurrentTCB->eNotifyState = eWaitingNotification;\r
+\r
+ if( xTicksToWait > ( TickType_t ) 0 )\r
+ {\r
+ /* The task is going to block. First it must be removed\r
+ from the ready list. */\r
+ if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is\r
+ no need to check, and the port reset macro can be called\r
+ directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ if( xTicksToWait == portMAX_DELAY )\r
+ {\r
+ /* Add the task to the suspended task list instead\r
+ of a delayed task list to ensure the task is not\r
+ woken by a timing event. It will block\r
+ indefinitely. */\r
+ vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* Calculate the time at which the task should be\r
+ woken if no notification events occur. This may\r
+ overflow but this doesn't matter, the scheduler will\r
+ handle it. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ }\r
+ #else /* INCLUDE_vTaskSuspend */\r
+ {\r
+ /* Calculate the time at which the task should be\r
+ woken if the event does not occur. This may\r
+ overflow but this doesn't matter, the scheduler will\r
+ handle it. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ #endif /* INCLUDE_vTaskSuspend */\r
+\r
+ traceTASK_NOTIFY_TAKE_BLOCK();\r
+\r
+ /* All ports are written to allow a yield in a critical\r
+ section (some will yield immediately, others wait until the\r
+ critical section exits) - but it is not something that\r
+ application code should ever do. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ traceTASK_NOTIFY_TAKE();\r
+ ulReturn = pxCurrentTCB->ulNotifiedValue;\r
+\r
+ if( ulReturn != 0UL )\r
+ {\r
+ if( xClearCountOnExit != pdFALSE )\r
+ {\r
+ pxCurrentTCB->ulNotifiedValue = 0UL;\r
+ }\r
+ else\r
+ {\r
+ ( pxCurrentTCB->ulNotifiedValue )--;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+\r
+ pxCurrentTCB->eNotifyState = eNotWaitingNotification;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return ulReturn;\r
+ }\r
+\r
+#endif /* configUSE_TASK_NOTIFICATIONS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configUSE_TASK_NOTIFICATIONS == 1 )\r
+\r
+ BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )\r
+ {\r
+ TickType_t xTimeToWake;\r
+ BaseType_t xReturn;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Only block if a notification is not already pending. */\r
+ if( pxCurrentTCB->eNotifyState != eNotified )\r
+ {\r
+ /* Clear bits in the task's notification value as bits may get\r
+ set by the notifying task or interrupt. This can be used to\r
+ clear the value to zero. */\r
+ pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;\r
+\r
+ /* Mark this task as waiting for a notification. */\r
+ pxCurrentTCB->eNotifyState = eWaitingNotification;\r
+\r
+ if( xTicksToWait > ( TickType_t ) 0 )\r
+ {\r
+ /* The task is going to block. First it must be removed\r
+ from the ready list. */\r
+ if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is\r
+ no need to check, and the port reset macro can be called\r
+ directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ if( xTicksToWait == portMAX_DELAY )\r
+ {\r
+ /* Add the task to the suspended task list instead\r
+ of a delayed task list to ensure the task is not\r
+ woken by a timing event. It will block\r
+ indefinitely. */\r
+ vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* Calculate the time at which the task should be\r
+ woken if no notification events occur. This may\r
+ overflow but this doesn't matter, the scheduler will\r
+ handle it. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ }\r
+ #else /* INCLUDE_vTaskSuspend */\r
+ {\r
+ /* Calculate the time at which the task should be\r
+ woken if the event does not occur. This may\r
+ overflow but this doesn't matter, the scheduler will\r
+ handle it. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ #endif /* INCLUDE_vTaskSuspend */\r
+\r
+ traceTASK_NOTIFY_WAIT_BLOCK();\r
+\r
+ /* All ports are written to allow a yield in a critical\r
+ section (some will yield immediately, others wait until the\r
+ critical section exits) - but it is not something that\r
+ application code should ever do. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ traceTASK_NOTIFY_WAIT();\r
+\r
+ if( pulNotificationValue != NULL )\r
+ {\r
+ /* Output the current notification value, which may or may not\r
+ have changed. */\r
+ *pulNotificationValue = pxCurrentTCB->ulNotifiedValue;\r
+ }\r
+\r
+ /* If eNotifyValue is set then either the task never entered the\r
+ blocked state (because a notification was already pending) or the\r
+ task unblocked because of a notification. Otherwise the task\r
+ unblocked because of a timeout. */\r
+ if( pxCurrentTCB->eNotifyState == eWaitingNotification )\r
+ {\r
+ /* A notification was not received. */\r
+ xReturn = pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ /* A notification was already pending or a notification was\r
+ received while the task was waiting. */\r
+ pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;\r
+ xReturn = pdTRUE;\r
+ }\r
+\r
+ pxCurrentTCB->eNotifyState = eNotWaitingNotification;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_TASK_NOTIFICATIONS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configUSE_TASK_NOTIFICATIONS == 1 )\r
+\r
+ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )\r
+ {\r
+ TCB_t * pxTCB;\r
+ eNotifyValue eOriginalNotifyState;\r
+ BaseType_t xReturn = pdPASS;\r
+\r
+ configASSERT( xTaskToNotify );\r
+ pxTCB = ( TCB_t * ) xTaskToNotify;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( pulPreviousNotificationValue != NULL )\r
+ {\r
+ *pulPreviousNotificationValue = pxTCB->ulNotifiedValue;\r
+ }\r
+\r
+ eOriginalNotifyState = pxTCB->eNotifyState;\r
+\r
+ pxTCB->eNotifyState = eNotified;\r
+\r
+ switch( eAction )\r
+ {\r
+ case eSetBits :\r
+ pxTCB->ulNotifiedValue |= ulValue;\r
+ break;\r
+\r
+ case eIncrement :\r
+ ( pxTCB->ulNotifiedValue )++;\r
+ break;\r
+\r
+ case eSetValueWithOverwrite :\r
+ pxTCB->ulNotifiedValue = ulValue;\r
+ break;\r
+\r
+ case eSetValueWithoutOverwrite :\r
+ if( eOriginalNotifyState != eNotified )\r
+ {\r
+ pxTCB->ulNotifiedValue = ulValue;\r
+ }\r
+ else\r
+ {\r
+ /* The value could not be written to the task. */\r
+ xReturn = pdFAIL;\r
+ }\r
+ break;\r
+\r
+ case eNoAction:\r
+ /* The task is being notified without its notify value being\r
+ updated. */\r
+ break;\r
+ }\r
+\r
+ traceTASK_NOTIFY();\r
+\r
+ /* If the task is in the blocked state specifically to wait for a\r
+ notification then unblock it now. */\r
+ if( eOriginalNotifyState == eWaitingNotification )\r
+ {\r
+ ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyList( pxTCB );\r
+\r
+ /* The task should not have been on an event list. */\r
+ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );\r
+\r
+ #if( configUSE_TICKLESS_IDLE != 0 )\r
+ {\r
+ /* If a task is blocked waiting for a notification then\r
+ xNextTaskUnblockTime might be set to the blocked task's time\r
+ out time. If the task is unblocked for a reason other than\r
+ a timeout xNextTaskUnblockTime is normally left unchanged,\r
+ because it will automatically get reset to a new value when\r
+ the tick count equals xNextTaskUnblockTime. However if\r
+ tickless idling is used it might be more important to enter\r
+ sleep mode at the earliest possible time - so reset\r
+ xNextTaskUnblockTime here to ensure it is updated at the\r
+ earliest possible time. */\r
+ prvResetNextTaskUnblockTime();\r
+ }\r
+ #endif\r
+\r
+ if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )\r
+ {\r
+ /* The notified task has a priority above the currently\r
+ executing task so a yield is required. */\r
+ taskYIELD_IF_USING_PREEMPTION();\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r