mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
Add xQueueOverwrite() and a common demo task to demonstrate its use.
Update MSVC Win32 demo to include the xQueueOverwrite() common demo tasks.
This commit is contained in:
parent
59f75a12f6
commit
671949ad78
8 changed files with 491 additions and 74 deletions
|
@ -109,8 +109,9 @@ typedef void * xQueueSetHandle;
|
|||
typedef void * xQueueSetMemberHandle;
|
||||
|
||||
/* For internal use only. */
|
||||
#define queueSEND_TO_BACK ( 0 )
|
||||
#define queueSEND_TO_FRONT ( 1 )
|
||||
#define queueSEND_TO_BACK ( 0 )
|
||||
#define queueSEND_TO_FRONT ( 1 )
|
||||
#define queueOVERWRITE ( 2 )
|
||||
|
||||
/* For internal use only. These definitions *must* match those in queue.c. */
|
||||
#define queueQUEUE_TYPE_BASE ( 0U )
|
||||
|
@ -426,6 +427,88 @@ typedef void * xQueueSetMemberHandle;
|
|||
*/
|
||||
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
portBASE_TYPE xQueueOverwrite(
|
||||
xQueueHandle xQueue,
|
||||
const void * pvItemToQueue,
|
||||
);
|
||||
* </pre>
|
||||
*
|
||||
* Only for use with queues that can hold a single item - so the queue is either
|
||||
* empty or full.
|
||||
*
|
||||
* Post an item on a queue. If the queue is already full then overwrite the
|
||||
* value held in the queue. The item is queued by copy, not by reference.
|
||||
* This function must not be called from an interrupt service routine.
|
||||
* See xQueueOverwriteFromISR () for an alternative which may be used in an ISR.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and
|
||||
* therefore has the same return values as xQueueSendToFront(). However, as
|
||||
* xQueueOverwrite() will write to the queue even when the queue is full pdPASS
|
||||
* will be returned in all cases (errQUEUE_FULL will never be returned).
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
|
||||
void vFunction( void *pvParameters )
|
||||
{
|
||||
xQueueHandle xQueue;
|
||||
unsigned long ulVarToSend, ulValReceived;
|
||||
|
||||
// Create a queue to hold one unsigned long value. It is strongly
|
||||
// recommended *not* to use xQueueOverwrite() on queues that can
|
||||
// contain more than one value, and doing so will trigger an assertion
|
||||
// if configASSERT() is defined.
|
||||
xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
|
||||
|
||||
// Write the value 10 to the queue using xQueueOverwrite().
|
||||
ulVarToSend = 10;
|
||||
xQueueOverwrite( xQueue, &ulVarToSend );
|
||||
|
||||
// Peeking the queue should now return 10, but leave the value 10 in
|
||||
// the queue. A block time of zero is used as it is known that the
|
||||
// queue holds a value.
|
||||
ulValReceived = 0;
|
||||
xQueuePeek( xQueue, &ulValReceived, 0 );
|
||||
|
||||
if( ulValReceived != 10 )
|
||||
{
|
||||
// Error!
|
||||
}
|
||||
|
||||
// The queue is still full. Use xQueueOverwrite() to overwrite the
|
||||
// value held in the queue with 100.
|
||||
ulVarToSend = 100;
|
||||
xQueueOverwrite( xQueue, &ulVarToSend );
|
||||
|
||||
// This time read from the queue, leaving the queue empty once more.
|
||||
// A block time of 0 is used again.
|
||||
xQueueReceive( xQueue, &ulValReceived, 0 );
|
||||
|
||||
// The value read should be the last value written, even though the
|
||||
// queue was already full when the value was written.
|
||||
if( ulValReceived != 100 )
|
||||
{
|
||||
// Error!
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueOverwrite xQueueOverwrite
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
|
||||
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
|
|
|
@ -570,6 +570,7 @@ xQUEUE *pxQueue;
|
|||
pxQueue = ( xQUEUE * ) xQueue;
|
||||
configASSERT( pxQueue );
|
||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
||||
|
||||
/* This function relaxes the coding standard somewhat to allow return
|
||||
statements within the function itself. This is done in the interest
|
||||
|
@ -578,9 +579,11 @@ xQUEUE *pxQueue;
|
|||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Is there room on the queue now? To be running we must be
|
||||
the highest priority task wanting to access the queue. */
|
||||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||
/* Is there room on the queue now? The running task must be
|
||||
the highest priority task wanting to access the queue. If
|
||||
the head item in the queue is to be overwritten then it does
|
||||
not matter if the queue is full. */
|
||||
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
|
||||
{
|
||||
traceQUEUE_SEND( pxQueue );
|
||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
@ -1046,7 +1049,8 @@ xQUEUE *pxQueue;
|
|||
the highest priority task wanting to access the queue. */
|
||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||
{
|
||||
/* Remember our read position in case we are just peeking. */
|
||||
/* Remember the read position in case the queue is only being
|
||||
peeked. */
|
||||
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
|
||||
|
||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||
|
@ -1320,7 +1324,7 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
|
|||
pxQueue->pxMutexHolder = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* configUSE_MUTEXES */
|
||||
}
|
||||
else if( xPosition == queueSEND_TO_BACK )
|
||||
{
|
||||
|
@ -1339,6 +1343,18 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
|
|||
{
|
||||
pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
|
||||
}
|
||||
|
||||
if( xPosition == queueOVERWRITE )
|
||||
{
|
||||
if( pxQueue->uxMessagesWaiting > 0 )
|
||||
{
|
||||
/* An item is not being added but overwritten, so subtract
|
||||
one from the recorded number of items in the queue so when
|
||||
one is added again below the number of recorded items remains
|
||||
correct. */
|
||||
--( pxQueue->uxMessagesWaiting );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++( pxQueue->uxMessagesWaiting );
|
||||
|
|
|
@ -115,7 +115,7 @@ typedef struct tskTaskControlBlock
|
|||
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
|
||||
#endif
|
||||
|
||||
xListItem xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
|
||||
xListItem xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
|
||||
xListItem xEventListItem; /*< Used to reference a task from an event list. */
|
||||
unsigned portBASE_TYPE uxPriority; /*< The priority of the task. 0 is the lowest priority. */
|
||||
portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */
|
||||
|
@ -149,8 +149,11 @@ typedef struct tskTaskControlBlock
|
|||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||
/* Allocate a Newlib reent structure that is specific to this task.
|
||||
Note Newlib support has been included by popular demand, but is not
|
||||
used by the FreeRTOS maintainers themselves, and therefore receives
|
||||
less rigorous testing than the rest of the FreeRTOS code. */
|
||||
used by the FreeRTOS maintainers themselves. FreeRTOS is not
|
||||
responsible for resulting newlib operation. User must be familiar with
|
||||
newlib and must provide system-wide implementations of the necessary
|
||||
stubs. Be warned that (at the time of writing) the current newlib design
|
||||
implements a system-wide malloc() that must be provided with locks. */
|
||||
struct _reent xNewLib_reent;
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue