Merge branch 'main' into posix-dont-break-external-threads

This commit is contained in:
Rahul Kar 2025-01-23 12:43:42 +05:30 committed by GitHub
commit e6b62d18e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 329 additions and 23 deletions

View file

@ -1484,6 +1484,14 @@
#define traceRETURN_xQueueCreateSet( pxQueue ) #define traceRETURN_xQueueCreateSet( pxQueue )
#endif #endif
#ifndef traceENTER_xQueueCreateSetStatic
#define traceENTER_xQueueCreateSetStatic( uxEventQueueLength )
#endif
#ifndef traceRETURN_xQueueCreateSetStatic
#define traceRETURN_xQueueCreateSetStatic( pxQueue )
#endif
#ifndef traceENTER_xQueueAddToSet #ifndef traceENTER_xQueueAddToSet
#define traceENTER_xQueueAddToSet( xQueueOrSemaphore, xQueueSet ) #define traceENTER_xQueueAddToSet( xQueueOrSemaphore, xQueueSet )
#endif #endif

View file

@ -269,6 +269,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
StaticQueue_t * pxStaticQueue, StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) 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, BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
@ -294,6 +297,9 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
StaticQueue_t * pxStaticQueue, StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) 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, BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,

View file

@ -150,6 +150,7 @@
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueGenericReset MPU_xQueueGenericReset #define xQueueGenericReset MPU_xQueueGenericReset
#define xQueueCreateSet MPU_xQueueCreateSet #define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueCreateSetStatic MPU_xQueueCreateSetStatic
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )

View file

@ -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 * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function. * function.
* *
* A queue set must be explicitly created using a call to xQueueCreateSet() * A queue set must be explicitly created using a call to xQueueCreateSet() or
* before it can be used. Once created, standard FreeRTOS queues and semaphores * xQueueCreateSetStatic() before it can be used. Once created, standard
* can be added to the set using calls to xQueueAddToSet(). * FreeRTOS queues and semaphores can be added to the set using calls to
* xQueueSelectFromSet() is then used to determine which, if any, of the queues * xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if
* or semaphores contained in the set is in a state where a queue read or * any, of the queues or semaphores contained in the set is in a state where a
* semaphore take operation would be successful. * 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 * 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 * 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;
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
#endif #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 * 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 * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function. * function.

View file

@ -1524,6 +1524,34 @@
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ #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 ) #if ( configUSE_QUEUE_SETS == 1 )
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */

View file

@ -3016,6 +3016,39 @@
#endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ #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 ) #if ( configUSE_QUEUE_SETS == 1 )
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,

View file

@ -121,6 +121,10 @@
::"r" ( portUNMASK_VALUE ) ); \ ::"r" ( portUNMASK_VALUE ) ); \
} }
/* The space on the stack required to hold the FPU registers.
* There are 32 128-bit plus 2 64-bit status registers.*/
#define portFPU_REGISTER_WORDS ( (32 * 2) + 2 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -129,6 +133,27 @@
*/ */
extern void vPortRestoreTaskContext( void ); extern void vPortRestoreTaskContext( void );
/*
* If the application provides an implementation of vApplicationIRQHandler(),
* then it will get called directly without saving the FPU registers on
* interrupt entry, and this weak implementation of
* vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors -
* it should never actually get called so its implementation contains a
* call to configASSERT() that will always fail.
*
* If the application provides its own implementation of
* vApplicationFPUSafeIRQHandler() then the implementation of
* vApplicationIRQHandler() provided in portASM.S will save the FPU registers
* before calling it.
*
* Therefore, if the application writer wants FPU registers to be saved on
* interrupt entry their IRQ handler must be called
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
* FPU registers to be saved on interrupt entry their IRQ handler must be
* called vApplicationIRQHandler().
*/
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* A variable is used to keep track of the critical section nesting. This /* A variable is used to keep track of the critical section nesting. This
@ -229,23 +254,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
pxTopOfStack--;
pxTopOfStack--;
*pxTopOfStack = portINITIAL_PSTATE; *pxTopOfStack = portINITIAL_PSTATE;
pxTopOfStack--;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are #if ( configUSE_TASK_FPU_SUPPORT == 1 )
* enabled. */ {
*pxTopOfStack = portNO_CRITICAL_NESTING; /* The task will start with a critical nesting count of 0 as interrupts are
pxTopOfStack--; * enabled. */
pxTopOfStack--;
*pxTopOfStack = portNO_CRITICAL_NESTING;
/* The task will start without a floating point context. A task that uses /* The task will start without a floating point context. A task that
* the floating point hardware must call vPortTaskUsesFPU() before executing * uses the floating point hardware must call vPortTaskUsesFPU() before
* any floating point instructions. */ * executing any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; pxTopOfStack--;
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
}
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
{
/* The task will start with a floating point context. Leave enough
* space for the registers - and ensure they are initialised to 0. */
pxTopOfStack -= portFPU_REGISTER_WORDS;
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
/* The task will start with a critical nesting count of 0 as interrupts are
* enabled. */
pxTopOfStack--;
*pxTopOfStack = portNO_CRITICAL_NESTING;
pxTopOfStack--;
*pxTopOfStack = pdTRUE;
ullPortTaskHasFPUContext = pdTRUE;
}
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
{
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
}
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
return pxTopOfStack; return pxTopOfStack;
} }
@ -384,6 +433,8 @@ void FreeRTOS_Tick_Handler( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
void vPortTaskUsesFPU( void ) void vPortTaskUsesFPU( void )
{ {
/* A task is registering the fact that it needs an FPU context. Set the /* A task is registering the fact that it needs an FPU context. Set the
@ -393,6 +444,8 @@ void vPortTaskUsesFPU( void )
/* Consider initialising the FPSR here - but probably not necessary in /* Consider initialising the FPSR here - but probably not necessary in
* AArch64. */ * AArch64. */
} }
#endif /* configUSE_TASK_FPU_SUPPORT */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
@ -463,3 +516,9 @@ UBaseType_t uxPortSetInterruptMask( void )
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
{
( void ) ulICCIAR;
configASSERT( ( volatile void * ) NULL );
}

View file

@ -87,7 +87,7 @@
LDR X0, ullPortTaskHasFPUContextConst LDR X0, ullPortTaskHasFPUContextConst
LDR X2, [X0] LDR X2, [X0]
/* Save the FPU context, if any (32 128-bit registers). */ /* Save the FPU context, if any (32 128-bit plus two 64-bit status registers). */
CMP X2, #0 CMP X2, #0
B.EQ 1f B.EQ 1f
STP Q0, Q1, [SP,#-0x20]! STP Q0, Q1, [SP,#-0x20]!
@ -107,6 +107,11 @@
STP Q28, Q29, [SP,#-0x20]! STP Q28, Q29, [SP,#-0x20]!
STP Q30, Q31, [SP,#-0x20]! STP Q30, Q31, [SP,#-0x20]!
/* Even though upper 32 bits of FPSR and FPCR are reserved, save and restore the whole 64 bits to keep 16-byte SP alignement. */
MRS X9, FPSR
MRS X10, FPCR
STP X9, X10, [SP, #-0x10]!
1: 1:
/* Store the critical nesting count and FPU context indicator. */ /* Store the critical nesting count and FPU context indicator. */
STP X2, X3, [SP, #-0x10]! STP X2, X3, [SP, #-0x10]!
@ -157,6 +162,7 @@
/* Restore the FPU context, if any. */ /* Restore the FPU context, if any. */
CMP X2, #0 CMP X2, #0
B.EQ 1f B.EQ 1f
LDP X9, X10, [SP], #0x10
LDP Q30, Q31, [SP], #0x20 LDP Q30, Q31, [SP], #0x20
LDP Q28, Q29, [SP], #0x20 LDP Q28, Q29, [SP], #0x20
LDP Q26, Q27, [SP], #0x20 LDP Q26, Q27, [SP], #0x20
@ -173,6 +179,8 @@
LDP Q4, Q5, [SP], #0x20 LDP Q4, Q5, [SP], #0x20
LDP Q2, Q3, [SP], #0x20 LDP Q2, Q3, [SP], #0x20
LDP Q0, Q1, [SP], #0x20 LDP Q0, Q1, [SP], #0x20
MSR FPSR, X9
MSR FPCR, X10
1: 1:
LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */
@ -406,8 +414,82 @@ Exit_IRQ_No_Context_Switch:
ERET ERET
/******************************************************************************
* If the application provides an implementation of vApplicationIRQHandler(),
* then it will get called directly without saving the FPU registers on
* interrupt entry, and this weak implementation of
* vApplicationIRQHandler() will not get called.
*
* If the application provides its own implementation of
* vApplicationFPUSafeIRQHandler() then this implementation of
* vApplicationIRQHandler() will be called, save the FPU registers, and then
* call vApplicationFPUSafeIRQHandler().
*
* Therefore, if the application writer wants FPU registers to be saved on
* interrupt entry their IRQ handler must be called
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
* FPU registers to be saved on interrupt entry their IRQ handler must be
* called vApplicationIRQHandler().
*****************************************************************************/
.align 8
.weak vApplicationIRQHandler
.type vApplicationIRQHandler, %function
vApplicationIRQHandler:
/* Save LR and FP on the stack */
STP X29, X30, [SP, #-0x10]!
/* Save FPU registers (32 128-bits + 2 64-bits configuration and status registers) */
STP Q0, Q1, [SP,#-0x20]!
STP Q2, Q3, [SP,#-0x20]!
STP Q4, Q5, [SP,#-0x20]!
STP Q6, Q7, [SP,#-0x20]!
STP Q8, Q9, [SP,#-0x20]!
STP Q10, Q11, [SP,#-0x20]!
STP Q12, Q13, [SP,#-0x20]!
STP Q14, Q15, [SP,#-0x20]!
STP Q16, Q17, [SP,#-0x20]!
STP Q18, Q19, [SP,#-0x20]!
STP Q20, Q21, [SP,#-0x20]!
STP Q22, Q23, [SP,#-0x20]!
STP Q24, Q25, [SP,#-0x20]!
STP Q26, Q27, [SP,#-0x20]!
STP Q28, Q29, [SP,#-0x20]!
STP Q30, Q31, [SP,#-0x20]!
/* Even though upper 32 bits of FPSR and FPCR are reserved, save and restore the whole 64 bits to keep 16-byte SP alignement. */
MRS X9, FPSR
MRS X10, FPCR
STP X9, X10, [SP, #-0x10]!
/* Call the C handler. */
BL vApplicationFPUSafeIRQHandler
/* Restore FPU registers */
LDP X9, X10, [SP], #0x10
LDP Q30, Q31, [SP], #0x20
LDP Q28, Q29, [SP], #0x20
LDP Q26, Q27, [SP], #0x20
LDP Q24, Q25, [SP], #0x20
LDP Q22, Q23, [SP], #0x20
LDP Q20, Q21, [SP], #0x20
LDP Q18, Q19, [SP], #0x20
LDP Q16, Q17, [SP], #0x20
LDP Q14, Q15, [SP], #0x20
LDP Q12, Q13, [SP], #0x20
LDP Q10, Q11, [SP], #0x20
LDP Q8, Q9, [SP], #0x20
LDP Q6, Q7, [SP], #0x20
LDP Q4, Q5, [SP], #0x20
LDP Q2, Q3, [SP], #0x20
LDP Q0, Q1, [SP], #0x20
MSR FPSR, X9
MSR FPCR, X10
/* Restore FP and LR */
LDP X29, X30, [SP], #0x10
RET
.align 8 .align 8
pxCurrentTCBConst: .dword pxCurrentTCB pxCurrentTCBConst: .dword pxCurrentTCB

View file

@ -135,9 +135,18 @@ extern void vPortInstallFreeRTOSVectorTable( void );
* handler for whichever peripheral is used to generate the RTOS tick. */ * handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void ); void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() /* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
* before any floating point instructions are executed. */ * created without an FPU context and must call vPortTaskUsesFPU() to give
void vPortTaskUsesFPU( void ); * themselves an FPU context before using any FPU instructions. If
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
* by default. */
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
void vPortTaskUsesFPU( void );
#else
/* Each task has an FPU context already, so define this function away to
* nothing to prevent it from being called accidentally. */
#define vPortTaskUsesFPU()
#endif
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )

22
queue.c
View file

@ -3186,7 +3186,27 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
return pxQueue; 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 ) #if ( configUSE_QUEUE_SETS == 1 )