mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-05-28 16:09:03 -04:00
FreeRTOS source:
- Major refactor to consolidate the multiple places where a task is removed from a ready list and placed in a delay list into a single function, reducing code size, and enabling the easy addition of up-coming functionality. - Replace the enum used for task notification states with a uint8_t to reduce the TCB struct size with some compilers, and allow additional members to be added without increasing its size. - Rearrange FreeRTOS.h so all INCLUDE_ defaults are grouped together.
This commit is contained in:
parent
42e73b9b8f
commit
2acc8f2c99
|
@ -56,7 +56,7 @@ extern int uiInEventGroupSetBitsFromISR;
|
|||
#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */
|
||||
|
||||
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
||||
|
||||
|
||||
/* Uses CMSIS API */
|
||||
|
||||
#define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
|
||||
|
@ -571,8 +571,8 @@ void* prvTraceGetCurrentTaskHandle(void);
|
|||
|
||||
/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
|
||||
#undef traceTASK_DELAY_UNTIL
|
||||
#define traceTASK_DELAY_UNTIL() \
|
||||
trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
|
||||
#define traceTASK_DELAY_UNTIL( xTickTimeToWake ) \
|
||||
trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, ( xTickTimeToWake)); \
|
||||
trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
|
||||
|
||||
#if (INCLUDE_OBJECT_DELETE == 1)
|
||||
|
@ -819,7 +819,7 @@ else \
|
|||
|
||||
#undef traceTASK_NOTIFY_TAKE
|
||||
#define traceTASK_NOTIFY_TAKE() \
|
||||
if (pxCurrentTCB->eNotifyState == eNotified) \
|
||||
if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
|
||||
vTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \
|
||||
else \
|
||||
vTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait);
|
||||
|
@ -831,7 +831,7 @@ else \
|
|||
|
||||
#undef traceTASK_NOTIFY_WAIT
|
||||
#define traceTASK_NOTIFY_WAIT() \
|
||||
if (pxCurrentTCB->eNotifyState == eNotified) \
|
||||
if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
|
||||
vTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \
|
||||
else \
|
||||
vTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait);
|
||||
|
@ -848,7 +848,7 @@ else \
|
|||
#undef traceTASK_NOTIFY_FROM_ISR
|
||||
#define traceTASK_NOTIFY_FROM_ISR() \
|
||||
vTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTaskToNotify));
|
||||
|
||||
|
||||
#undef traceTASK_NOTIFY_GIVE_FROM_ISR
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR() \
|
||||
vTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTaskToNotify));
|
||||
|
|
|
@ -129,30 +129,6 @@ extern "C" {
|
|||
#error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskPrioritySet
|
||||
#error Missing definition: INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_uxTaskPriorityGet
|
||||
#error Missing definition: INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelete
|
||||
#error Missing definition: INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskSuspend
|
||||
#error Missing definition: INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelayUntil
|
||||
#error Missing definition: INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelay
|
||||
#error Missing definition: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_16_BIT_TICKS
|
||||
#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
@ -165,20 +141,38 @@ extern "C" {
|
|||
#define configUSE_CO_ROUTINES 0
|
||||
#endif
|
||||
|
||||
#if configUSE_CO_ROUTINES != 0
|
||||
#ifndef configMAX_CO_ROUTINE_PRIORITIES
|
||||
#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
|
||||
#endif
|
||||
#ifndef INCLUDE_vTaskPrioritySet
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
#ifndef INCLUDE_uxTaskPriorityGet
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelete
|
||||
#define INCLUDE_vTaskDelete 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskSuspend
|
||||
#define INCLUDE_vTaskSuspend 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelayUntil
|
||||
#define INCLUDE_vTaskDelayUntil 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_vTaskDelay
|
||||
#define INCLUDE_vTaskDelay 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskAbortDelay
|
||||
#define INCLUDE_xTaskAbortDelay 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#endif
|
||||
|
@ -199,14 +193,6 @@ extern "C" {
|
|||
#define INCLUDE_xTaskGetTaskHandle 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_APPLICATION_TASK_TAG
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#endif
|
||||
|
||||
#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#endif
|
||||
|
@ -215,6 +201,40 @@ extern "C" {
|
|||
#define INCLUDE_eTaskGetState 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskResumeFromISR
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTimerPendFunctionCall
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetSchedulerState
|
||||
#define INCLUDE_xTaskGetSchedulerState 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||
#endif
|
||||
|
||||
#if configUSE_CO_ROUTINES != 0
|
||||
#ifndef configMAX_CO_ROUTINE_PRIORITIES
|
||||
#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_APPLICATION_TASK_TAG
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#endif
|
||||
|
||||
#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#endif
|
||||
|
@ -251,14 +271,6 @@ extern "C" {
|
|||
#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskResumeFromISR
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTimerPendFunctionCall
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
#endif
|
||||
|
||||
#ifndef configASSERT
|
||||
#define configASSERT( x )
|
||||
#define configASSERT_DEFINED 0
|
||||
|
@ -283,15 +295,6 @@ extern "C" {
|
|||
|
||||
#endif /* configUSE_TIMERS */
|
||||
|
||||
#ifndef INCLUDE_xTaskGetSchedulerState
|
||||
#define INCLUDE_xTaskGetSchedulerState 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#endif
|
||||
|
@ -515,7 +518,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifndef traceTASK_DELAY_UNTIL
|
||||
#define traceTASK_DELAY_UNTIL()
|
||||
#define traceTASK_DELAY_UNTIL( x )
|
||||
#endif
|
||||
|
||||
#ifndef traceTASK_DELAY
|
||||
|
@ -877,12 +880,6 @@ typedef struct xSTATIC_LIST
|
|||
StaticMiniListItem_t xDummy3;
|
||||
} StaticList_t;
|
||||
|
||||
/* For data hiding purposes. */
|
||||
typedef enum
|
||||
{
|
||||
eNothing = 0
|
||||
} eDummy;
|
||||
|
||||
/*
|
||||
* In line with software engineering best practice, especially when supplying a
|
||||
* library that is likely to change in future versions, FreeRTOS implements a
|
||||
|
@ -932,7 +929,7 @@ typedef struct xSTATIC_TCB
|
|||
#endif
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
uint32_t ulDummy18;
|
||||
eDummy eDummy19;
|
||||
uint8_t ucDummy19;
|
||||
#endif
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
uint8_t uxDummy20;
|
||||
|
|
|
@ -185,14 +185,6 @@ typedef enum
|
|||
eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */
|
||||
} eSleepModeStatus;
|
||||
|
||||
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
||||
typedef enum
|
||||
{
|
||||
eNotWaitingNotification = 0,
|
||||
eWaitingNotification,
|
||||
eNotified
|
||||
} eNotifyValue;
|
||||
|
||||
/**
|
||||
* Defines the priority used by the idle task. This must not be modified.
|
||||
*
|
||||
|
@ -2105,7 +2097,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xIte
|
|||
* indefinitely, whereas vTaskPlaceOnEventList() does.
|
||||
*
|
||||
*/
|
||||
void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
|
||||
void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
|
|
|
@ -129,6 +129,11 @@ deleted. */
|
|||
#define taskSTATICALLY_ALLOCATED_STACK ( ( uint8_t ) 0x01 )
|
||||
#define taskSTATICALLY_ALLOCATED_TCB ( ( uint8_t ) 0x02 )
|
||||
|
||||
/* Values that can be assigned to the ucNotifyState member of the TCB. */
|
||||
#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 )
|
||||
#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 )
|
||||
#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 )
|
||||
|
||||
/*
|
||||
* Task control block. A task control block (TCB) is allocated for each task,
|
||||
* and stores task state information, including a pointer to the task's context
|
||||
|
@ -174,7 +179,7 @@ typedef struct tskTaskControlBlock
|
|||
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||
#endif
|
||||
|
||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
|
||||
#endif
|
||||
|
||||
|
@ -189,16 +194,16 @@ typedef struct tskTaskControlBlock
|
|||
struct _reent xNewLib_reent;
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
volatile uint32_t ulNotifiedValue;
|
||||
volatile eNotifyValue eNotifyState;
|
||||
volatile uint8_t ucNotifyState;
|
||||
#endif
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
uint8_t ucStaticAllocationFlags; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
|
||||
#endif
|
||||
|
||||
} tskTCB;
|
||||
} tskTCB;
|
||||
|
||||
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
||||
below to enable the use of older kernel aware debuggers. */
|
||||
|
@ -489,7 +494,7 @@ static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
|
|||
* The currently executing task is entering the Blocked state. Add the task to
|
||||
* either the current or the overflow delayed task list.
|
||||
*/
|
||||
static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION;
|
||||
static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Allocates memory from the heap for a TCB and associated stack. Checks the
|
||||
|
@ -615,7 +620,7 @@ StackType_t *pxTopOfStack;
|
|||
/* If we want to use stack checking on architectures that use
|
||||
a positive stack growth direction then we also need to store the
|
||||
other extreme of the stack space. */
|
||||
pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
|
||||
pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );
|
||||
}
|
||||
#endif /* portSTACK_GROWTH */
|
||||
|
||||
|
@ -889,23 +894,11 @@ StackType_t *pxTopOfStack;
|
|||
|
||||
if( xShouldDelay != pdFALSE )
|
||||
{
|
||||
traceTASK_DELAY_UNTIL();
|
||||
traceTASK_DELAY_UNTIL( xTimeToWake );
|
||||
|
||||
/* Remove the task from the ready list before adding it to the
|
||||
blocked list as the same list item is used for both lists. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
/* prvAddCurrentTaskToDelayedList() needs the block time, not
|
||||
the time to wake, so subtract the current tick count. */
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -933,10 +926,8 @@ StackType_t *pxTopOfStack;
|
|||
|
||||
void vTaskDelay( const TickType_t xTicksToDelay )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
BaseType_t xAlreadyYielded = pdFALSE;
|
||||
|
||||
|
||||
/* A delay time of zero just forces a reschedule. */
|
||||
if( xTicksToDelay > ( TickType_t ) 0U )
|
||||
{
|
||||
|
@ -952,26 +943,7 @@ StackType_t *pxTopOfStack;
|
|||
|
||||
This task cannot be in an event list as it is the currently
|
||||
executing task. */
|
||||
|
||||
/* Calculate the time to wake - this may overflow but this is
|
||||
not a problem. */
|
||||
xTimeToWake = xTickCount + xTicksToDelay;
|
||||
|
||||
/* We must remove ourselves from the ready list before adding
|
||||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
}
|
||||
|
@ -2447,8 +2419,6 @@ void vTaskSwitchContext( void )
|
|||
|
||||
void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
configASSERT( pxEventList );
|
||||
|
||||
/* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE
|
||||
|
@ -2460,54 +2430,12 @@ TickType_t xTimeToWake;
|
|||
list is locked, preventing simultaneous access from interrupts. */
|
||||
vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
|
||||
/* The task must be removed from from the ready list before it is added to
|
||||
the blocked list as the same list item is used for both lists. Exclusive
|
||||
access to the ready lists guaranteed because the scheduler is locked. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is no need to
|
||||
check, and the port reset macro can be called directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead of a delayed task
|
||||
list to ensure the task is not woken by a timing event. It will
|
||||
block indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be woken if the event
|
||||
does not occur. This may overflow but this doesn't matter, the
|
||||
scheduler will handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#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, the scheduler
|
||||
will handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
configASSERT( pxEventList );
|
||||
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
|
||||
|
@ -2526,56 +2454,14 @@ TickType_t xTimeToWake;
|
|||
the task level). */
|
||||
vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
|
||||
/* The task must be removed from the ready list before it is added to the
|
||||
blocked list. Exclusive access can be assured to the ready list as the
|
||||
scheduler is locked. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is no need to
|
||||
check, and the port reset macro can be called directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead of a delayed task
|
||||
list to ensure it is not woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be woken if the event
|
||||
does not occur. This may overflow but this doesn't matter, the
|
||||
kernel will manage it correctly. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#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, the kernel
|
||||
will manage it correctly. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_TIMERS == 1
|
||||
#if( configUSE_TIMERS == 1 )
|
||||
|
||||
void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely )
|
||||
void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
configASSERT( pxEventList );
|
||||
|
||||
/* This function should not be called by application code hence the
|
||||
|
@ -2590,59 +2476,16 @@ TickType_t xTimeToWake;
|
|||
can be used in place of vListInsert. */
|
||||
vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
|
||||
/* We must remove this task from the ready list before adding it to the
|
||||
blocked list as the same list item is used for both lists. This
|
||||
function is called with the scheduler locked so interrupts will not
|
||||
access the lists at the same time. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
/* If the task should block indefinitely then set the block time to a
|
||||
value that will be recognised as an indefinite delay inside the
|
||||
prvAddCurrentTaskToDelayedList() function. */
|
||||
if( xWaitIndefinitely == pdTRUE )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is no need to
|
||||
check, and the port reset macro can be called directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
xTicksToWait = portMAX_DELAY;
|
||||
}
|
||||
|
||||
/* If vTaskSuspend() is available then the suspended task list is also
|
||||
available and a task that is blocking indefinitely can enter the
|
||||
suspended state (it is not really suspended as it will re-enter the
|
||||
Ready state when the event it is waiting indefinitely for occurs).
|
||||
Blocking indefinitely is useful when using tickless idle mode as when
|
||||
all tasks are blocked indefinitely all timers can be turned off. */
|
||||
#if( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xWaitIndefinitely == pdTRUE )
|
||||
{
|
||||
/* Add the task to the suspended task list instead of a delayed
|
||||
task list to ensure the task is not woken by a timing event. It
|
||||
will block indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
traceTASK_DELAY_UNTIL();
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* 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;
|
||||
traceTASK_DELAY_UNTIL();
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
|
||||
/* Remove compiler warnings when INCLUDE_vTaskSuspend() is not
|
||||
defined. */
|
||||
( void ) xWaitIndefinitely;
|
||||
}
|
||||
#endif
|
||||
traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) );
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely );
|
||||
}
|
||||
|
||||
#endif /* configUSE_TIMERS */
|
||||
|
@ -2782,9 +2625,9 @@ BaseType_t xReturn;
|
|||
const TickType_t xConstTickCount = xTickCount;
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
|
||||
the maximum block time then the task should block indefinitely, and
|
||||
therefore never time out. */
|
||||
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified
|
||||
is the maximum block time then the task should block indefinitely,
|
||||
and therefore never time out. */
|
||||
if( *pxTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
|
@ -2794,16 +2637,17 @@ BaseType_t xReturn;
|
|||
|
||||
if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */
|
||||
{
|
||||
/* The tick count is greater than the time at which vTaskSetTimeout()
|
||||
was called, but has also overflowed since vTaskSetTimeOut() was called.
|
||||
It must have wrapped all the way around and gone past us again. This
|
||||
passed since vTaskSetTimeout() was called. */
|
||||
/* The tick count is greater than the time at which
|
||||
vTaskSetTimeout() was called, but has also overflowed since
|
||||
vTaskSetTimeOut() was called. It must have wrapped all the way
|
||||
around and gone past again. This passed since vTaskSetTimeout()
|
||||
was called. */
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )
|
||||
else if( ( ( TickType_t ) ( xConstTickCount - pxTimeOut->xTimeOnEntering ) ) < *pxTicksToWait )
|
||||
{
|
||||
/* Not a genuine timeout. Adjust parameters for time remaining. */
|
||||
*pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
|
||||
*pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
|
||||
vTaskSetTimeOutState( pxTimeOut );
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
@ -3117,7 +2961,7 @@ UBaseType_t x;
|
|||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = 0;
|
||||
pxTCB->eNotifyState = eNotWaitingNotification;
|
||||
pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3126,7 +2970,7 @@ UBaseType_t x;
|
|||
/* Initialise this task's Newlib reent structure. */
|
||||
_REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
|
||||
}
|
||||
#endif /* configUSE_NEWLIB_REENTRANT */
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -3261,36 +3105,6 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
|
||||
{
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow list. */
|
||||
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so the current block list is used. */
|
||||
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* If the task entering the blocked state was placed at the head of the
|
||||
list of blocked tasks then xNextTaskUnblockTime needs to be updated
|
||||
too. */
|
||||
if( xTimeToWake < xNextTaskUnblockTime )
|
||||
{
|
||||
xNextTaskUnblockTime = xTimeToWake;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer, TCB_t * const pxTaskBuffer )
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
|
@ -4190,7 +4004,6 @@ TickType_t uxReturn;
|
|||
|
||||
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
uint32_t ulReturn;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
|
@ -4199,55 +4012,11 @@ TickType_t uxReturn;
|
|||
if( pxCurrentTCB->ulNotifiedValue == 0UL )
|
||||
{
|
||||
/* Mark this task as waiting for a notification. */
|
||||
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||
pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION;
|
||||
|
||||
if( xTicksToWait > ( TickType_t ) 0 )
|
||||
{
|
||||
/* The task is going to block. First it must be removed
|
||||
from the ready list. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead
|
||||
of a delayed task list to ensure the task is not
|
||||
woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if no notification events occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#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, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||
traceTASK_NOTIFY_TAKE_BLOCK();
|
||||
|
||||
/* All ports are written to allow a yield in a critical
|
||||
|
@ -4289,7 +4058,7 @@ TickType_t uxReturn;
|
|||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||
pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
|
@ -4303,13 +4072,12 @@ TickType_t uxReturn;
|
|||
|
||||
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
BaseType_t xReturn;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Only block if a notification is not already pending. */
|
||||
if( pxCurrentTCB->eNotifyState != eNotified )
|
||||
if( pxCurrentTCB->ucNotifyState != 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
|
||||
|
@ -4317,55 +4085,11 @@ TickType_t uxReturn;
|
|||
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
|
||||
|
||||
/* Mark this task as waiting for a notification. */
|
||||
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||
pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION;
|
||||
|
||||
if( xTicksToWait > ( TickType_t ) 0 )
|
||||
{
|
||||
/* The task is going to block. First it must be removed
|
||||
from the ready list. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is
|
||||
no need to check, and the port reset macro can be called
|
||||
directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( xTicksToWait == portMAX_DELAY )
|
||||
{
|
||||
/* Add the task to the suspended task list instead
|
||||
of a delayed task list to ensure the task is not
|
||||
woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be
|
||||
woken if no notification events occur. This may
|
||||
overflow but this doesn't matter, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#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, the scheduler will
|
||||
handle it. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||
traceTASK_NOTIFY_WAIT_BLOCK();
|
||||
|
||||
/* All ports are written to allow a yield in a critical
|
||||
|
@ -4397,11 +4121,11 @@ TickType_t uxReturn;
|
|||
*pulNotificationValue = pxCurrentTCB->ulNotifiedValue;
|
||||
}
|
||||
|
||||
/* If eNotifyValue is set then either the task never entered the
|
||||
/* 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->eNotifyState == eWaitingNotification )
|
||||
if( pxCurrentTCB->ucNotifyState == taskWAITING_NOTIFICATION )
|
||||
{
|
||||
/* A notification was not received. */
|
||||
xReturn = pdFALSE;
|
||||
|
@ -4414,7 +4138,7 @@ TickType_t uxReturn;
|
|||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||
pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
|
@ -4429,8 +4153,8 @@ TickType_t uxReturn;
|
|||
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
uint8_t ucOriginalNotifyState;
|
||||
|
||||
configASSERT( xTaskToNotify );
|
||||
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||
|
@ -4442,9 +4166,9 @@ TickType_t uxReturn;
|
|||
*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;
|
||||
}
|
||||
|
||||
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||
ucOriginalNotifyState = pxTCB->ucNotifyState;
|
||||
|
||||
pxTCB->eNotifyState = eNotified;
|
||||
pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;
|
||||
|
||||
switch( eAction )
|
||||
{
|
||||
|
@ -4461,7 +4185,7 @@ TickType_t uxReturn;
|
|||
break;
|
||||
|
||||
case eSetValueWithoutOverwrite :
|
||||
if( eOriginalNotifyState != eNotified )
|
||||
if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
}
|
||||
|
@ -4482,7 +4206,7 @@ TickType_t uxReturn;
|
|||
|
||||
/* If the task is in the blocked state specifically to wait for a
|
||||
notification then unblock it now. */
|
||||
if( eOriginalNotifyState == eWaitingNotification )
|
||||
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
|
@ -4535,7 +4259,7 @@ TickType_t uxReturn;
|
|||
BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
uint8_t ucOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
|
||||
|
@ -4568,8 +4292,8 @@ TickType_t uxReturn;
|
|||
*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;
|
||||
}
|
||||
|
||||
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||
pxTCB->eNotifyState = eNotified;
|
||||
ucOriginalNotifyState = pxTCB->ucNotifyState;
|
||||
pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;
|
||||
|
||||
switch( eAction )
|
||||
{
|
||||
|
@ -4586,7 +4310,7 @@ TickType_t uxReturn;
|
|||
break;
|
||||
|
||||
case eSetValueWithoutOverwrite :
|
||||
if( eOriginalNotifyState != eNotified )
|
||||
if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
|
||||
{
|
||||
pxTCB->ulNotifiedValue = ulValue;
|
||||
}
|
||||
|
@ -4607,7 +4331,7 @@ TickType_t uxReturn;
|
|||
|
||||
/* If the task is in the blocked state specifically to wait for a
|
||||
notification then unblock it now. */
|
||||
if( eOriginalNotifyState == eWaitingNotification )
|
||||
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
|
||||
{
|
||||
/* The task should not have been on an event list. */
|
||||
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||
|
@ -4659,7 +4383,7 @@ TickType_t uxReturn;
|
|||
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
uint8_t ucOriginalNotifyState;
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
|
||||
configASSERT( xTaskToNotify );
|
||||
|
@ -4686,8 +4410,8 @@ TickType_t uxReturn;
|
|||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||
pxTCB->eNotifyState = eNotified;
|
||||
ucOriginalNotifyState = pxTCB->ucNotifyState;
|
||||
pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;
|
||||
|
||||
/* 'Giving' is equivalent to incrementing a count in a counting
|
||||
semaphore. */
|
||||
|
@ -4697,7 +4421,7 @@ TickType_t uxReturn;
|
|||
|
||||
/* If the task is in the blocked state specifically to wait for a
|
||||
notification then unblock it now. */
|
||||
if( eOriginalNotifyState == eWaitingNotification )
|
||||
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
|
||||
{
|
||||
/* The task should not have been on an event list. */
|
||||
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||
|
@ -4756,9 +4480,9 @@ TickType_t uxReturn;
|
|||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
if( pxTCB->eNotifyState == eNotified )
|
||||
if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED )
|
||||
{
|
||||
pxTCB->eNotifyState = eNotWaitingNotification;
|
||||
pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
|
@ -4775,6 +4499,109 @@ TickType_t uxReturn;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, BaseType_t xCanBlockIndefinitely )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
/* Remove the task from the ready list before adding it to the blocked list
|
||||
as the same list item is used for both lists. */
|
||||
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* The current task must be in a ready list, so there is no need to
|
||||
check, and the port reset macro can be called directly. */
|
||||
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) )
|
||||
{
|
||||
/* Add the task to the suspended task list instead of a delayed task
|
||||
list to ensure it is not woken by a timing event. It will block
|
||||
indefinitely. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the time at which the task should be woken if the event
|
||||
does not occur. This may overflow but this doesn't matter, the
|
||||
kernel will manage it correctly. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow
|
||||
list. */
|
||||
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so the current block list
|
||||
is used. */
|
||||
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* If the task entering the blocked state was placed at the
|
||||
head of the list of blocked tasks then xNextTaskUnblockTime
|
||||
needs to be updated too. */
|
||||
if( xTimeToWake < xNextTaskUnblockTime )
|
||||
{
|
||||
xNextTaskUnblockTime = xTimeToWake;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#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, the kernel
|
||||
will manage it correctly. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow list. */
|
||||
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so the current block list is used. */
|
||||
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* If the task entering the blocked state was placed at the head of the
|
||||
list of blocked tasks then xNextTaskUnblockTime needs to be updated
|
||||
too. */
|
||||
if( xTimeToWake < xNextTaskUnblockTime )
|
||||
{
|
||||
xNextTaskUnblockTime = xTimeToWake;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
||||
/* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */
|
||||
( void ) xCanBlockIndefinitely;
|
||||
}
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
}
|
||||
|
||||
|
||||
#ifdef FREERTOS_MODULE_TEST
|
||||
#include "tasks_test_access_functions.h"
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue