forked from epagris/FreeRTOS-Kernel
		
	Added xTaskAbortDelayFromISR() and ulTaskNotifyValueClear() API functions.
Added tests for xTaskAbortDelayFromISR() into Demo/Common/Minimal/AbortDelay.c. Added tests for ulTaskNotifyValueClear() into Demo/Common/Minimal/TaskNotify.c.
This commit is contained in:
		
							parent
							
								
									0a29d350b1
								
							
						
					
					
						commit
						be3561ed53
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -101,6 +101,12 @@ static void prvTestAbortingEventGroupWait( void );
 | 
			
		||||
static void prvTestAbortingQueueSend( void );
 | 
			
		||||
static void prvTestAbortingStreamBufferReceive( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Performs a few tests to cover code paths not otherwise covered by the continuous
 | 
			
		||||
 * tests.
 | 
			
		||||
 */
 | 
			
		||||
static void prvPerformSingleTaskTests( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks the amount of time a task spent in the Blocked state is within the
 | 
			
		||||
 * expected bounds.
 | 
			
		||||
@ -143,6 +149,10 @@ uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS;
 | 
			
		||||
TickType_t xTimeAtStart;
 | 
			
		||||
const TickType_t xStartMargin = 2UL;
 | 
			
		||||
 | 
			
		||||
/* Used to control whether to use xTaskAbortDelay() or xTaskAbortDelayFromISR() so
 | 
			
		||||
both are used with all the tests. */
 | 
			
		||||
BaseType_t xUseFromISRVersion = pdFALSE, xHigherPriorityTaskWoken;
 | 
			
		||||
 | 
			
		||||
	/* Just to remove compiler warnings. */
 | 
			
		||||
	( void ) pvParameters;
 | 
			
		||||
 | 
			
		||||
@ -167,10 +177,46 @@ const TickType_t xStartMargin = 2UL;
 | 
			
		||||
		raise the priority of the controlling task to that of the blocking
 | 
			
		||||
		task to minimise discrepancies. */
 | 
			
		||||
		vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY );
 | 
			
		||||
 | 
			
		||||
		vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin );
 | 
			
		||||
		if( xTaskAbortDelay( xBlockingTask ) != pdPASS )
 | 
			
		||||
 | 
			
		||||
		/* For test coverage sometimes xTaskAbortDelay() is used and sometimes
 | 
			
		||||
		xTaskAbortDelayFromISR() is used. */
 | 
			
		||||
		if( xUseFromISRVersion == pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			xErrorOccurred = pdTRUE;
 | 
			
		||||
			if( xTaskAbortDelay( xBlockingTask ) != pdPASS )
 | 
			
		||||
			{
 | 
			
		||||
				xErrorOccurred = pdTRUE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			xHigherPriorityTaskWoken = pdFALSE;
 | 
			
		||||
 | 
			
		||||
			/* For test coverage, sometimes xHigherPriorityTaskWoken is used, and
 | 
			
		||||
			sometimes NULL is used. */
 | 
			
		||||
 | 
			
		||||
			if( ( xControllingCycles % 2 ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
				if( xTaskAbortDelayFromISR( xBlockingTask, &xHigherPriorityTaskWoken ) != pdPASS )
 | 
			
		||||
				{
 | 
			
		||||
					xErrorOccurred = pdTRUE;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if( xTaskAbortDelayFromISR( xBlockingTask, NULL ) != pdPASS )
 | 
			
		||||
				{
 | 
			
		||||
					xErrorOccurred = pdTRUE;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* The tasks have the same priority so xHigherPriorityTaskWoken should
 | 
			
		||||
			never get set. */
 | 
			
		||||
			if( xHigherPriorityTaskWoken != pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				xErrorOccurred = pdTRUE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Reset the priority to the normal controlling priority. */
 | 
			
		||||
@ -195,6 +241,13 @@ const TickType_t xStartMargin = 2UL;
 | 
			
		||||
 | 
			
		||||
		/* To indicate this task is still executing. */
 | 
			
		||||
		xControllingCycles++;
 | 
			
		||||
 | 
			
		||||
		if( ( xControllingCycles % abtMAX_TESTS ) == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* Looped through all the tests.  Switch between using xTaskAbortDelay()
 | 
			
		||||
			and xTaskAbortDelayFromISR() for the next round of tests. */
 | 
			
		||||
			xUseFromISRVersion = !xUseFromISRVersion;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -208,6 +261,10 @@ const uint32_t ulMax = 0xffffffffUL;
 | 
			
		||||
	/* Just to remove compiler warnings. */
 | 
			
		||||
	( void ) pvParameters;
 | 
			
		||||
 | 
			
		||||
	/* Start by performing a few tests to cover code not exercised in the loops
 | 
			
		||||
	below. */
 | 
			
		||||
	prvPerformSingleTaskTests();
 | 
			
		||||
 | 
			
		||||
	xControllingTask = xTaskGetHandle( pcControllingTaskName );
 | 
			
		||||
	configASSERT( xControllingTask );
 | 
			
		||||
 | 
			
		||||
@ -264,6 +321,29 @@ const uint32_t ulMax = 0xffffffffUL;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvPerformSingleTaskTests( void )
 | 
			
		||||
{
 | 
			
		||||
TaskHandle_t xThisTask;
 | 
			
		||||
BaseType_t xReturned;
 | 
			
		||||
 | 
			
		||||
	/* Try unblocking this task using both the task and ISR versions of the API -
 | 
			
		||||
	both should return false as this task is not blocked. */
 | 
			
		||||
	xThisTask = xTaskGetCurrentTaskHandle();
 | 
			
		||||
 | 
			
		||||
	xReturned = xTaskAbortDelay( xThisTask );
 | 
			
		||||
	if( xReturned != pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		xErrorOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xReturned = xTaskAbortDelayFromISR( xThisTask, NULL );
 | 
			
		||||
	if( xReturned != pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		xErrorOccurred = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvTestAbortingTaskDelayUntil( void )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xTimeAtStart, xLastBlockTime;
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,12 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define notifyTASK_PRIORITY		( tskIDLE_PRIORITY )
 | 
			
		||||
#define notifyUINT32_MAX	( ( uint32_t ) 0xffffffff )
 | 
			
		||||
 | 
			
		||||
/* Constants used in tests when setting/clearing bits. */
 | 
			
		||||
#define notifyUINT32_MAX		( ( uint32_t ) 0xffffffff )
 | 
			
		||||
#define notifyUINT32_HIGH_BYTE	( ( uint32_t ) 0xff000000 )
 | 
			
		||||
#define notifyUINT32_LOW_BYTE	( ( uint32_t ) 0x000000ff )
 | 
			
		||||
 | 
			
		||||
#define notifySUSPENDED_TEST_TIMER_PERIOD pdMS_TO_TICKS( 50 )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -403,6 +408,37 @@ TimerHandle_t xSingleTaskTimer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* ------------------------------------------------------------------------
 | 
			
		||||
	Clear bits in the notification value. */
 | 
			
		||||
 | 
			
		||||
	/* Get the task to set all bits its own notification value.  This is not a
 | 
			
		||||
	normal thing to do, and is only done here for test purposes. */
 | 
			
		||||
	xTaskNotify( xTaskToNotify, notifyUINT32_MAX, eSetBits );
 | 
			
		||||
 | 
			
		||||
	/* Now clear the top bytes - the returned value from the first call should
 | 
			
		||||
	indicate that previously all bits were set. */
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_HIGH_BYTE ) == notifyUINT32_MAX );
 | 
			
		||||
 | 
			
		||||
	/* Next clear the bottom bytes - the returned value this time should indicate
 | 
			
		||||
	that the top byte was clear (before the bottom byte was cleared. */
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_LOW_BYTE ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE ) );
 | 
			
		||||
 | 
			
		||||
	/* Next clear all bytes - the returned value should indicate that previously the
 | 
			
		||||
	high and low bytes were clear. */
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE & ~notifyUINT32_LOW_BYTE ) );
 | 
			
		||||
 | 
			
		||||
	/* Now all bits should be clear. */
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 );
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, 0UL ) == 0 );
 | 
			
		||||
	configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 );
 | 
			
		||||
 | 
			
		||||
	/* Now the notification state should be eNotified, so it should now be
 | 
			
		||||
	possible to clear the notification state. */
 | 
			
		||||
	configASSERT( xTaskNotifyStateClear( NULL ) == pdTRUE );
 | 
			
		||||
	configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* ------------------------------------------------------------------------
 | 
			
		||||
	Create a timer that will try notifying this task while it is suspended. */
 | 
			
		||||
	xSingleTaskTimer = xTimerCreate( "SingleNotify", notifySUSPENDED_TEST_TIMER_PERIOD, pdFALSE, NULL, prvSuspendedTaskTimerTestCallback );
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,21 @@ Changes since the last release:
 | 
			
		||||
	  the variable xPendingTicks.
 | 
			
		||||
	+ Correct alignment of stack top in RISC-V port when
 | 
			
		||||
	  configISR_STACK_SIZE_WORDS is defined to a non zero value.
 | 
			
		||||
	+ RISC-V port updates:  The machine timer compare register can now be for
 | 
			
		||||
	  any HART, and correct the sequence used to update the 64-bit machine timer
 | 
			
		||||
	  compare register on 32-bit cores.
 | 
			
		||||
	+ Update Keil projects that use the MPU so memory regions come from linker
 | 
			
		||||
	  script (scatter file) variables instead of being hard coded.
 | 
			
		||||
	+ Added tickless low power modes into the ARM, IAR and GCC Cortex-M0 compiler
 | 
			
		||||
	  ports.
 | 
			
		||||
	+ Updated the behaviour of the ARMv7-M MPU (Memory Protection Unit) ports to
 | 
			
		||||
	  match that of the ARMv8-M ports whereby privilege escalations can only
 | 
			
		||||
	  originate from within the kernel's own memory segment.
 | 
			
		||||
	+ Added LPC51U68 Cortex-M0+ port for GCC (MCUXpresso), Keil and IAR
 | 
			
		||||
	  compilers.
 | 
			
		||||
	+ Added CORTEX_MPU_STM32L4_Discovery_Keil_STM32Cube demo.
 | 
			
		||||
	+ Added xTaskAbortDelayFromISR() API function.
 | 
			
		||||
	+ Added xTaskNotifyValueClear() API function.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Changes between FreeRTOS V10.2.1 and FreeRTOS V10.2.0 released May 13 2019:
 | 
			
		||||
@ -515,6 +530,8 @@ Changes between V8.2.0 and V8.2.1 released 24th March 2015.
 | 
			
		||||
	  Windows port.
 | 
			
		||||
	+ Update the PIC32 port to remove deprecation warnings output by the latest
 | 
			
		||||
	  XC32 compilers.
 | 
			
		||||
	+ Fix bug when xQueueOverwrite() and xQueueOverwrite() from ISR are used to
 | 
			
		||||
	  overwrite items in two queues that are part of the same set.
 | 
			
		||||
 | 
			
		||||
	Demo application updates:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -76,6 +76,7 @@ BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue,
 | 
			
		||||
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
uint32_t MPU_ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
 | 
			
		||||
@ -82,6 +82,7 @@ only for ports that are using the MPU. */
 | 
			
		||||
		#define xTaskNotifyWait							MPU_xTaskNotifyWait
 | 
			
		||||
		#define ulTaskNotifyTake						MPU_ulTaskNotifyTake
 | 
			
		||||
		#define xTaskNotifyStateClear					MPU_xTaskNotifyStateClear
 | 
			
		||||
		#define ulTaskNotifyValueClear					MPU_ulTaskNotifyValueClear
 | 
			
		||||
		#define xTaskCatchUpTicks						MPU_xTaskCatchUpTicks
 | 
			
		||||
 | 
			
		||||
		#define xTaskGetCurrentTaskHandle				MPU_xTaskGetCurrentTaskHandle
 | 
			
		||||
 | 
			
		||||
@ -841,6 +841,39 @@ void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xT
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* task. h
 | 
			
		||||
* <pre>BaseType_t xTaskAbortDelayFromISR( TaskHandle_t xTask, BaseType_t * const pxHigherPriorityTaskWoken )</pre>
 | 
			
		||||
*
 | 
			
		||||
* INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this
 | 
			
		||||
* function to be available.
 | 
			
		||||
*
 | 
			
		||||
* A version of xTaskAbortDelay() that can be used from an interrupt service routine.
 | 
			
		||||
*
 | 
			
		||||
* A task will enter the Blocked state when it is waiting for an event.  The
 | 
			
		||||
* event it is waiting for can be a temporal event (waiting for a time), such
 | 
			
		||||
* as when vTaskDelay() is called, or an event on an object, such as when
 | 
			
		||||
* xQueueReceive() or ulTaskNotifyTake() is called.  If the handle of a task
 | 
			
		||||
* that is in the Blocked state is used in a call to xTaskAbortDelay() then the
 | 
			
		||||
* task will leave the Blocked state, and return from whichever function call
 | 
			
		||||
* placed the task into the Blocked state.
 | 
			
		||||
*
 | 
			
		||||
* @param xTask The handle of the task to remove from the Blocked state.
 | 
			
		||||
*
 | 
			
		||||
* @param pxHigherPriorityTaskWoken xTaskAbortDelayFromISR() will set
 | 
			
		||||
* *pxHigherPriorityTaskWoken to pdTRUE if a task was removed from the Blocked state,
 | 
			
		||||
* and the task that was removed from the Blocked state has a priority higher than the
 | 
			
		||||
* currently running task.  If xTaskAbortDelayFromISR() sets this value to pdTRUE then
 | 
			
		||||
* a context switch should be requested before the interrupt is exited.
 | 
			
		||||
*
 | 
			
		||||
* @return If the task referenced by xTask was not in the Blocked state then
 | 
			
		||||
* pdFAIL is returned.  Otherwise pdPASS is returned.
 | 
			
		||||
*
 | 
			
		||||
* \defgroup xTaskAbortDelay xTaskAbortDelayFromISR
 | 
			
		||||
* \ingroup TaskCtrl
 | 
			
		||||
*/
 | 
			
		||||
BaseType_t xTaskAbortDelayFromISR( TaskHandle_t xTask, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * task. h
 | 
			
		||||
 * <pre>UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );</pre>
 | 
			
		||||
@ -2201,6 +2234,24 @@ uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* task. h
 | 
			
		||||
* <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.
 | 
			
		||||
*
 | 
			
		||||
* Set ulBitsToClear to to 0xffffffff (UINT_MAX on 32-bit architectures) to clear
 | 
			
		||||
* the notification value to 0.  Set ulBitsToClear to 0 to query the task's
 | 
			
		||||
* notification value without clearing any bits.
 | 
			
		||||
*
 | 
			
		||||
* @return The value of the target task's notification value before the bits
 | 
			
		||||
* specified by ulBitsToClear were cleared.
 | 
			
		||||
* \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear
 | 
			
		||||
* \ingroup TaskNotifications
 | 
			
		||||
*/
 | 
			
		||||
uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * task.h
 | 
			
		||||
 * <pre>void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )</pre>
 | 
			
		||||
 | 
			
		||||
@ -586,6 +586,19 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
 | 
			
		||||
	uint32_t MPU_ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */
 | 
			
		||||
	{
 | 
			
		||||
	uint32_t ulReturn;
 | 
			
		||||
	BaseType_t xRunningPrivileged = xPortRaisePrivilege();
 | 
			
		||||
 | 
			
		||||
		ulReturn = ulTaskNotifyValueClear( xTask, ulBitsToClear );
 | 
			
		||||
		vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
		return ulReturn;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 | 
			
		||||
	QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -2626,7 +2626,7 @@ BaseType_t xYieldRequired = pdFALSE;
 | 
			
		||||
	relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */
 | 
			
		||||
	configASSERT( uxSchedulerSuspended == 0 );
 | 
			
		||||
 | 
			
		||||
	/* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occuring when
 | 
			
		||||
	/* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occurring when
 | 
			
		||||
	the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	xPendedTicks += xTicksToCatchUp;
 | 
			
		||||
@ -2636,6 +2636,91 @@ BaseType_t xYieldRequired = pdFALSE;
 | 
			
		||||
}
 | 
			
		||||
/*----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTaskAbortDelay == 1 )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xTaskAbortDelayFromISR( TaskHandle_t xTask, BaseType_t * const pxHigherPriorityTaskWoken )
 | 
			
		||||
	{
 | 
			
		||||
	TCB_t *pxTCB = xTask;
 | 
			
		||||
	BaseType_t xReturn;
 | 
			
		||||
	UBaseType_t uxSavedInterruptStatus;
 | 
			
		||||
 | 
			
		||||
		configASSERT( pxTCB );
 | 
			
		||||
 | 
			
		||||
		/* RTOS ports that support interrupt nesting have the concept of a maximum
 | 
			
		||||
		system call (or maximum API call) interrupt priority.  Interrupts that are
 | 
			
		||||
		above the maximum system call priority are kept permanently enabled, even
 | 
			
		||||
		when the RTOS kernel is in a critical section, but cannot make any calls to
 | 
			
		||||
		FreeRTOS API functions.  If configASSERT() is defined in FreeRTOSConfig.h
 | 
			
		||||
		then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 | 
			
		||||
		failure if a FreeRTOS API function is called from an interrupt that has been
 | 
			
		||||
		assigned a priority above the configured maximum system call priority.
 | 
			
		||||
		Only FreeRTOS functions that end in FromISR can be called from interrupts
 | 
			
		||||
		that have been assigned a priority at or (logically) below the maximum
 | 
			
		||||
		system call	interrupt priority.  FreeRTOS maintains a separate interrupt
 | 
			
		||||
		safe API to ensure interrupt entry is as fast and as simple as possible.
 | 
			
		||||
		More information (albeit Cortex-M specific) is provided on the following
 | 
			
		||||
		link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 | 
			
		||||
		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 | 
			
		||||
 | 
			
		||||
		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
		{
 | 
			
		||||
			/* A task can only be prematurely removed from the Blocked state if
 | 
			
		||||
			it is actually in the Blocked state. */
 | 
			
		||||
			if( eTaskGetState( xTask ) == eBlocked )
 | 
			
		||||
			{
 | 
			
		||||
				xReturn = pdPASS;
 | 
			
		||||
 | 
			
		||||
				/* Remove the reference to the task from the blocked list.  A higher
 | 
			
		||||
				priority interrupt won't touch the xStateListItem because of the
 | 
			
		||||
				critical section. */
 | 
			
		||||
				( void ) uxListRemove( &( pxTCB->xStateListItem ) );
 | 
			
		||||
 | 
			
		||||
				/* Is the task waiting on an event also?  If so remove it from
 | 
			
		||||
				the event list too. */
 | 
			
		||||
				if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
 | 
			
		||||
				{
 | 
			
		||||
					( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
					/* This lets the task know it was forcibly removed from the
 | 
			
		||||
					blocked state so it should not re-evaluate its block time and
 | 
			
		||||
					then block again. */
 | 
			
		||||
					pxTCB->ucDelayAborted = pdTRUE;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* Place the unblocked task into the appropriate ready list. */
 | 
			
		||||
				prvAddTaskToReadyList( pxTCB );
 | 
			
		||||
 | 
			
		||||
				if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
 | 
			
		||||
				{
 | 
			
		||||
					if( pxHigherPriorityTaskWoken != NULL )
 | 
			
		||||
					{
 | 
			
		||||
						/* Pend the yield to be performed when the scheduler
 | 
			
		||||
						is unsuspended. */
 | 
			
		||||
						*pxHigherPriorityTaskWoken = pdTRUE;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				xReturn = pdFAIL;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTaskAbortDelay == 1 )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xTaskAbortDelay( TaskHandle_t xTask )
 | 
			
		||||
@ -2667,6 +2752,10 @@ BaseType_t xYieldRequired = pdFALSE;
 | 
			
		||||
					if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
 | 
			
		||||
					{
 | 
			
		||||
						( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
						/* This lets the task know it was forcibly removed from the
 | 
			
		||||
						blocked state so it should not re-evaluate its block time and
 | 
			
		||||
						then block again. */
 | 
			
		||||
						pxTCB->ucDelayAborted = pdTRUE;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
@ -5096,7 +5185,6 @@ TickType_t uxReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_TASK_NOTIFICATIONS */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
 | 
			
		||||
@ -5130,6 +5218,32 @@ TickType_t uxReturn;
 | 
			
		||||
#endif /* configUSE_TASK_NOTIFICATIONS */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
 | 
			
		||||
 | 
			
		||||
	uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear )
 | 
			
		||||
	{
 | 
			
		||||
	TCB_t *pxTCB;
 | 
			
		||||
	uint32_t ulReturn;
 | 
			
		||||
 | 
			
		||||
		/* If null is passed in here then it is the calling task that is having
 | 
			
		||||
		its notification state cleared. */
 | 
			
		||||
		pxTCB = prvGetTCBFromHandle( xTask );
 | 
			
		||||
 | 
			
		||||
		taskENTER_CRITICAL();
 | 
			
		||||
		{
 | 
			
		||||
			/* Return the notification as it was before the bits were cleared,
 | 
			
		||||
			then clear the bit mask. */
 | 
			
		||||
			ulReturn = pxCurrentTCB->ulNotifiedValue;
 | 
			
		||||
			pxTCB->ulNotifiedValue &= ~ulBitsToClear;
 | 
			
		||||
		}
 | 
			
		||||
		taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
		return ulReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_TASK_NOTIFICATIONS */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
 | 
			
		||||
 | 
			
		||||
	uint32_t ulTaskGetIdleRunTimeCounter( void )
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user