mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
Added xQueueSendToBack, xQueueSendToFront, xQueuePeek and xSemaphoreCreateMutex - along with GenQTest.c to demonstrate their usage.
This commit is contained in:
parent
ac14fdb0b7
commit
60338bd872
18 changed files with 2005 additions and 367 deletions
259
Source/queue.c
259
Source/queue.c
|
@ -70,9 +70,9 @@ Changes from V4.1.2:
|
|||
|
||||
Changes from V4.1.3:
|
||||
|
||||
+ Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)
|
||||
case whereby a task unblocking due to a temporal event can remove/send an
|
||||
item from/to a queue when a higher priority task is still blocked on the
|
||||
+ Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)
|
||||
case whereby a task unblocking due to a temporal event can remove/send an
|
||||
item from/to a queue when a higher priority task is still blocked on the
|
||||
queue. This modification is a result of the SafeRTOS testing.
|
||||
*/
|
||||
|
||||
|
@ -90,6 +90,15 @@ Changes from V4.1.3:
|
|||
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
|
||||
#define queueERRONEOUS_UNBLOCK ( -1 )
|
||||
|
||||
/* For internal use only. */
|
||||
#define queueSEND_TO_BACK ( 0 )
|
||||
#define queueSEND_TO_FRONT ( 1 )
|
||||
|
||||
/* Effectively make a union out of the xQUEUE structure. */
|
||||
#define pxMutexHolder pcTail
|
||||
#define uxQueueType pcHead
|
||||
#define queueQUEUE_IS_MUTEX NULL
|
||||
|
||||
/*
|
||||
* Definition of the queue used by the scheduler.
|
||||
* Items are queued by copy, not reference.
|
||||
|
@ -109,8 +118,8 @@ typedef struct QueueDefinition
|
|||
unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
|
||||
unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
|
||||
|
||||
signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
} xQUEUE;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -127,12 +136,13 @@ typedef xQUEUE * xQueueHandle;
|
|||
* functions are documented in the API header file.
|
||||
*/
|
||||
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
|
||||
signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait );
|
||||
signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
|
||||
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle pxQueue );
|
||||
void vQueueDelete( xQueueHandle xQueue );
|
||||
signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken );
|
||||
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
|
||||
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition );
|
||||
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
|
||||
xQueueHandle xQueueCreateMutex( void );
|
||||
|
||||
#if configUSE_CO_ROUTINES == 1
|
||||
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
|
||||
|
@ -166,20 +176,15 @@ static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue );
|
|||
static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue );
|
||||
|
||||
/*
|
||||
* Macro that copies an item into the queue. This is done by copying the item
|
||||
* byte for byte, not by reference. Updates the queue state to ensure it's
|
||||
* integrity after the copy.
|
||||
* Copies an item into the queue, either at the front of the queue or the
|
||||
* back of the queue.
|
||||
*/
|
||||
#define prvCopyQueueData( pxQueue, pvItemToQueue ) \
|
||||
{ \
|
||||
memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); \
|
||||
++( pxQueue->uxMessagesWaiting ); \
|
||||
pxQueue->pcWriteTo += pxQueue->uxItemSize; \
|
||||
if( pxQueue->pcWriteTo >= pxQueue->pcTail ) \
|
||||
{ \
|
||||
pxQueue->pcWriteTo = pxQueue->pcHead; \
|
||||
} \
|
||||
}
|
||||
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition );
|
||||
|
||||
/*
|
||||
* Copies an item out of a queue.
|
||||
*/
|
||||
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -248,7 +253,49 @@ size_t xQueueSizeInBytes;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
|
||||
xQueueHandle xQueueCreateMutex( void )
|
||||
{
|
||||
xQUEUE *pxNewQueue;
|
||||
|
||||
/* Allocate the new queue structure. */
|
||||
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
|
||||
if( pxNewQueue != NULL )
|
||||
{
|
||||
/* Information required for priority inheritance. */
|
||||
pxNewQueue->pxMutexHolder = NULL;
|
||||
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
|
||||
|
||||
/* Queues used as a mutex no data is actually copied into or out
|
||||
of the queue. */
|
||||
pxNewQueue->pcWriteTo = NULL;
|
||||
pxNewQueue->pcReadFrom = NULL;
|
||||
|
||||
/* Each mutex has a length of 1 (like a binary semaphore) and
|
||||
an item size of 0 as nothing is actually copied into or out
|
||||
of the mutex. */
|
||||
pxNewQueue->uxMessagesWaiting = 0;
|
||||
pxNewQueue->uxLength = 1;
|
||||
pxNewQueue->uxItemSize = 0;
|
||||
pxNewQueue->xRxLock = queueUNLOCKED;
|
||||
pxNewQueue->xTxLock = queueUNLOCKED;
|
||||
|
||||
/* Ensure the event queues start with the correct state. */
|
||||
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
|
||||
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
|
||||
|
||||
/* Start with the semaphore in the expected state. */
|
||||
xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );
|
||||
}
|
||||
|
||||
return pxNewQueue;
|
||||
}
|
||||
|
||||
#endif /* configUSE_MUTEXES */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||
{
|
||||
signed portBASE_TYPE xReturn = pdPASS;
|
||||
xTimeOutType xTimeOut;
|
||||
|
@ -285,15 +332,15 @@ xTimeOutType xTimeOut;
|
|||
queue being modified here. Places where the event list is modified
|
||||
include:
|
||||
|
||||
+ xQueueSendFromISR(). This checks the lock on the queue to see if
|
||||
it has access. If the queue is locked then the Tx lock count is
|
||||
+ xQueueGenericSendFromISR(). This checks the lock on the queue to see
|
||||
if it has access. If the queue is locked then the Tx lock count is
|
||||
incremented to signify that a task waiting for data can be made ready
|
||||
once the queue lock is removed. If the queue is not locked then
|
||||
a task can be moved from the event list, but will not be removed
|
||||
from the delayed list or placed in the ready list until the scheduler
|
||||
is unlocked.
|
||||
|
||||
+ xQueueReceiveFromISR(). As per xQueueSendFromISR().
|
||||
+ xQueueReceiveFromISR(). As per xQueueGenericSendFromISR().
|
||||
*/
|
||||
|
||||
/* If the queue is already full we may have to block. */
|
||||
|
@ -390,7 +437,7 @@ xTimeOutType xTimeOut;
|
|||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||
{
|
||||
/* There is room in the queue, copy the data into the queue. */
|
||||
prvCopyQueueData( pxQueue, pvItemToQueue );
|
||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
xReturn = pdPASS;
|
||||
|
||||
/* Update the TxLock count so prvUnlockQueue knows to check for
|
||||
|
@ -425,16 +472,16 @@ xTimeOutType xTimeOut;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken )
|
||||
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition )
|
||||
{
|
||||
/* Similar to xQueueSend, except we don't block if there is no room in the
|
||||
queue. Also we don't directly wake a task that was blocked on a queue
|
||||
read, instead we return a flag to say whether a context switch is required
|
||||
or not (i.e. has a task with a higher priority than us been woken by this
|
||||
post). */
|
||||
/* Similar to xQueueGenericSend, except we don't block if there is no room
|
||||
in the queue. Also we don't directly wake a task that was blocked on a
|
||||
queue read, instead we return a flag to say whether a context switch is
|
||||
required or not (i.e. has a task with a higher priority than us been woken
|
||||
by this post). */
|
||||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||
{
|
||||
prvCopyQueueData( pxQueue, pvItemToQueue );
|
||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
||||
/* If the queue is locked we do not alter the event list. This will
|
||||
be done when the queue is unlocked later. */
|
||||
|
@ -467,13 +514,14 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
|
||||
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
|
||||
{
|
||||
signed portBASE_TYPE xReturn = pdTRUE;
|
||||
xTimeOutType xTimeOut;
|
||||
signed portCHAR *pcOriginalReadPosition;
|
||||
|
||||
/* This function is very similar to xQueueSend(). See comments within
|
||||
xQueueSend() for a more detailed explanation.
|
||||
/* This function is very similar to xQueueGenericSend(). See comments
|
||||
within xQueueGenericSend() for a more detailed explanation.
|
||||
|
||||
Make sure other tasks do not access the queue. */
|
||||
vTaskSuspendAll();
|
||||
|
@ -493,6 +541,17 @@ xTimeOutType xTimeOut;
|
|||
leave with nothing? */
|
||||
if( xTicksToWait > ( portTickType ) 0 )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
portENTER_CRITICAL();
|
||||
vTaskPriorityInherit( ( xTaskHandle * const ) pxQueue->pxMutexHolder );
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
|
@ -522,18 +581,39 @@ xTimeOutType xTimeOut;
|
|||
{
|
||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||
{
|
||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
||||
/* Remember our read position in case we are just peeking. */
|
||||
pcOriginalReadPosition = pxQueue->pcReadFrom;
|
||||
|
||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||
|
||||
if( xJustPeeking == pdFALSE )
|
||||
{
|
||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
||||
/* We are actually removing data. */
|
||||
--( pxQueue->uxMessagesWaiting );
|
||||
|
||||
/* Increment the lock count so prvUnlockQueue knows to check for
|
||||
tasks waiting for space to become available on the queue. */
|
||||
++( pxQueue->xRxLock );
|
||||
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
/* Record the information required to implement
|
||||
priority inheritance should it become necessary. */
|
||||
pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
--( pxQueue->uxMessagesWaiting );
|
||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
||||
|
||||
/* Increment the lock count so prvUnlockQueue knows to check for
|
||||
tasks waiting for space to become available on the queue. */
|
||||
++( pxQueue->xRxLock );
|
||||
xReturn = pdPASS;
|
||||
else
|
||||
{
|
||||
/* We are not removing the data, so reset our read
|
||||
pointer. */
|
||||
pxQueue->pcReadFrom = pcOriginalReadPosition;
|
||||
}
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -563,21 +643,15 @@ xTimeOutType xTimeOut;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken )
|
||||
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )
|
||||
{
|
||||
signed portBASE_TYPE xReturn;
|
||||
|
||||
/* We cannot block from an ISR, so check there is data available. */
|
||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||
{
|
||||
/* Copy the data from the queue. */
|
||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
||||
{
|
||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
||||
}
|
||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||
--( pxQueue->uxMessagesWaiting );
|
||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
||||
|
||||
/* If the queue is locked we will not modify the event list. Instead
|
||||
we update the lock count so the task that unlocks the queue will know
|
||||
|
@ -636,6 +710,57 @@ void vQueueDelete( xQueueHandle pxQueue )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
|
||||
{
|
||||
if( pxQueue->uxItemSize == 0 )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
/* The mutex is no longer being held. */
|
||||
vTaskPriorityDisinherit( ( xTaskHandle * const ) pxQueue->pxMutexHolder );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if( xPosition == queueSEND_TO_BACK )
|
||||
{
|
||||
memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
|
||||
pxQueue->pcWriteTo += pxQueue->uxItemSize;
|
||||
if( pxQueue->pcWriteTo >= pxQueue->pcTail )
|
||||
{
|
||||
pxQueue->pcWriteTo = pxQueue->pcHead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
|
||||
pxQueue->pcReadFrom -= pxQueue->uxItemSize;
|
||||
if( pxQueue->pcReadFrom < pxQueue->pcHead )
|
||||
{
|
||||
pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
|
||||
}
|
||||
}
|
||||
|
||||
++( pxQueue->uxMessagesWaiting );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
|
||||
{
|
||||
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
||||
{
|
||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
||||
}
|
||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUnlockQueue( xQueueHandle pxQueue )
|
||||
{
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
|
||||
|
@ -722,7 +847,7 @@ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQue
|
|||
signed portBASE_TYPE xReturn;
|
||||
|
||||
/* If the queue is already full we may have to block. A critical section
|
||||
is required to prevent an interrupt removing something from the queue
|
||||
is required to prevent an interrupt removing something from the queue
|
||||
between the check to see if the queue is full and blocking on the queue. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
|
@ -754,19 +879,19 @@ signed portBASE_TYPE xReturn;
|
|||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||
{
|
||||
/* There is room in the queue, copy the data into the queue. */
|
||||
prvCopyQueueData( pxQueue, pvItemToQueue );
|
||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
|
||||
xReturn = pdPASS;
|
||||
|
||||
/* Were any co-routines waiting for data to become available? */
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
|
||||
{
|
||||
/* In this instance the co-routine could be placed directly
|
||||
into the ready list as we are within a critical section.
|
||||
Instead the same pending ready list mechansim is used as if
|
||||
/* In this instance the co-routine could be placed directly
|
||||
into the ready list as we are within a critical section.
|
||||
Instead the same pending ready list mechanism is used as if
|
||||
the event were caused from within an interrupt. */
|
||||
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
/* The co-routine waiting has a higher priority so record
|
||||
/* The co-routine waiting has a higher priority so record
|
||||
that a yield might be appropriate. */
|
||||
xReturn = errQUEUE_YIELD;
|
||||
}
|
||||
|
@ -790,7 +915,7 @@ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, port
|
|||
signed portBASE_TYPE xReturn;
|
||||
|
||||
/* If the queue is already empty we may have to block. A critical section
|
||||
is required to prevent an interrupt adding something to the queue
|
||||
is required to prevent an interrupt adding something to the queue
|
||||
between the check to see if the queue is empty and blocking on the queue. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
|
@ -835,9 +960,9 @@ signed portBASE_TYPE xReturn;
|
|||
/* Were any co-routines waiting for space to become available? */
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
|
||||
{
|
||||
/* In this instance the co-routine could be placed directly
|
||||
into the ready list as we are within a critical section.
|
||||
Instead the same pending ready list mechansim is used as if
|
||||
/* In this instance the co-routine could be placed directly
|
||||
into the ready list as we are within a critical section.
|
||||
Instead the same pending ready list mechanism is used as if
|
||||
the event were caused from within an interrupt. */
|
||||
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
|
@ -866,9 +991,9 @@ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvIt
|
|||
exit without doing anything. */
|
||||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||
{
|
||||
prvCopyQueueData( pxQueue, pvItemToQueue );
|
||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
|
||||
|
||||
/* We only want to wake one co-routine per ISR, so check that a
|
||||
/* We only want to wake one co-routine per ISR, so check that a
|
||||
co-routine has not already been woken. */
|
||||
if( !xCoRoutinePreviouslyWoken )
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue