Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add port-optimised task selection for ARMv8-M #703

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions portable/ARMv8M/non_secure/port.c
Expand Up @@ -495,13 +495,13 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* FreeRTOS API functions are not called from interrupts that have been assigned
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
*/
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )

static uint8_t ucMaxSysCallPriority = 0;
static uint32_t ulMaxPRIGROUPValue = 0;
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;

#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */

#if ( configUSE_TICKLESS_IDLE == 1 )

Expand Down Expand Up @@ -1614,7 +1614,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,

BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
{
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
{
volatile uint32_t ulOriginalPriority;
volatile uint32_t ulImplementedPrioBits = 0;
Expand Down Expand Up @@ -1695,7 +1695,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
* value. */
portNVIC_SHPR2_REG = ulOriginalPriority;
}
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */

/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
Expand Down Expand Up @@ -1936,7 +1936,7 @@ BaseType_t xPortIsInsideInterrupt( void )
}
/*-----------------------------------------------------------*/

#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )

void vPortValidateInterruptPriority( void )
{
Expand Down Expand Up @@ -1994,5 +1994,5 @@ BaseType_t xPortIsInsideInterrupt( void )
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}

#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/
Expand Up @@ -48,9 +48,9 @@
/**
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M23"
#define portHAS_BASEPRI 0
#define portDONT_DISCARD __attribute__( ( used ) )
#define portARCH_NAME "Cortex-M23"
#define portHAS_ARMV8M_MAIN_EXTENSION 0
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

/* ARMv8-M common port configurations. */
Expand Down
Expand Up @@ -48,9 +48,9 @@
/**
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M23"
#define portHAS_BASEPRI 0
#define portDONT_DISCARD __attribute__( ( used ) )
#define portARCH_NAME "Cortex-M23"
#define portHAS_ARMV8M_MAIN_EXTENSION 0
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

/* ARMv8-M common port configurations. */
Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M33"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M33"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M35P"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -54,7 +54,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M55"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -54,7 +54,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M85"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -48,9 +48,9 @@
/**
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M23"
#define portHAS_BASEPRI 0
#define portDONT_DISCARD __root
#define portARCH_NAME "Cortex-M23"
#define portHAS_ARMV8M_MAIN_EXTENSION 0
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

/* ARMv8-M common port configurations. */
Expand Down
Expand Up @@ -48,9 +48,9 @@
/**
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M23"
#define portHAS_BASEPRI 0
#define portDONT_DISCARD __root
#define portARCH_NAME "Cortex-M23"
#define portHAS_ARMV8M_MAIN_EXTENSION 0
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

/* ARMv8-M common port configurations. */
Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M33"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M33"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -49,7 +49,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M35P"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -54,7 +54,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M55"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

Expand Down
Expand Up @@ -54,7 +54,7 @@
* Architecture specifics.
*/
#define portARCH_NAME "Cortex-M85"
#define portHAS_BASEPRI 1
#define portHAS_ARMV8M_MAIN_EXTENSION 1
#define portDONT_DISCARD __root
/*-----------------------------------------------------------*/

Expand Down
118 changes: 84 additions & 34 deletions portable/ARMv8M/non_secure/portmacrocommon.h
Expand Up @@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL

/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
Expand Down Expand Up @@ -307,7 +307,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
* system calls.
*/
#ifdef configASSERT
#if ( portHAS_BASEPRI == 1 )
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif
Expand Down Expand Up @@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P

#if ( configENABLE_TRUSTZONE == 1 )

/**
* @brief Allocate a secure context for the task.
*
* Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function.
*
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/**
* @brief Allocate a secure context for the task.
*
* Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function.
*
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )

/**
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one.
*
* @param[in] pxTCB The TCB of the task being deleted.
*/
/**
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one.
*
* @param[in] pxTCB The TCB of the task being deleted.
*/
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/

#if ( configENABLE_MPU == 1 )

/**
* @brief Checks whether or not the processor is privileged.
*
* @return 1 if the processor is already privileged, 0 otherwise.
*/
/**
* @brief Checks whether or not the processor is privileged.
*
* @return 1 if the processor is already privileged, 0 otherwise.
*/
#define portIS_PRIVILEGED() xIsPrivileged()

/**
* @brief Raise an SVC request to raise privilege.
*
* The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place,
* the privilege is not raised.
*/
/**
* @brief Raise an SVC request to raise privilege.
*
* The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place,
* the privilege is not raised.
*/
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );

/**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register.
*/
/**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register.
*/
#define portRESET_PRIVILEGE() vResetPrivilege()
#else
#define portIS_PRIVILEGED()
Expand Down Expand Up @@ -435,6 +435,56 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/

/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
* based on whether or not Mainline extension is implemented. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#else
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#endif
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */

/**
* @brief Port-optimised task selection.
*/
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )

/**
* @brief Count the number of leading zeros in a 32-bit value.
*/
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
{
uint32_t ulReturn;

__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );

return ulReturn;
}

/* Check the configuration. */
#if ( configMAX_PRIORITIES > 32 )
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
#endif

#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
#endif

/**
* @brief Store/clear the ready priorities in a bit map.
*/
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )

/**
* @brief Get the priority of the highest-priority task that is ready to execute.
*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )

#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/*-----------------------------------------------------------*/

/* *INDENT-OFF* */
#ifdef __cplusplus
}
Expand Down
12 changes: 6 additions & 6 deletions portable/GCC/ARM_CM23/non_secure/port.c
Expand Up @@ -495,13 +495,13 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* FreeRTOS API functions are not called from interrupts that have been assigned
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
*/
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )

static uint8_t ucMaxSysCallPriority = 0;
static uint32_t ulMaxPRIGROUPValue = 0;
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;

#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */

#if ( configUSE_TICKLESS_IDLE == 1 )

Expand Down Expand Up @@ -1614,7 +1614,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,

BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
{
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
{
volatile uint32_t ulOriginalPriority;
volatile uint32_t ulImplementedPrioBits = 0;
Expand Down Expand Up @@ -1695,7 +1695,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
* value. */
portNVIC_SHPR2_REG = ulOriginalPriority;
}
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */

/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
Expand Down Expand Up @@ -1936,7 +1936,7 @@ BaseType_t xPortIsInsideInterrupt( void )
}
/*-----------------------------------------------------------*/

#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) )
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )

void vPortValidateInterruptPriority( void )
{
Expand Down Expand Up @@ -1994,5 +1994,5 @@ BaseType_t xPortIsInsideInterrupt( void )
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}

#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/