Skip to content

Commit e7e7005

Browse files
authored
Merge branch 'main' into idleTaskSAFixes
2 parents 1f59ce7 + b421abc commit e7e7005

File tree

38 files changed

+618
-215
lines changed

38 files changed

+618
-215
lines changed

.github/workflows/kernel-demos.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,12 @@ jobs:
268268
fetch-depth: 1
269269

270270
- env:
271-
stepName: Fetch Community-Supported-Demos Submodule
271+
stepName: Fetch Dependencies
272272
shell: bash
273273
run: |
274274
# ${{ env.stepName }}
275275
echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}"
276-
git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos
276+
git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace
277277
echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}"
278278
279279
# Checkout user pull request changes

include/FreeRTOS.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,14 @@
14841484
#define traceRETURN_xQueueCreateSet( pxQueue )
14851485
#endif
14861486

1487+
#ifndef traceENTER_xQueueCreateSetStatic
1488+
#define traceENTER_xQueueCreateSetStatic( uxEventQueueLength )
1489+
#endif
1490+
1491+
#ifndef traceRETURN_xQueueCreateSetStatic
1492+
#define traceRETURN_xQueueCreateSetStatic( pxQueue )
1493+
#endif
1494+
14871495
#ifndef traceENTER_xQueueAddToSet
14881496
#define traceENTER_xQueueAddToSet( xQueueOrSemaphore, xQueueSet )
14891497
#endif

include/mpu_prototypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
269269
StaticQueue_t * pxStaticQueue,
270270
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
271271
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
272+
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
273+
uint8_t * pucQueueStorage,
274+
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
272275
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
273276
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
274277
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
@@ -294,6 +297,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
294297
StaticQueue_t * pxStaticQueue,
295298
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
296299
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
300+
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
301+
uint8_t * pucQueueStorage,
302+
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
297303
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
298304
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
299305
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,

include/mpu_wrappers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
151151
#define xQueueGenericReset MPU_xQueueGenericReset
152152
#define xQueueCreateSet MPU_xQueueCreateSet
153+
#define xQueueCreateSetStatic MPU_xQueueCreateSetStatic
153154
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
154155

155156
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

include/queue.h

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,12 +1638,12 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
16381638
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
16391639
* function.
16401640
*
1641-
* A queue set must be explicitly created using a call to xQueueCreateSet()
1642-
* before it can be used. Once created, standard FreeRTOS queues and semaphores
1643-
* can be added to the set using calls to xQueueAddToSet().
1644-
* xQueueSelectFromSet() is then used to determine which, if any, of the queues
1645-
* or semaphores contained in the set is in a state where a queue read or
1646-
* semaphore take operation would be successful.
1641+
* A queue set must be explicitly created using a call to xQueueCreateSet() or
1642+
* xQueueCreateSetStatic() before it can be used. Once created, standard
1643+
* FreeRTOS queues and semaphores can be added to the set using calls to
1644+
* xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if
1645+
* any, of the queues or semaphores contained in the set is in a state where a
1646+
* queue read or semaphore take operation would be successful.
16471647
*
16481648
* Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets
16491649
* for reasons why queue sets are very rarely needed in practice as there are
@@ -1683,9 +1683,69 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
16831683
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
16841684
#endif
16851685

1686+
/*
1687+
* Queue sets provide a mechanism to allow a task to block (pend) on a read
1688+
* operation from multiple queues or semaphores simultaneously.
1689+
*
1690+
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
1691+
* function.
1692+
*
1693+
* A queue set must be explicitly created using a call to xQueueCreateSet()
1694+
* or xQueueCreateSetStatic() before it can be used. Once created, standard
1695+
* FreeRTOS queues and semaphores can be added to the set using calls to
1696+
* xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if
1697+
* any, of the queues or semaphores contained in the set is in a state where a
1698+
* queue read or semaphore take operation would be successful.
1699+
*
1700+
* Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets
1701+
* for reasons why queue sets are very rarely needed in practice as there are
1702+
* simpler methods of blocking on multiple objects.
1703+
*
1704+
* Note 2: Blocking on a queue set that contains a mutex will not cause the
1705+
* mutex holder to inherit the priority of the blocked task.
1706+
*
1707+
* Note 3: An additional 4 bytes of RAM is required for each space in a every
1708+
* queue added to a queue set. Therefore counting semaphores that have a high
1709+
* maximum count value should not be added to a queue set.
1710+
*
1711+
* Note 4: A receive (in the case of a queue) or take (in the case of a
1712+
* semaphore) operation must not be performed on a member of a queue set unless
1713+
* a call to xQueueSelectFromSet() has first returned a handle to that set member.
1714+
*
1715+
* @param uxEventQueueLength Queue sets store events that occur on
1716+
* the queues and semaphores contained in the set. uxEventQueueLength specifies
1717+
* the maximum number of events that can be queued at once. To be absolutely
1718+
* certain that events are not lost uxEventQueueLength should be set to the
1719+
* total sum of the length of the queues added to the set, where binary
1720+
* semaphores and mutexes have a length of 1, and counting semaphores have a
1721+
* length set by their maximum count value. Examples:
1722+
* + If a queue set is to hold a queue of length 5, another queue of length 12,
1723+
* and a binary semaphore, then uxEventQueueLength should be set to
1724+
* (5 + 12 + 1), or 18.
1725+
* + If a queue set is to hold three binary semaphores then uxEventQueueLength
1726+
* should be set to (1 + 1 + 1 ), or 3.
1727+
* + If a queue set is to hold a counting semaphore that has a maximum count of
1728+
* 5, and a counting semaphore that has a maximum count of 3, then
1729+
* uxEventQueueLength should be set to (5 + 3), or 8.
1730+
*
1731+
* @param pucQueueStorage pucQueueStorage must point to a uint8_t array that is
1732+
* at least large enough to hold uxEventQueueLength events.
1733+
*
1734+
* @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which
1735+
* will be used to hold the queue's data structure.
1736+
*
1737+
* @return If the queue set is created successfully then a handle to the created
1738+
* queue set is returned. If pxQueueBuffer is NULL then NULL is returned.
1739+
*/
1740+
#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
1741+
QueueSetHandle_t xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
1742+
uint8_t * pucQueueStorage,
1743+
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
1744+
#endif
1745+
16861746
/*
16871747
* Adds a queue or semaphore to a queue set that was previously created by a
1688-
* call to xQueueCreateSet().
1748+
* call to xQueueCreateSet() or xQueueCreateSetStatic().
16891749
*
16901750
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
16911751
* function.

portable/ARMv8M/non_secure/portmacrocommon.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
251251
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
252252
*
253253
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
254-
* 16 16 8 8 5 16 1
254+
* 16 17 8 8 5 16 1
255255
*/
256-
#define MAX_CONTEXT_SIZE 70
256+
#define MAX_CONTEXT_SIZE 71
257257

258258
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
259259

@@ -264,9 +264,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
264264
* +-----------+---------------+----------+-----------------+------------------------------+-----+
265265
*
266266
* <-----------><--------------><---------><----------------><-----------------------------><---->
267-
* 16 16 8 8 5 1
267+
* 16 17 8 8 5 1
268268
*/
269-
#define MAX_CONTEXT_SIZE 54
269+
#define MAX_CONTEXT_SIZE 55
270270

271271
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
272272

@@ -277,9 +277,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
277277
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
278278
*
279279
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
280-
* 16 16 8 8 4 16 1
280+
* 16 17 8 8 4 16 1
281281
*/
282-
#define MAX_CONTEXT_SIZE 69
282+
#define MAX_CONTEXT_SIZE 70
283283

284284
#else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
285285

@@ -290,9 +290,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
290290
* +-----------+---------------+----------+-----------------+----------------------+-----+
291291
*
292292
* <-----------><--------------><---------><----------------><---------------------><---->
293-
* 16 16 8 8 4 1
293+
* 16 17 8 8 4 1
294294
*/
295-
#define MAX_CONTEXT_SIZE 53
295+
#define MAX_CONTEXT_SIZE 54
296296

297297
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
298298

portable/Common/mpu_wrappers.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,34 @@
15241524
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
15251525
/*-----------------------------------------------------------*/
15261526

1527+
#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
1528+
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
1529+
uint8_t * pucQueueStorage,
1530+
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
1531+
{
1532+
QueueSetHandle_t xReturn;
1533+
1534+
if( portIS_PRIVILEGED() == pdFALSE )
1535+
{
1536+
portRAISE_PRIVILEGE();
1537+
portMEMORY_BARRIER();
1538+
1539+
xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );
1540+
portMEMORY_BARRIER();
1541+
1542+
portRESET_PRIVILEGE();
1543+
portMEMORY_BARRIER();
1544+
}
1545+
else
1546+
{
1547+
xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );
1548+
}
1549+
1550+
return xReturn;
1551+
}
1552+
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
1553+
/*-----------------------------------------------------------*/
1554+
15271555
#if ( configUSE_QUEUE_SETS == 1 )
15281556
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
15291557
TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */

portable/Common/mpu_wrappers_v2.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,6 +3016,39 @@
30163016
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
30173017
/*-----------------------------------------------------------*/
30183018

3019+
#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
3020+
3021+
QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength,
3022+
uint8_t * pucQueueStorage,
3023+
StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */
3024+
{
3025+
QueueSetHandle_t xInternalQueueSetHandle = NULL;
3026+
QueueSetHandle_t xExternalQueueSetHandle = NULL;
3027+
int32_t lIndex;
3028+
3029+
lIndex = MPU_GetFreeIndexInKernelObjectPool();
3030+
3031+
if( lIndex != -1 )
3032+
{
3033+
xInternalQueueSetHandle = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue );
3034+
3035+
if( xInternalQueueSetHandle != NULL )
3036+
{
3037+
MPU_StoreQueueSetHandleAtIndex( lIndex, xInternalQueueSetHandle );
3038+
xExternalQueueSetHandle = ( QueueSetHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex );
3039+
}
3040+
else
3041+
{
3042+
MPU_SetIndexFreeInKernelObjectPool( lIndex );
3043+
}
3044+
}
3045+
3046+
return xExternalQueueSetHandle;
3047+
}
3048+
3049+
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
3050+
/*-----------------------------------------------------------*/
3051+
30193052
#if ( configUSE_QUEUE_SETS == 1 )
30203053

30213054
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,

portable/GCC/ARM_AARCH64_SRE/port.c

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@
121121
::"r" ( portUNMASK_VALUE ) ); \
122122
}
123123

124+
/* The space on the stack required to hold the FPU registers.
125+
* There are 32 128-bit plus 2 64-bit status registers.*/
126+
#define portFPU_REGISTER_WORDS ( (32 * 2) + 2 )
127+
124128
/*-----------------------------------------------------------*/
125129

126130
/*
@@ -129,6 +133,27 @@
129133
*/
130134
extern void vPortRestoreTaskContext( void );
131135

136+
/*
137+
* If the application provides an implementation of vApplicationIRQHandler(),
138+
* then it will get called directly without saving the FPU registers on
139+
* interrupt entry, and this weak implementation of
140+
* vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors -
141+
* it should never actually get called so its implementation contains a
142+
* call to configASSERT() that will always fail.
143+
*
144+
* If the application provides its own implementation of
145+
* vApplicationFPUSafeIRQHandler() then the implementation of
146+
* vApplicationIRQHandler() provided in portASM.S will save the FPU registers
147+
* before calling it.
148+
*
149+
* Therefore, if the application writer wants FPU registers to be saved on
150+
* interrupt entry their IRQ handler must be called
151+
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
152+
* FPU registers to be saved on interrupt entry their IRQ handler must be
153+
* called vApplicationIRQHandler().
154+
*/
155+
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
156+
132157
/*-----------------------------------------------------------*/
133158

134159
/* A variable is used to keep track of the critical section nesting. This
@@ -229,23 +254,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
229254
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
230255
pxTopOfStack--;
231256
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
232-
pxTopOfStack--;
233-
234-
*pxTopOfStack = portINITIAL_PSTATE;
235-
pxTopOfStack--;
236257

237-
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
238258
pxTopOfStack--;
259+
*pxTopOfStack = portINITIAL_PSTATE;
239260

240-
/* The task will start with a critical nesting count of 0 as interrupts are
241-
* enabled. */
242-
*pxTopOfStack = portNO_CRITICAL_NESTING;
243261
pxTopOfStack--;
262+
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
244263

245-
/* The task will start without a floating point context. A task that uses
246-
* the floating point hardware must call vPortTaskUsesFPU() before executing
247-
* any floating point instructions. */
248-
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
264+
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
265+
{
266+
/* The task will start with a critical nesting count of 0 as interrupts are
267+
* enabled. */
268+
pxTopOfStack--;
269+
*pxTopOfStack = portNO_CRITICAL_NESTING;
270+
271+
/* The task will start without a floating point context. A task that
272+
* uses the floating point hardware must call vPortTaskUsesFPU() before
273+
* executing any floating point instructions. */
274+
pxTopOfStack--;
275+
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
276+
}
277+
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
278+
{
279+
/* The task will start with a floating point context. Leave enough
280+
* space for the registers - and ensure they are initialised to 0. */
281+
pxTopOfStack -= portFPU_REGISTER_WORDS;
282+
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
283+
284+
/* The task will start with a critical nesting count of 0 as interrupts are
285+
* enabled. */
286+
pxTopOfStack--;
287+
*pxTopOfStack = portNO_CRITICAL_NESTING;
288+
289+
pxTopOfStack--;
290+
*pxTopOfStack = pdTRUE;
291+
ullPortTaskHasFPUContext = pdTRUE;
292+
}
293+
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
294+
{
295+
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
296+
}
297+
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
249298

250299
return pxTopOfStack;
251300
}
@@ -384,6 +433,8 @@ void FreeRTOS_Tick_Handler( void )
384433
}
385434
/*-----------------------------------------------------------*/
386435

436+
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
437+
387438
void vPortTaskUsesFPU( void )
388439
{
389440
/* A task is registering the fact that it needs an FPU context. Set the
@@ -393,6 +444,8 @@ void vPortTaskUsesFPU( void )
393444
/* Consider initialising the FPSR here - but probably not necessary in
394445
* AArch64. */
395446
}
447+
448+
#endif /* configUSE_TASK_FPU_SUPPORT */
396449
/*-----------------------------------------------------------*/
397450

398451
void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
@@ -463,3 +516,9 @@ UBaseType_t uxPortSetInterruptMask( void )
463516

464517
#endif /* configASSERT_DEFINED */
465518
/*-----------------------------------------------------------*/
519+
520+
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
521+
{
522+
( void ) ulICCIAR;
523+
configASSERT( ( volatile void * ) NULL );
524+
}

0 commit comments

Comments
 (0)