mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Continue working on queue set implementation and testing.
This commit is contained in:
parent
4e5090e061
commit
232a5b3433
|
@ -70,10 +70,13 @@
|
||||||
* Demonstrates the creation an use of queue sets.
|
* Demonstrates the creation an use of queue sets.
|
||||||
*
|
*
|
||||||
* A receive task creates a number of queues and adds them to a queue set before
|
* A receive task creates a number of queues and adds them to a queue set before
|
||||||
* blocking on a queue set receive. A transmit task repeatedly unblocks the
|
* blocking on the queue set receive. A transmit task and (optionally) an
|
||||||
* receive task by sending messages to the queues in a pseudo random order.
|
* interrupt repeatedly unblocks the receive task by sending messages to the
|
||||||
* The receive task removes the messages from the queues and flags an error if
|
* queues in a pseudo random order. The receive task removes the messages from
|
||||||
* the received message does not match that expected.
|
* the queues and flags an error if the received message does not match that
|
||||||
|
* expected. The task sends values in the range 0 to
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE to 0xffffffffUL;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel includes. */
|
/* Kernel includes. */
|
||||||
|
@ -94,6 +97,23 @@
|
||||||
#define queuesetSHORT_DELAY 200
|
#define queuesetSHORT_DELAY 200
|
||||||
#define queuesetDONT_BLOCK 0
|
#define queuesetDONT_BLOCK 0
|
||||||
|
|
||||||
|
/* Messages are sent in incrementing order from both a task and an interrupt.
|
||||||
|
The task sends values in the range 0 to 0xfffe, and the interrupt sends values
|
||||||
|
in the range of 0xffff to 0xffffffff; */
|
||||||
|
#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL
|
||||||
|
|
||||||
|
/* The priorities used in this demo. */
|
||||||
|
#define queuesetLOW_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define queuesetMEDIUM_PRIORITY ( queuesetLOW_PRIORITY + 1 )
|
||||||
|
#define queuesetHIGH_PRIORITY ( queuesetMEDIUM_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* For test purposes the priority of the sending task is changed after every
|
||||||
|
queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
|
||||||
|
#define queuesetPRIORITY_CHANGE_LOOPS 100UL
|
||||||
|
|
||||||
|
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
|
||||||
|
#define queuesetISR_TX_PERIOD ( 100UL )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The task that periodically sends to the queue set.
|
* The task that periodically sends to the queue set.
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +127,10 @@ static void prvQueueSetReceivingTask( void *pvParameters );
|
||||||
/* The queues that are added to the set. */
|
/* The queues that are added to the set. */
|
||||||
static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
|
||||||
|
/* Counts how many times each queue in the set is used to ensure all the
|
||||||
|
queues are used. */
|
||||||
|
static unsigned long ulQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
|
||||||
/* The handle of the queue set to which the queues are added. */
|
/* The handle of the queue set to which the queues are added. */
|
||||||
static xQueueSetHandle xQueueSet;
|
static xQueueSetHandle xQueueSet;
|
||||||
|
|
||||||
|
@ -115,24 +139,32 @@ it increments ulCycleCounter on each iteration.
|
||||||
xAreQueueSetTasksStillRunning() returns pdPASS if the value of
|
xAreQueueSetTasksStillRunning() returns pdPASS if the value of
|
||||||
ulCycleCounter has changed between consecutive calls, and pdFALSE if
|
ulCycleCounter has changed between consecutive calls, and pdFALSE if
|
||||||
ulCycleCounter has stopped incrementing (indicating an error condition). */
|
ulCycleCounter has stopped incrementing (indicating an error condition). */
|
||||||
volatile unsigned long ulCycleCounter = 0UL;
|
static volatile unsigned long ulCycleCounter = 0UL;
|
||||||
|
|
||||||
/* Set to pdFAIL if an error is detected by any queue set task.
|
/* Set to pdFAIL if an error is detected by any queue set task.
|
||||||
ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
|
ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
|
||||||
volatile portBASE_TYPE xQueueSetTasksStatus = pdPASS;
|
static volatile portBASE_TYPE xQueueSetTasksStatus = pdPASS;
|
||||||
|
|
||||||
|
/* Just a flag to let the function that writes to a queue from an ISR know that
|
||||||
|
the queues are setup and can be used. */
|
||||||
|
static volatile portBASE_TYPE xSetupComplete = pdFALSE;
|
||||||
|
|
||||||
|
/* The value sent to the queue from the ISR is file scope so the
|
||||||
|
xAreQueeuSetTasksStillRunning() function can check it is incrementing as
|
||||||
|
expected. */
|
||||||
|
static volatile unsigned long ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority )
|
void vStartQueueSetTasks( void )
|
||||||
{
|
{
|
||||||
xTaskHandle xQueueSetSendingTask;
|
xTaskHandle xQueueSetSendingTask;
|
||||||
|
|
||||||
/* Create the two queues. The handle of the sending task is passed into
|
/* Create the two queues. The handle of the sending task is passed into
|
||||||
the receiving task using the task parameter. The receiving task uses the
|
the receiving task using the task parameter. The receiving task uses the
|
||||||
handle to resume the sending task after it has created the queues. */
|
handle to resume the sending task after it has created the queues. */
|
||||||
xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xQueueSetSendingTask );
|
xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );
|
||||||
xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, uxPriority, NULL );
|
xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL );
|
||||||
|
|
||||||
/* It is important that the sending task does not attempt to write to a
|
/* It is important that the sending task does not attempt to write to a
|
||||||
queue before the queue has been created. It is therefore placed into the
|
queue before the queue has been created. It is therefore placed into the
|
||||||
|
@ -145,8 +177,9 @@ xTaskHandle xQueueSetSendingTask;
|
||||||
|
|
||||||
portBASE_TYPE xAreQueueSetTasksStillRunning( void )
|
portBASE_TYPE xAreQueueSetTasksStillRunning( void )
|
||||||
{
|
{
|
||||||
static unsigned long ulLastCycleCounter;
|
static unsigned long ulLastCycleCounter, ulLastISRTxValue = 0;
|
||||||
portBASE_TYPE xReturn;
|
static unsigned long ulLastQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
portBASE_TYPE xReturn = pdPASS, x;
|
||||||
|
|
||||||
if( ulLastCycleCounter == ulCycleCounter )
|
if( ulLastCycleCounter == ulCycleCounter )
|
||||||
{
|
{
|
||||||
|
@ -154,44 +187,180 @@ portBASE_TYPE xReturn;
|
||||||
tasks is stalled or an error has been detected. */
|
tasks is stalled or an error has been detected. */
|
||||||
xReturn = pdFAIL;
|
xReturn = pdFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ulLastCycleCounter = ulCycleCounter;
|
||||||
|
|
||||||
|
/* Ensure that all the queues in the set have been used. This ensures the
|
||||||
|
test is working as intended and guards against the rand() in the Tx task
|
||||||
|
missing some values. */
|
||||||
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
|
{
|
||||||
|
if( ulLastQueueUsedCounter[ x ] == ulQueueUsedCounter[ x ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastQueueUsedCounter[ x ] = ulQueueUsedCounter[ x ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the global status flag. */
|
||||||
|
if( xQueueSetTasksStatus != pdPASS )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the ISR is still sending values to the queues too. */
|
||||||
|
if( ulISRTxValue == ulLastISRTxValue )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xReturn = pdPASS;
|
ulLastISRTxValue = ulISRTxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vQueueSetWriteToQueueFromISR( void )
|
||||||
|
{
|
||||||
|
portBASE_TYPE x = 0;
|
||||||
|
static unsigned long ulCallCount = 0;
|
||||||
|
|
||||||
|
/* xSetupComplete is set to pdTRUE when the queues have been created and
|
||||||
|
are available for use. */
|
||||||
|
if( xSetupComplete == pdTRUE )
|
||||||
|
{
|
||||||
|
/* It is intended that this function is called from the tick hook
|
||||||
|
function, so each call is one tick period apart. */
|
||||||
|
ulCallCount++;
|
||||||
|
if( ulCallCount > queuesetISR_TX_PERIOD )
|
||||||
|
{
|
||||||
|
ulCallCount = 0;
|
||||||
|
|
||||||
|
/* Look for a queue that can be written to. */
|
||||||
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
|
{
|
||||||
|
if( xQueues[ x ] != NULL )
|
||||||
|
{
|
||||||
|
/* xQueues[ x ] can be written to. Send the next value. */
|
||||||
|
if( xQueueSendFromISR( xQueues[ x ], &ulISRTxValue, NULL ) == pdPASS )
|
||||||
|
{
|
||||||
|
ulISRTxValue++;
|
||||||
|
|
||||||
|
/* If the Tx value has wrapped then set it back to its
|
||||||
|
initial value. */
|
||||||
|
if( ulISRTxValue == 0UL )
|
||||||
|
{
|
||||||
|
ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvQueueSetSendingTask( void *pvParameters )
|
static void prvQueueSetSendingTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
unsigned long ulTxValue = 0;
|
unsigned long ulTaskTxValue = 0;
|
||||||
portBASE_TYPE xQueueToWriteTo;
|
portBASE_TYPE xQueueToWriteTo;
|
||||||
|
xQueueHandle xQueueInUse;
|
||||||
|
unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
|
||||||
|
|
||||||
/* Remove compiler warning about the unused parameter. */
|
/* Remove compiler warning about the unused parameter. */
|
||||||
( void ) pvParameters;
|
( void ) pvParameters;
|
||||||
|
|
||||||
srand( ( unsigned int ) &ulTxValue );
|
srand( ( unsigned int ) &ulTaskTxValue );
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
/* Generate the index for the queue to which a value is to be sent. */
|
/* Generate the index for the queue to which a value is to be sent. */
|
||||||
xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;
|
xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;
|
||||||
if( xQueueSendToBack( xQueues[ xQueueToWriteTo ], &ulTxValue, portMAX_DELAY ) != pdPASS )
|
xQueueInUse = xQueues[ xQueueToWriteTo ];
|
||||||
|
|
||||||
|
/* Note which index is being written to to ensure all the queues are
|
||||||
|
used. */
|
||||||
|
( ulQueueUsedCounter[ xQueueToWriteTo ] )++;
|
||||||
|
|
||||||
|
/* Send to the queue to unblock the task that is waiting for data to
|
||||||
|
arrive on a queue within the queue set to which this queue belongs. */
|
||||||
|
if( xQueueSendToBack( xQueueInUse, &ulTaskTxValue, portMAX_DELAY ) != pdPASS )
|
||||||
{
|
{
|
||||||
/* The send should always pass as an infinite block time was
|
/* The send should always pass as an infinite block time was
|
||||||
used. */
|
used. */
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulTxValue++;
|
/* Attempt to remove the queue from a queue set it does not belong
|
||||||
|
to (NULL being passed as the queue set in this case). */
|
||||||
|
if( xQueueRemoveFromQueueSet( xQueueInUse, NULL ) != pdFAIL )
|
||||||
|
{
|
||||||
|
/* It is not possible to successfully remove a queue from a queue
|
||||||
|
set it does not belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the space in the array of queues as being empty before actually
|
||||||
|
removing the queue from the queue set. This is to prevent the code
|
||||||
|
that accesses the queue set from an interrupt from attempting to access
|
||||||
|
a queue that is no longer in the set. */
|
||||||
|
xQueues[ xQueueToWriteTo ] = 0;
|
||||||
|
|
||||||
|
/* Attempt to remove the queue from the queue set it does belong to. */
|
||||||
|
if( xQueueRemoveFromQueueSet( xQueueInUse, xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* It should be possible to remove the queue from the queue set it
|
||||||
|
does belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the queue back before cycling back to run again. */
|
||||||
|
if( xQueueAddToQueueSet( xQueueInUse, xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* If the queue was successfully removed from the queue set then it
|
||||||
|
should be possible to add it back in again. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now the queue is back in the set it is ok for the interrupt that
|
||||||
|
writes to the queues to access it again. */
|
||||||
|
xQueues[ xQueueToWriteTo ] = xQueueInUse;
|
||||||
|
|
||||||
|
ulTaskTxValue++;
|
||||||
|
|
||||||
|
/* If the Tx value has reached the range used by the ISR then set it
|
||||||
|
back to 0. */
|
||||||
|
if( ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
ulTaskTxValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Occasionally change the task priority relative to the priority of
|
||||||
|
the receiving task. */
|
||||||
|
ulLoops++;
|
||||||
|
if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )
|
||||||
|
{
|
||||||
|
ulLoops = 0;
|
||||||
|
uxPriority++;
|
||||||
|
if( uxPriority > queuesetHIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
uxPriority = queuesetLOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskPrioritySet( NULL, uxPriority );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvQueueSetReceivingTask( void *pvParameters )
|
static void prvQueueSetReceivingTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
unsigned long ulReceived, ulLastReceived = ~0UL;
|
unsigned long ulReceived, ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
xQueueHandle xActivatedQueue;
|
xQueueHandle xActivatedQueue;
|
||||||
portBASE_TYPE x;
|
portBASE_TYPE x;
|
||||||
xTaskHandle xQueueSetSendingTask;
|
xTaskHandle xQueueSetSendingTask;
|
||||||
|
@ -208,7 +377,8 @@ xTaskHandle xQueueSetSendingTask;
|
||||||
|
|
||||||
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
{
|
{
|
||||||
/* Create the queue and add it to the set. */
|
/* Create the queue and add it to the set. The queue is just holding
|
||||||
|
unsigned long value. */
|
||||||
xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );
|
xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
configASSERT( xQueues[ x ] );
|
configASSERT( xQueues[ x ] );
|
||||||
if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdPASS )
|
if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdPASS )
|
||||||
|
@ -227,16 +397,19 @@ xTaskHandle xQueueSetSendingTask;
|
||||||
/* The task that sends to the queues is not running yet, so attempting to
|
/* The task that sends to the queues is not running yet, so attempting to
|
||||||
read from the queue set should fail, resulting in xActivatedQueue being set
|
read from the queue set should fail, resulting in xActivatedQueue being set
|
||||||
to NULL. */
|
to NULL. */
|
||||||
xActivatedQueue = xQueueReadMultiple( xQueueSet, queuesetSHORT_DELAY );
|
xActivatedQueue = xQueueBlockMultiple( xQueueSet, queuesetSHORT_DELAY );
|
||||||
configASSERT( xActivatedQueue == NULL );
|
configASSERT( xActivatedQueue == NULL );
|
||||||
|
|
||||||
/* Resume the task that writes to the queues. */
|
/* Resume the task that writes to the queues. */
|
||||||
vTaskResume( xQueueSetSendingTask );
|
vTaskResume( xQueueSetSendingTask );
|
||||||
|
|
||||||
|
/* Let the ISR access the queues also. */
|
||||||
|
xSetupComplete = pdTRUE;
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
/* Wait for a message to arrive on one of the queues in the set. */
|
/* Wait for a message to arrive on one of the queues in the set. */
|
||||||
xActivatedQueue = xQueueReadMultiple( xQueueSet, portMAX_DELAY );
|
xActivatedQueue = xQueueBlockMultiple( xQueueSet, portMAX_DELAY );
|
||||||
configASSERT( xActivatedQueue );
|
configASSERT( xActivatedQueue );
|
||||||
|
|
||||||
if( xActivatedQueue == NULL )
|
if( xActivatedQueue == NULL )
|
||||||
|
@ -254,16 +427,51 @@ xTaskHandle xQueueSetSendingTask;
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is always expected that the received value will be one
|
/* If the received value is equal to or greater than
|
||||||
greater than the previously received value. */
|
queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */
|
||||||
configASSERT( ulReceived == ( ulLastReceived + 1 ) );
|
if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE )
|
||||||
if( ulReceived != ( ulLastReceived + 1 ) )
|
|
||||||
{
|
{
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
/* The value was sent from the ISR. Check it against its
|
||||||
|
expected value. */
|
||||||
|
configASSERT( ulReceived == ulExpectedReceivedFromISR );
|
||||||
|
if( ulReceived != ulExpectedReceivedFromISR )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is expected to receive an incrementing value. */
|
||||||
|
ulExpectedReceivedFromISR++;
|
||||||
|
|
||||||
|
/* If the expected value has wrapped then set it back to
|
||||||
|
its initial value. */
|
||||||
|
if( ulExpectedReceivedFromISR == 0 )
|
||||||
|
{
|
||||||
|
ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ulLastReceived = ulReceived;
|
/* The value was sent from the Tx task. Check it against its
|
||||||
|
expected value. */
|
||||||
|
configASSERT( ulReceived == ulExpectedReceivedFromTask );
|
||||||
|
if( ulReceived != ulExpectedReceivedFromTask )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is expected to receive an incrementing value. */
|
||||||
|
ulExpectedReceivedFromTask++;
|
||||||
|
|
||||||
|
/* If the expected value has reached the range of values
|
||||||
|
used by the ISR then set it back to 0. */
|
||||||
|
if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
ulExpectedReceivedFromTask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,10 @@
|
||||||
#ifndef QUEUE_WAIT_MULTIPLE_H
|
#ifndef QUEUE_WAIT_MULTIPLE_H
|
||||||
#define QUEUE_WAIT_MULTIPLE_H
|
#define QUEUE_WAIT_MULTIPLE_H
|
||||||
|
|
||||||
void vStartQueueSetTasks( unsigned portBASE_TYPE uxPriority );
|
void vStartQueueSetTasks( void );
|
||||||
portBASE_TYPE xAreQueueSetTasksStillRunning( void );
|
portBASE_TYPE xAreQueueSetTasksStillRunning( void );
|
||||||
|
void vQueueSetWriteToQueueFromISR( void );
|
||||||
|
|
||||||
#endif
|
#endif /* QUEUE_WAIT_MULTIPLE_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -130,7 +130,6 @@
|
||||||
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
#define mainQUEUE_SET_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
|
||||||
|
|
||||||
#define mainTIMER_TEST_PERIOD ( 50 )
|
#define mainTIMER_TEST_PERIOD ( 50 )
|
||||||
|
|
||||||
|
@ -167,7 +166,7 @@ int main( void )
|
||||||
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
||||||
vStartCountingSemaphoreTasks();
|
vStartCountingSemaphoreTasks();
|
||||||
vStartDynamicPriorityTasks();
|
vStartDynamicPriorityTasks();
|
||||||
vStartQueueSetTasks( mainQUEUE_SET_TASK_PRIORITY );
|
vStartQueueSetTasks();
|
||||||
|
|
||||||
/* The suicide tasks must be created last as they need to know how many
|
/* 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
|
tasks were running prior to their creation. This then allows them to
|
||||||
|
@ -406,6 +405,10 @@ void vApplicationTickHook( void )
|
||||||
/* Call the periodic timer test, which tests the timer API functions that
|
/* Call the periodic timer test, which tests the timer API functions that
|
||||||
can be called from an ISR. */
|
can be called from an ISR. */
|
||||||
vTimerPeriodicISRTests();
|
vTimerPeriodicISRTests();
|
||||||
|
|
||||||
|
/* Write to a queue that is in use as part of the queue set demo to
|
||||||
|
demonstrate using queue sets from an ISR. */
|
||||||
|
vQueueSetWriteToQueueFromISR();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,17 @@ typedef void * xQueueHandle;
|
||||||
/**
|
/**
|
||||||
* Type by which queue sets are referenced. For example, a call to
|
* Type by which queue sets are referenced. For example, a call to
|
||||||
* xQueueSetCreate() returns an xQueueSet variable that can then be used as a
|
* xQueueSetCreate() returns an xQueueSet variable that can then be used as a
|
||||||
* parameter to xQueueReadMultiple(), xQueueAddToQueueSet(), etc.
|
* parameter to xQueueBlockMultiple(), xQueueAddToQueueSet(), etc.
|
||||||
*/
|
*/
|
||||||
typedef void * xQueueSetHandle;
|
typedef void * xQueueSetHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue sets can contain both queues and semaphores, so the
|
||||||
|
* xQueueSetMemberHandle is defined as a type to be used where a parameter or
|
||||||
|
* return value can be either an xQueueHandle or an xSemaphoreHandle.
|
||||||
|
*/
|
||||||
|
typedef void * xQueueSetMemberHandle;
|
||||||
|
|
||||||
/* For internal use only. */
|
/* For internal use only. */
|
||||||
#define queueSEND_TO_BACK ( 0 )
|
#define queueSEND_TO_BACK ( 0 )
|
||||||
#define queueSEND_TO_FRONT ( 1 )
|
#define queueSEND_TO_FRONT ( 1 )
|
||||||
|
@ -1305,7 +1312,7 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
|
||||||
* A queue set must be explicitly created using a call to xQueueSetCreate()
|
* A queue set must be explicitly created using a call to xQueueSetCreate()
|
||||||
* before it can be used. Once created, standard FreeRTOS queues and semaphores
|
* before it can be used. Once created, standard FreeRTOS queues and semaphores
|
||||||
* can be added to the set using calls to xQueueAddToQueueSet().
|
* can be added to the set using calls to xQueueAddToQueueSet().
|
||||||
* xQueueReadMultiple() is then used to determine which, if any, of the queues
|
* xQueueBlockMultiple() is then used to determine which, if any, of the queues
|
||||||
* or semaphores contained in the set is in a state where a queue read or
|
* or semaphores contained in the set is in a state where a queue read or
|
||||||
* semaphore take operation would be successful.
|
* semaphore take operation would be successful.
|
||||||
*
|
*
|
||||||
|
@ -1349,10 +1356,8 @@ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
*
|
*
|
||||||
* @param xQueue The handle of the queue or semaphore being added to the
|
* @param xQueueOrSemaphore The handle of the queue or semaphore being added to
|
||||||
* queue set. Variables of type xSemaphoreHandle can be safely added to a
|
* the queue set (cast to an xQueueSetMemberHandle type).
|
||||||
* queue set but may require casting to an xQueueHandle type to avoid compiler
|
|
||||||
* warnings.
|
|
||||||
*
|
*
|
||||||
* @param xQueueSet The handle of the queue set to which the queue or semaphore
|
* @param xQueueSet The handle of the queue set to which the queue or semaphore
|
||||||
* is being added.
|
* is being added.
|
||||||
|
@ -1362,7 +1367,7 @@ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
|
||||||
* queue set because it is already a member of a different queue set then pdFAIL
|
* queue set because it is already a member of a different queue set then pdFAIL
|
||||||
* is returned.
|
* is returned.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet );
|
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Removes a queue or semaphore from a queue set.
|
* Removes a queue or semaphore from a queue set.
|
||||||
|
@ -1370,9 +1375,8 @@ portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSe
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
*
|
*
|
||||||
* @param xQueue The handle of the queue or semaphore being removed from the
|
* @param xQueueOrSemaphore The handle of the queue or semaphore being removed
|
||||||
* queue set. Variables of type xSemaphoreHandle can be safely used but may
|
* from the queue set (cast to an xQueueSetMemberHandle type).
|
||||||
* require casting to an xQueueHandle type to avoid compiler warnings.
|
|
||||||
*
|
*
|
||||||
* @param xQueueSet The handle of the queue set in which the queue or semaphore
|
* @param xQueueSet The handle of the queue set in which the queue or semaphore
|
||||||
* is included.
|
* is included.
|
||||||
|
@ -1381,10 +1385,10 @@ portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSe
|
||||||
* then pdPASS is returned. If the queue was not in the queue set then pdFAIL
|
* then pdPASS is returned. If the queue was not in the queue set then pdFAIL
|
||||||
* is returned.
|
* is returned.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue );
|
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xQueueReadMultiple() allows a task to block (pend) on a read operation on
|
* xQueueBlockMultiple() allows a task to block (pend) on a read operation on
|
||||||
* all the queues and semaphores in a queue set simultaneously.
|
* all the queues and semaphores in a queue set simultaneously.
|
||||||
*
|
*
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
|
@ -1405,12 +1409,13 @@ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle
|
||||||
* of the queue set to be ready for a successful queue read or semaphore take
|
* of the queue set to be ready for a successful queue read or semaphore take
|
||||||
* operation.
|
* operation.
|
||||||
*
|
*
|
||||||
* @return xQueueReadMultiple() will return the handle of a queue contained
|
* @return xQueueBlockMultiple() will return the handle of a queue (cast to
|
||||||
* in the queue set that contains data, or the handle of a semaphore contained
|
* a xQueueSetMemberHandle type) contained in the queue set that contains data,
|
||||||
|
* or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained
|
||||||
* in the queue set that is available, or NULL if no such queue or semaphore
|
* in the queue set that is available, or NULL if no such queue or semaphore
|
||||||
* exists before before the specified block time expires.
|
* exists before before the specified block time expires.
|
||||||
*/
|
*/
|
||||||
xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
|
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
|
||||||
|
|
||||||
/* Not public API functions. */
|
/* Not public API functions. */
|
||||||
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
|
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
FreeRTOS WEB site.
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* Having a problem? Start by reading the FAQ "My application does *
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
@ -52,17 +52,17 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
and contact details.
|
and contact details.
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool.
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
the code with commercial support, indemnification, and middleware, under
|
the code with commercial support, indemnification, and middleware, under
|
||||||
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
provide a safety engineered and independently SIL3 certified version under
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
the SafeRTOS brand: http://www.SafeRTOS.com.
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -148,15 +148,22 @@ typedef struct QueueDefinition
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inside this file xQueueHandle is a pointer to a xQUEUE structure.
|
* Inside this file xQueueHandle and xQueueSetHandle are both pointers to xQUEUE
|
||||||
* To keep the definition private the API header file defines it as a
|
* structures. To keep the definition private the API header file defines both
|
||||||
* pointer to void.
|
* as pointers to void.
|
||||||
*/
|
*/
|
||||||
typedef xQUEUE * xQueueHandle;
|
typedef xQUEUE * xQueueHandle;
|
||||||
typedef xQUEUE * xQueueSetHandle;
|
typedef xQUEUE * xQueueSetHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue sets can contain both queues and semaphores, so the
|
||||||
|
* xQueueSetMemberHandle is defined as a type to be used where a parameter or
|
||||||
|
* return value can be either an xQueueHandle or an xSemaphoreHandle.
|
||||||
|
*/
|
||||||
|
typedef xQUEUE * xQueueSetMemberHandle;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In order to implement strict data hiding, the queue.h header file defines
|
* In order to implement strict data hiding, the queue.h header file defines
|
||||||
* xQueueHandle and xQueueSetHandle as pointers to void. In this file
|
* xQueueHandle and xQueueSetHandle as pointers to void. In this file
|
||||||
* xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.
|
* xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.
|
||||||
* Therefore the queue.h header file cannot be included in this source file,
|
* Therefore the queue.h header file cannot be included in this source file,
|
||||||
|
@ -185,9 +192,9 @@ unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
|
||||||
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
|
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
|
||||||
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
||||||
xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
|
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Co-routine queue functions differ from task queue functions. Co-routines are
|
* Co-routine queue functions differ from task queue functions. Co-routines are
|
||||||
|
@ -266,7 +273,7 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
|
||||||
* Checks to see if a queue is a member of a queue set, and if so, notifies
|
* Checks to see if a queue is a member of a queue set, and if so, notifies
|
||||||
* the queue set that the queue contains data.
|
* the queue set that the queue contains data.
|
||||||
*/
|
*/
|
||||||
static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );
|
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -361,7 +368,7 @@ xQueueHandle xReturn = NULL;
|
||||||
pxNewQueue->uxLength = uxQueueLength;
|
pxNewQueue->uxLength = uxQueueLength;
|
||||||
pxNewQueue->uxItemSize = uxItemSize;
|
pxNewQueue->uxItemSize = uxItemSize;
|
||||||
xQueueGenericReset( pxNewQueue, pdTRUE );
|
xQueueGenericReset( pxNewQueue, pdTRUE );
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
{
|
{
|
||||||
pxNewQueue->ucQueueType = ucQueueType;
|
pxNewQueue->ucQueueType = ucQueueType;
|
||||||
|
@ -640,12 +647,15 @@ xTimeOutType xTimeOut;
|
||||||
{
|
{
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
{
|
{
|
||||||
if( prvCheckForMembershipOfQueueSet( pxQueue, xCopyPosition ) == pdTRUE )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
/* The queue is a member of a queue set, and posting to
|
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
||||||
the queue set caused a higher priority task to unblock.
|
{
|
||||||
A context switch is required. */
|
/* The queue is a member of a queue set, and posting to
|
||||||
portYIELD_WITHIN_API();
|
the queue set caused a higher priority task to unblock.
|
||||||
|
A context switch is required. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
@ -985,7 +995,16 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
{
|
{
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK );
|
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* The queue is a member of a queue set, and posting
|
||||||
|
to the queue set caused a higher priority task to
|
||||||
|
unblock. A context switch is required. */
|
||||||
|
if( pxHigherPriorityTaskWoken != NULL )
|
||||||
|
{
|
||||||
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
@ -1068,7 +1087,7 @@ signed char *pcOriginalReadPosition;
|
||||||
{
|
{
|
||||||
traceQUEUE_PEEK( pxQueue );
|
traceQUEUE_PEEK( pxQueue );
|
||||||
|
|
||||||
/* The data is not being removed, so reset the read
|
/* The data is not being removed, so reset the read
|
||||||
pointer. */
|
pointer. */
|
||||||
pxQueue->pcReadFrom = pcOriginalReadPosition;
|
pxQueue->pcReadFrom = pcOriginalReadPosition;
|
||||||
|
|
||||||
|
@ -1084,17 +1103,6 @@ signed char *pcOriginalReadPosition;
|
||||||
portYIELD_WITHIN_API();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
|
||||||
{
|
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
|
||||||
{
|
|
||||||
xQueueGenericSend( pxQueue->pxQueueSetContainer, &pxQueue, 0, queueSEND_TO_BACK );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
@ -1379,10 +1387,11 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
|
||||||
{
|
{
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
|
||||||
xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, &xHigherPriorityTaskWoken, queueSEND_TO_BACK );
|
|
||||||
if( xHigherPriorityTaskWoken != pdFALSE )
|
|
||||||
{
|
{
|
||||||
|
/* The queue is a member of a queue set, and posting to
|
||||||
|
the queue set caused a higher priority task to unblock.
|
||||||
|
A context switch is required. */
|
||||||
vTaskMissedYield();
|
vTaskMissedYield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1784,11 +1793,11 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet )
|
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
if( xQueue->pxQueueSetContainer != NULL )
|
if( xQueueOrSemaphore->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
xReturn = pdFAIL;
|
xReturn = pdFAIL;
|
||||||
}
|
}
|
||||||
|
@ -1796,7 +1805,7 @@ signed portBASE_TYPE xReturn;
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
xQueue->pxQueueSetContainer = xQueueSet;
|
xQueueOrSemaphore->pxQueueSetContainer = xQueueSet;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
@ -1810,11 +1819,11 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue )
|
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
if( xQueue->pxQueueSetContainer != xQueueSet )
|
if( xQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
|
||||||
{
|
{
|
||||||
xReturn = pdFAIL;
|
xReturn = pdFAIL;
|
||||||
}
|
}
|
||||||
|
@ -1822,7 +1831,7 @@ signed portBASE_TYPE xReturn;
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
xQueue->pxQueueSetContainer = NULL;
|
xQueueOrSemaphore->pxQueueSetContainer = NULL;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
@ -1836,10 +1845,10 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
|
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
|
||||||
{
|
{
|
||||||
xQueueHandle xReturn = NULL;
|
xQueueSetMemberHandle xReturn = NULL;
|
||||||
|
|
||||||
xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );
|
xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
@ -1849,23 +1858,23 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
|
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
|
xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
|
||||||
portBASE_TYPE xReturn = pdFALSE;
|
portBASE_TYPE xReturn = pdFALSE;
|
||||||
|
|
||||||
if( pxQueueSetContainer != NULL )
|
configASSERT( pxQueueSetContainer );
|
||||||
|
configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength );
|
||||||
|
|
||||||
|
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
||||||
{
|
{
|
||||||
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
{
|
{
|
||||||
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
|
if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
|
|
||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
|
/* The task waiting has a higher priority */
|
||||||
{
|
xReturn = pdTRUE;
|
||||||
/* The task waiting has a higher priority */
|
|
||||||
xReturn = pdTRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue