Skip to content

Commit

Permalink
Add xQueueCreateSetStatic method for static allocation of Queue Sets (#…
Browse files Browse the repository at this point in the history
…1228)

Add xQueueCreateSetStatic method for static allocation of Queue Sets

This commit introduces the xQueueCreateSetStatic function, which allows for the static allocation of Queue Sets in FreeRTOS when both configUSE_QUEUE_SETS and configSUPPORT_STATIC_ALLOCATION are enabled.
  • Loading branch information
kzorer authored Jan 22, 2025
1 parent b5d1b97 commit 1b8f596
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 8 deletions.
8 changes: 8 additions & 0 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,14 @@
#define traceRETURN_xQueueCreateSet( pxQueue )
#endif

#ifndef traceENTER_xQueueCreateSetStatic
#define traceENTER_xQueueCreateSetStatic( uxEventQueueLength )
#endif

#ifndef traceRETURN_xQueueCreateSetStatic
#define traceRETURN_xQueueCreateSetStatic( pxQueue )
#endif

#ifndef traceENTER_xQueueAddToSet
#define traceENTER_xQueueAddToSet( xQueueOrSemaphore, xQueueSet )
#endif
Expand Down
6 changes: 6 additions & 0 deletions include/mpu_prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
Expand All @@ -294,6 +297,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
Expand Down
1 change: 1 addition & 0 deletions include/mpu_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueGenericReset MPU_xQueueGenericReset
#define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueCreateSetStatic MPU_xQueueCreateSetStatic
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
Expand Down
74 changes: 67 additions & 7 deletions include/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -1638,12 +1638,12 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
*
* A queue set must be explicitly created using a call to xQueueCreateSet()
* before it can be used. Once created, standard FreeRTOS queues and semaphores
* can be added to the set using calls to xQueueAddToSet().
* xQueueSelectFromSet() 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
* semaphore take operation would be successful.
* A queue set must be explicitly created using a call to xQueueCreateSet() or
* xQueueCreateSetStatic() before it can be used. Once created, standard
* FreeRTOS queues and semaphores can be added to the set using calls to
* xQueueAddToSet(). xQueueSelectFromSet() 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 semaphore take operation would be successful.
*
* Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets
* for reasons why queue sets are very rarely needed in practice as there are
Expand Down Expand Up @@ -1683,9 +1683,69 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
#endif

/*
* Queue sets provide a mechanism to allow a task to block (pend) on a read
* operation from multiple queues or semaphores simultaneously.
*
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
*
* A queue set must be explicitly created using a call to xQueueCreateSet()
* or xQueueCreateSetStatic() before it can be used. Once created, standard
* FreeRTOS queues and semaphores can be added to the set using calls to
* xQueueAddToSet(). xQueueSelectFromSet() 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 semaphore take operation would be successful.
*
* Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets
* for reasons why queue sets are very rarely needed in practice as there are
* simpler methods of blocking on multiple objects.
*
* Note 2: Blocking on a queue set that contains a mutex will not cause the
* mutex holder to inherit the priority of the blocked task.
*
* Note 3: An additional 4 bytes of RAM is required for each space in a every
* queue added to a queue set. Therefore counting semaphores that have a high
* maximum count value should not be added to a queue set.
*
* Note 4: A receive (in the case of a queue) or take (in the case of a
* semaphore) operation must not be performed on a member of a queue set unless
* a call to xQueueSelectFromSet() has first returned a handle to that set member.
*
* @param uxEventQueueLength Queue sets store events that occur on
* the queues and semaphores contained in the set. uxEventQueueLength specifies
* the maximum number of events that can be queued at once. To be absolutely
* certain that events are not lost uxEventQueueLength should be set to the
* total sum of the length of the queues added to the set, where binary
* semaphores and mutexes have a length of 1, and counting semaphores have a
* length set by their maximum count value. Examples:
* + If a queue set is to hold a queue of length 5, another queue of length 12,
* and a binary semaphore, then uxEventQueueLength should be set to
* (5 + 12 + 1), or 18.
* + If a queue set is to hold three binary semaphores then uxEventQueueLength
* should be set to (1 + 1 + 1 ), or 3.
* + If a queue set is to hold a counting semaphore that has a maximum count of
* 5, and a counting semaphore that has a maximum count of 3, then
* uxEventQueueLength should be set to (5 + 3), or 8.
*
* @param pucQueueStorage pucQueueStorage must point to a uint8_t array that is
* at least large enough to hold uxEventQueueLength events.
*
* @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which
* will be used to hold the queue's data structure.
*
* @return If the queue set is created successfully then a handle to the created
* queue set is returned. If pxQueueBuffer is NULL then NULL is returned.
*/
#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
QueueSetHandle_t xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
#endif

/*
* Adds a queue or semaphore to a queue set that was previously created by a
* call to xQueueCreateSet().
* call to xQueueCreateSet() or xQueueCreateSetStatic().
*
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
Expand Down
28 changes: 28 additions & 0 deletions portable/Common/mpu_wrappers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,34 @@
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
{
QueueSetHandle_t xReturn;

if( portIS_PRIVILEGED() == pdFALSE )
{
portRAISE_PRIVILEGE();
portMEMORY_BARRIER();

xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );
portMEMORY_BARRIER();

portRESET_PRIVILEGE();
portMEMORY_BARRIER();
}
else
{
xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );
}

return xReturn;
}
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( configUSE_QUEUE_SETS == 1 )
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */
Expand Down
33 changes: 33 additions & 0 deletions portable/Common/mpu_wrappers_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -3016,6 +3016,39 @@
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )

QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */
{
QueueSetHandle_t xInternalQueueSetHandle = NULL;
QueueSetHandle_t xExternalQueueSetHandle = NULL;
int32_t lIndex;

lIndex = MPU_GetFreeIndexInKernelObjectPool();

if( lIndex != -1 )
{
xInternalQueueSetHandle = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );

if( xInternalQueueSetHandle != NULL )
{
MPU_StoreQueueSetHandleAtIndex( lIndex, xInternalQueueSetHandle );
xExternalQueueSetHandle = ( QueueSetHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex );
}
else
{
MPU_SetIndexFreeInKernelObjectPool( lIndex );
}
}

return xExternalQueueSetHandle;
}

#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( configUSE_QUEUE_SETS == 1 )

BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
Expand Down
22 changes: 21 additions & 1 deletion queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -3186,7 +3186,27 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
return pxQueue;
}

#endif /* configUSE_QUEUE_SETS */
#endif /* #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )

QueueSetHandle_t xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue )
{
QueueSetHandle_t pxQueue;

traceENTER_xQueueCreateSetStatic( uxEventQueueLength );

pxQueue = xQueueGenericCreateStatic( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), pucQueueStorage, pxStaticQueue, queueQUEUE_TYPE_SET );

traceRETURN_xQueueCreateSetStatic( pxQueue );

return pxQueue;
}

#endif /* #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( configUSE_QUEUE_SETS == 1 )
Expand Down

0 comments on commit 1b8f596

Please sign in to comment.