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:
Richard Barry 2013-06-27 09:21:43 +00:00
parent 59f75a12f6
commit 671949ad78
8 changed files with 491 additions and 74 deletions

View file

@ -0,0 +1,197 @@
/*
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. You should have received a copy of the GNU General Public License
and the FreeRTOS license exception along with FreeRTOS; if not it can be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new
fully thread aware and reentrant UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support,
indemnification and middleware, under the OpenRTOS brand.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
*/
/*
* Basic task to demonstrate the xQueueOverwrite() function. See the comments
* in the function itself.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo program include files. */
#include "QueueOverwrite.h"
/* A block time of 0 just means "don't block". */
#define qoDONT_BLOCK 0
/* Number of times to overwrite the value in the queue. */
#define qoLOOPS 5
/* The task that uses the queue. */
static void prvQueueOverwriteTask( void *pvParameters );
/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided
prvQueueOverwriteTask() has not found any errors. */
static unsigned long ulLoopCounter = 0;
/*-----------------------------------------------------------*/
void vStartQueueOverwriteTask( unsigned portBASE_TYPE uxPriority )
{
/* Create the test task. */
xTaskCreate( prvQueueOverwriteTask, ( signed char * ) "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );
}
/*-----------------------------------------------------------*/
static void prvQueueOverwriteTask( void *pvParameters )
{
xQueueHandle xQueue;
const unsigned portBASE_TYPE uxQueueLength = 1;
unsigned long ulValue, ulStatus = pdPASS, x;
/* The parameter is not used. */
( void ) pvParameters;
/* Create the queue. xQueueOverwrite() should only be used on queues that
have a length of 1. */
xQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );
configASSERT( xQueue );
for( ;; )
{
/* The queue is empty. Writing to the queue then reading from the queue
should return the item written. */
ulValue = 10;
xQueueOverwrite( xQueue, &ulValue );
ulValue = 0;
xQueueReceive( xQueue, &ulValue, qoDONT_BLOCK );
if( ulValue != 10 )
{
ulStatus = pdFAIL;
}
/* Now try writing to the queue several times. Each time the value
in the queue should get overwritten. */
for( x = 0; x < qoLOOPS; x++ )
{
/* Write to the queue. */
xQueueOverwrite( xQueue, &x );
/* Check the value in the queue is that written, even though the
queue was not necessarily empty. */
xQueuePeek( xQueue, &ulValue, qoDONT_BLOCK );
if( ulValue != x )
{
ulStatus = pdFAIL;
}
/* There should always be one item in the queue. */
if( uxQueueMessagesWaiting( xQueue ) != uxQueueLength )
{
ulStatus = pdFAIL;
}
}
/* Empty the queue again. */
xQueueReceive( xQueue, &ulValue, qoDONT_BLOCK );
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
ulStatus = pdFAIL;
}
if( ulStatus != pdFAIL )
{
/* Increment a counter to show this task is still running without
error. */
ulLoopCounter++;
}
}
}
/*-----------------------------------------------------------*/
portBASE_TYPE xIsQueueOverwriteTaskStillRunning( void )
{
portBASE_TYPE xReturn;
if( ulLoopCounter > 0 )
{
xReturn = pdPASS;
}
else
{
/* The task has either stalled of discovered an error. */
xReturn = pdFAIL;
}
ulLoopCounter = 0;
return xReturn;
}

View file

@ -0,0 +1,83 @@
/*
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. You should have received a copy of the GNU General Public License
and the FreeRTOS license exception along with FreeRTOS; if not it can be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., contact details for whom are available
on the FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new
fully thread aware and reentrant UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support,
indemnification and middleware, under the OpenRTOS brand.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
*/
#ifndef QUEUE_OVERWRITE_H
#define QUEUE_OVERWRITE_H
void vStartQueueOverwriteTask( unsigned portBASE_TYPE uxPriority );
portBASE_TYPE xIsQueueOverwriteTaskStillRunning( void );
#endif /* QUEUE_OVERWRITE_H */

View file

@ -143,6 +143,7 @@
<ClCompile Include="..\Common\Minimal\integer.c" />
<ClCompile Include="..\Common\Minimal\PollQ.c" />
<ClCompile Include="..\Common\Minimal\QPeek.c" />
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c" />
<ClCompile Include="..\Common\Minimal\QueueSet.c" />
<ClCompile Include="..\Common\Minimal\semtest.c" />
<ClCompile Include="..\Common\Minimal\timerdemo.c" />

View file

@ -121,6 +121,9 @@
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcHardwarePort.c">
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
</ClCompile>
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c">
<Filter>Demo App Source\Common Demo Tasks</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FreeRTOSConfig.h">

View file

@ -132,6 +132,7 @@
#include "death.h"
#include "dynamic.h"
#include "QueueSet.h"
#include "QueueOverwrite.h"
/* Priorities at which the tasks are created. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
@ -144,6 +145,7 @@
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
#define mainTIMER_TEST_PERIOD ( 50 )
@ -160,6 +162,12 @@ static void prvTestTask( void *pvParameters );
*/
static void prvSaveTraceFile( void );
/*
* Called from the idle task hook function to demonstrate a few utility
* functions that are not demonstrated by any of the standard demo tasks.
*/
static void prvDemonstrateTaskStateAndHandleGetFunctions( void );
/*-----------------------------------------------------------*/
/* The variable into which error messages are latched. */
@ -200,6 +208,7 @@ int main( void )
vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks();
vStartQueueSetTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation. This then allows them to
@ -294,6 +303,10 @@ const portTickType xCycleFrequency = 1000 / portTICK_RATE_MS;
{
pcStatusMessage = "Error: Queue set\r\n";
}
else if( xIsQueueOverwriteTaskStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue overwrite\r\n";
}
/* This is the only task that uses stdout so its ok to call printf()
directly. */
@ -323,9 +336,7 @@ const unsigned long ulMSToSleep = 5;
void vApplicationIdleHook( void )
{
const unsigned long ulMSToSleep = 15;
xTaskHandle xIdleTaskHandle, xTimerTaskHandle, xTestTask;
signed char *pcTaskName;
const unsigned char ucConstQueueNumber = 0xaaU, ucConstTaskNumber = 0x55U;
const unsigned char ucConstQueueNumber = 0xaaU;
void *pvAllocated;
static portBASE_TYPE xTraceRunning = pdTRUE;
@ -341,39 +352,9 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
tasks waiting to be terminated by the idle task. */
Sleep( ulMSToSleep );
/* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and
xTaskGetIdleTaskHandle() functions. Also try using the function that sets
the task number. */
xIdleTaskHandle = xTaskGetIdleTaskHandle();
xTimerTaskHandle = xTimerGetTimerDaemonTaskHandle();
vTaskSetTaskNumber( xIdleTaskHandle, ( unsigned long ) ucConstTaskNumber );
configASSERT( uxTaskGetTaskNumber( xIdleTaskHandle ) == ucConstTaskNumber );
/* This is the idle hook, so the current task handle should equal the
returned idle task handle. */
if( xTaskGetCurrentTaskHandle() != xIdleTaskHandle )
{
pcStatusMessage = "Error: Returned idle task handle was incorrect";
}
/* Check the timer task handle was returned correctly. */
pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );
if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )
{
pcStatusMessage = "Error: Returned timer task handle was incorrect";
}
/* This task is running, make sure its state is returned as running. */
if( eTaskStateGet( xIdleTaskHandle ) != eRunning )
{
pcStatusMessage = "Error: Returned idle task state was incorrect";
}
/* If this task is running, then the timer task must be blocked. */
if( eTaskStateGet( xTimerTaskHandle ) != eBlocked )
{
pcStatusMessage = "Error: Returned timer task state was incorrect";
}
/* Demonstrate a few utility functions that are not demonstrated by any of
the standard demo tasks. */
prvDemonstrateTaskStateAndHandleGetFunctions();
/* If xMutexToDelete has not already been deleted, then delete it now.
This is done purely to demonstrate the use of, and test, the
@ -393,34 +374,6 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
configASSERT( ucQueueGetQueueType( xMutexToDelete ) == queueQUEUE_TYPE_MUTEX );
vSemaphoreDelete( xMutexToDelete );
xMutexToDelete = NULL;
/* Other tests that should only be performed once follow. The test task
is not created on each iteration because to do so would cause the death
task to report an error (too many tasks running). */
/* Create a test task to use to test other eTaskStateGet() return values. */
if( xTaskCreate( prvTestTask, "Test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xTestTask ) == pdPASS )
{
/* If this task is running, the test task must be in the ready state. */
if( eTaskStateGet( xTestTask ) != eReady )
{
pcStatusMessage = "Error: Returned test task state was incorrect 1";
}
/* Now suspend the test task and check its state is reported correctly. */
vTaskSuspend( xTestTask );
if( eTaskStateGet( xTestTask ) != eSuspended )
{
pcStatusMessage = "Error: Returned test task state was incorrect 2";
}
/* Now delete the task and check its state is reported correctly. */
vTaskDelete( xTestTask );
if( eTaskStateGet( xTestTask ) != eDeleted )
{
pcStatusMessage = "Error: Returned test task state was incorrect 3";
}
}
}
/* Exercise heap_4 a bit. The malloc failed hook will trap failed
@ -499,3 +452,81 @@ FILE* pxOutputFile;
printf( "\r\nFailed to create trace dump file\r\n" );
}
}
/*-----------------------------------------------------------*/
static void prvDemonstrateTaskStateAndHandleGetFunctions( void )
{
xTaskHandle xIdleTaskHandle, xTimerTaskHandle;
const unsigned char ucConstTaskNumber = 0x55U;
signed char *pcTaskName;
static portBASE_TYPE xPerformedOneShotTests = pdFALSE;
xTaskHandle xTestTask;
/* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and
xTaskGetIdleTaskHandle() functions. Also try using the function that sets
the task number. */
xIdleTaskHandle = xTaskGetIdleTaskHandle();
xTimerTaskHandle = xTimerGetTimerDaemonTaskHandle();
vTaskSetTaskNumber( xIdleTaskHandle, ( unsigned long ) ucConstTaskNumber );
configASSERT( uxTaskGetTaskNumber( xIdleTaskHandle ) == ucConstTaskNumber );
/* This is the idle hook, so the current task handle should equal the
returned idle task handle. */
if( xTaskGetCurrentTaskHandle() != xIdleTaskHandle )
{
pcStatusMessage = "Error: Returned idle task handle was incorrect";
}
/* Check the timer task handle was returned correctly. */
pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );
if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )
{
pcStatusMessage = "Error: Returned timer task handle was incorrect";
}
/* This task is running, make sure it's state is returned as running. */
if( eTaskStateGet( xIdleTaskHandle ) != eRunning )
{
pcStatusMessage = "Error: Returned idle task state was incorrect";
}
/* If this task is running, then the timer task must be blocked. */
if( eTaskStateGet( xTimerTaskHandle ) != eBlocked )
{
pcStatusMessage = "Error: Returned timer task state was incorrect";
}
/* Other tests that should only be performed once follow. The test task
is not created on each iteration because to do so would cause the death
task to report an error (too many tasks running). */
if( xPerformedOneShotTests == pdFALSE )
{
/* Don't run this part of the test again. */
xPerformedOneShotTests = pdTRUE;
/* Create a test task to use to test other eTaskStateGet() return values. */
if( xTaskCreate( prvTestTask, "Test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xTestTask ) == pdPASS )
{
/* If this task is running, the test task must be in the ready state. */
if( eTaskStateGet( xTestTask ) != eReady )
{
pcStatusMessage = "Error: Returned test task state was incorrect 1";
}
/* Now suspend the test task and check its state is reported correctly. */
vTaskSuspend( xTestTask );
if( eTaskStateGet( xTestTask ) != eSuspended )
{
pcStatusMessage = "Error: Returned test task state was incorrect 2";
}
/* Now delete the task and check its state is reported correctly. */
vTaskDelete( xTestTask );
if( eTaskStateGet( xTestTask ) != eDeleted )
{
pcStatusMessage = "Error: Returned test task state was incorrect 3";
}
}
}
}

View file

@ -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

View file

@ -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 );

View file

@ -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