pcTail members are used as pointers into the queue storage area. When the\r
Queue_t structure is used to represent a mutex pcHead and pcTail pointers are\r
not necessary, and the pcHead pointer is set to NULL to indicate that the\r
-pcTail pointer actually points to the mutex holder (if any). Map alternative\r
-names to the pcHead and pcTail structure members to ensure the readability of\r
-the code is maintained despite this dual use of two structure members. An\r
-alternative implementation would be to use a union, but use of a union is\r
-against the coding standard (although an exception to the standard has been\r
-permitted where the dual use also significantly changes the type of the\r
-structure member). */\r
-#define pxMutexHolder pcTail\r
+structure instead holds a pointer to the mutex holder (if any). Map alternative\r
+names to the pcHead and structure member to ensure the readability of the code\r
+is maintained. The QueuePointers_t and SemaphoreData_t types are used to form\r
+a union as their usage is mutually exclusive dependent on what the queue is\r
+being used for. */\r
#define uxQueueType pcHead\r
#define queueQUEUE_IS_MUTEX NULL\r
\r
+typedef struct QueuePointers\r
+{\r
+ int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
+ int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */\r
+} QueuePointers_t;\r
+\r
+typedef struct SemaphoreData\r
+{\r
+ TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */\r
+ UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */\r
+} SemaphoreData_t;\r
+\r
/* Semaphores do not actually store or copy data, so have an item size of\r
zero. */\r
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 )\r
typedef struct QueueDef_t\r
{\r
int8_t *pcHead; /*< Points to the beginning of the queue storage area. */\r
- int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */\r
\r
- union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */\r
+ union\r
{\r
- int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */\r
- UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */\r
+ QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */\r
+ SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */\r
} u;\r
\r
List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */\r
\r
taskENTER_CRITICAL();\r
{\r
- pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );\r
+ pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */\r
pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;\r
pxQueue->pcWriteTo = pxQueue->pcHead;\r
- pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize );\r
+ pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */\r
pxQueue->cRxLock = queueUNLOCKED;\r
pxQueue->cTxLock = queueUNLOCKED;\r
\r
{\r
/* Jump past the queue structure to find the location of the queue\r
storage area. */\r
- pucQueueStorage = ( ( uint8_t * ) pxNewQueue ) + sizeof( Queue_t );\r
+ pucQueueStorage = ( uint8_t * ) pxNewQueue;\r
+ pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */\r
\r
#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
{\r
correctly for a generic queue, but this function is creating a\r
mutex. Overwrite those members that need to be set differently -\r
in particular the information required for priority inheritance. */\r
- pxNewQueue->pxMutexHolder = NULL;\r
+ pxNewQueue->u.xSemaphore.xMutexHolder = NULL;\r
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
\r
/* In case this is a recursive mutex. */\r
- pxNewQueue->u.uxRecursiveCallCount = 0;\r
+ pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0;\r
\r
traceCREATE_MUTEX( pxNewQueue );\r
\r
\r
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )\r
\r
- void* xQueueGetMutexHolder( QueueHandle_t xSemaphore )\r
+ TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore )\r
{\r
- void *pxReturn;\r
+ TaskHandle_t pxReturn;\r
Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore;\r
\r
/* This function is called by xSemaphoreGetMutexHolder(), and should not\r
{\r
if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
- pxReturn = ( void * ) pxSemaphore->pxMutexHolder;\r
+ pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder;\r
}\r
else\r
{\r
\r
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )\r
\r
- void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore )\r
+ TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore )\r
{\r
- void *pxReturn;\r
+ TaskHandle_t pxReturn;\r
\r
configASSERT( xSemaphore );\r
\r
not required here. */\r
if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
- pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder;\r
+ pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder;\r
}\r
else\r
{\r
\r
configASSERT( pxMutex );\r
\r
- /* If this is the task that holds the mutex then pxMutexHolder will not\r
+ /* If this is the task that holds the mutex then xMutexHolder will not\r
change outside of this task. If this task does not hold the mutex then\r
pxMutexHolder can never coincidentally equal the tasks handle, and as\r
this is the only condition we are interested in it does not matter if\r
pxMutexHolder is accessed simultaneously by another task. Therefore no\r
mutual exclusion is required to test the pxMutexHolder variable. */\r
- if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as TaskHandle_t is a typedef. */\r
+ if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() )\r
{\r
traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
\r
- /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to\r
+ /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to\r
the task handle, therefore no underflow check is required. Also,\r
uxRecursiveCallCount is only modified by the mutex holder, and as\r
there can only be one, no mutual exclusion is required to modify the\r
uxRecursiveCallCount member. */\r
- ( pxMutex->u.uxRecursiveCallCount )--;\r
+ ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--;\r
\r
/* Has the recursive call count unwound to 0? */\r
- if( pxMutex->u.uxRecursiveCallCount == ( UBaseType_t ) 0 )\r
+ if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 )\r
{\r
/* Return the mutex. This will automatically unblock any other\r
task that might be waiting to access the mutex. */\r
\r
traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
\r
- if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */\r
+ if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() )\r
{\r
- ( pxMutex->u.uxRecursiveCallCount )++;\r
+ ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++;\r
xReturn = pdPASS;\r
}\r
else\r
before reaching here. */\r
if( xReturn != pdFAIL )\r
{\r
- ( pxMutex->u.uxRecursiveCallCount )++;\r
+ ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++;\r
}\r
else\r
{\r
/* Normally a mutex would not be given from an interrupt, especially if\r
there is a mutex holder, as priority inheritance makes no sense for an\r
interrupts, only tasks. */\r
- configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->pxMutexHolder != NULL ) ) );\r
+ configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) );\r
\r
/* RTOS ports that support interrupt nesting have the concept of a maximum\r
system call (or maximum API call) interrupt priority. Interrupts that are\r
{\r
/* Record the information required to implement\r
priority inheritance should it become necessary. */\r
- pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */\r
+ pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount();\r
}\r
else\r
{\r
{\r
taskENTER_CRITICAL();\r
{\r
- xInheritanceOccurred = xTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+ xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder );\r
}\r
taskEXIT_CRITICAL();\r
}\r
again, but only as low as the next highest priority\r
task that is waiting for the same mutex. */\r
uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue );\r
- vTaskPriorityDisinheritAfterTimeout( ( void * ) pxQueue->pxMutexHolder, uxHighestWaitingPriority );\r
+ vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority );\r
}\r
taskEXIT_CRITICAL();\r
}\r
#endif\r
\r
\r
- /* This function relaxes the coding standard somewhat to allow return\r
- statements within the function itself. This is done in the interest\r
- of execution time efficiency. */\r
-\r
+ /*lint -save -e904 This function relaxes the coding standard somewhat to\r
+ allow return statements within the function itself. This is done in the\r
+ interest of execution time efficiency. */\r
for( ;; )\r
{\r
taskENTER_CRITICAL();\r
/* Remember the read position so it can be reset after the data\r
is read from the queue as this function is only peeking the\r
data, not removing it. */\r
- pcOriginalReadPosition = pxQueue->u.pcReadFrom;\r
+ pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom;\r
\r
prvCopyDataFromQueue( pxQueue, pvBuffer );\r
traceQUEUE_PEEK( pxQueue );\r
\r
/* The data is not being removed, so reset the read pointer. */\r
- pxQueue->u.pcReadFrom = pcOriginalReadPosition;\r
+ pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition;\r
\r
/* The data is being left in the queue, so see if there are\r
any other tasks waiting for the data. */\r
mtCOVERAGE_TEST_MARKER();\r
}\r
}\r
- }\r
+ } /*lint -restore */\r
}\r
/*-----------------------------------------------------------*/\r
\r
\r
/* Remember the read position so it can be reset as nothing is\r
actually being removed from the queue. */\r
- pcOriginalReadPosition = pxQueue->u.pcReadFrom;\r
+ pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom;\r
prvCopyDataFromQueue( pxQueue, pvBuffer );\r
- pxQueue->u.pcReadFrom = pcOriginalReadPosition;\r
+ pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition;\r
\r
xReturn = pdPASS;\r
}\r
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
/* The mutex is no longer being held. */\r
- xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
- pxQueue->pxMutexHolder = NULL;\r
+ xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder );\r
+ pxQueue->u.xSemaphore.xMutexHolder = NULL;\r
}\r
else\r
{\r
{\r
( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */\r
pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */\r
- if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */\r
+ if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */\r
{\r
pxQueue->pcWriteTo = pxQueue->pcHead;\r
}\r
}\r
else\r
{\r
- ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */\r
- pxQueue->u.pcReadFrom -= pxQueue->uxItemSize;\r
- if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */\r
+ ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */\r
+ pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize;\r
+ if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */\r
{\r
- pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
+ pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize );\r
}\r
else\r
{\r
{\r
if( pxQueue->uxItemSize != ( UBaseType_t ) 0 )\r
{\r
- pxQueue->u.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */\r
- if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */\r
+ pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */\r
+ if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */\r
{\r
- pxQueue->u.pcReadFrom = pxQueue->pcHead;\r
+ pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead;\r
}\r
else\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
- ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */\r
+ ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */\r
}\r
}\r
/*-----------------------------------------------------------*/\r
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )\r
{\r
/* Data is available from the queue. */\r
- pxQueue->u.pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )\r
+ pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail )\r
{\r
- pxQueue->u.pcReadFrom = pxQueue->pcHead;\r
+ pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead;\r
}\r
else\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
--( pxQueue->uxMessagesWaiting );\r
- ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
\r
xReturn = pdPASS;\r
\r
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )\r
{\r
/* Copy the data from the queue. */\r
- pxQueue->u.pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )\r
+ pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail )\r
{\r
- pxQueue->u.pcReadFrom = pxQueue->pcHead;\r
+ pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead;\r
}\r
else\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
--( pxQueue->uxMessagesWaiting );\r
- ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
\r
if( ( *pxCoRoutineWoken ) == pdFALSE )\r
{\r