Cortex-M Assert when NVIC implements 8 PRIO bits (#639)
* Cortex-M Assert when NVIC implements 8 PRIO bits
* Fix CM3 ports
* Fix ARM_CM3_MPU
* Fix ARM CM3
* Fix ARM_CM4_MPU
* Fix ARM_CM4
* Fix GCC ARM_CM7
* Fix IAR ARM ports
* Uncrustify changes
* Fix MikroC_ARM_CM4F port
* Fix MikroC_ARM_CM4F port-(2)
* Fix RVDS ARM ports
* Revert changes for Tasking/ARM_CM4F port
* Revert changes for Tasking/ARM_CM4F port-(2)
* Update port.c
Fix GCC/ARM_CM4F port
* Update port.c
* update GCC\ARM_CM4F port
* update port.c
* Assert to check configMAX_SYSCALL_INTERRUPT_PRIORITY is set to higher priority
* Fix merge error: remove duplicate code
* Fix typos
---------
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-17-174.ec2.internal>
diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c
old mode 100644
new mode 100755
index dfdb240..63dc600
--- a/portable/CCS/ARM_CM3/port.c
+++ b/portable/CCS/ARM_CM3/port.c
@@ -219,6 +219,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -250,20 +251,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -272,7 +299,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -379,9 +406,9 @@
/* Enter a critical section but don't use the taskENTER_CRITICAL()
* method as that will mask interrupts that should exit sleep mode. */
- __asm( " cpsid i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsid i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* If a context switch is pending or a task is waiting for the scheduler
* to be unsuspended then abandon the low power entry. */
@@ -389,7 +416,7 @@
{
/* Re-enable interrupts - see comments above the cpsid instruction
* above. */
- __asm( " cpsie i");
+ __asm( " cpsie i" );
}
else
{
@@ -450,9 +477,9 @@
if( xModifiableIdleTime > 0 )
{
- __asm( " dsb");
- __asm( " wfi");
- __asm( " isb");
+ __asm( " dsb" );
+ __asm( " wfi" );
+ __asm( " isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
@@ -460,17 +487,17 @@
/* Re-enable interrupts to allow the interrupt that brought the MCU
* out of sleep mode to execute immediately. See comments above
* the cpsid instruction above. */
- __asm( " cpsie i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsie i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* Disable interrupts again because the clock is about to be stopped
* and interrupts that execute while the clock is stopped will increase
* any slippage between the time maintained by the RTOS and calendar
* time. */
- __asm( " cpsid i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsid i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* Disable the SysTick clock without reading the
* portNVIC_SYSTICK_CTRL_REG register to ensure the
@@ -578,7 +605,7 @@
vTaskStepTick( ulCompleteTickPeriods );
/* Exit with interrupts enabled. */
- __asm( " cpsie i");
+ __asm( " cpsie i" );
}
}
diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c
old mode 100644
new mode 100755
index 360e83d..a741b09
--- a/portable/CCS/ARM_CM4F/port.c
+++ b/portable/CCS/ARM_CM4F/port.c
@@ -238,6 +238,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -269,20 +270,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -291,7 +318,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -404,9 +431,9 @@
/* Enter a critical section but don't use the taskENTER_CRITICAL()
* method as that will mask interrupts that should exit sleep mode. */
- __asm( " cpsid i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsid i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* If a context switch is pending or a task is waiting for the scheduler
* to be unsuspended then abandon the low power entry. */
@@ -414,7 +441,7 @@
{
/* Re-enable interrupts - see comments above the cpsid instruction
* above. */
- __asm( " cpsie i");
+ __asm( " cpsie i" );
}
else
{
@@ -475,9 +502,9 @@
if( xModifiableIdleTime > 0 )
{
- __asm( " dsb");
- __asm( " wfi");
- __asm( " isb");
+ __asm( " dsb" );
+ __asm( " wfi" );
+ __asm( " isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
@@ -485,17 +512,17 @@
/* Re-enable interrupts to allow the interrupt that brought the MCU
* out of sleep mode to execute immediately. See comments above
* the cpsid instruction above. */
- __asm( " cpsie i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsie i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* Disable interrupts again because the clock is about to be stopped
* and interrupts that execute while the clock is stopped will increase
* any slippage between the time maintained by the RTOS and calendar
* time. */
- __asm( " cpsid i");
- __asm( " dsb");
- __asm( " isb");
+ __asm( " cpsid i" );
+ __asm( " dsb" );
+ __asm( " isb" );
/* Disable the SysTick clock without reading the
* portNVIC_SYSTICK_CTRL_REG register to ensure the
@@ -603,7 +630,7 @@
vTaskStepTick( ulCompleteTickPeriods );
/* Exit with interrupts enabled. */
- __asm( " cpsie i");
+ __asm( " cpsie i" );
}
}
diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c
old mode 100644
new mode 100755
index a5cea1e..57337e6
--- a/portable/GCC/ARM_CM3/port.c
+++ b/portable/GCC/ARM_CM3/port.c
@@ -262,6 +262,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -293,20 +294,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -315,7 +342,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -756,4 +783,4 @@
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
-#endif /* configASSERT_DEFINED */
+#endif /* configASSERT_DEFINED */
\ No newline at end of file
diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c
old mode 100644
new mode 100755
index 5f7d2c8..4b21236
--- a/portable/GCC/ARM_CM3_MPU/port.c
+++ b/portable/GCC/ARM_CM3_MPU/port.c
@@ -385,6 +385,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -416,20 +417,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -438,7 +465,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -923,4 +950,4 @@
}
#endif /* configASSERT_DEFINED */
-/*-----------------------------------------------------------*/
+/*-----------------------------------------------------------*/
\ No newline at end of file
diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c
old mode 100644
new mode 100755
index b978f0a..84e7913
--- a/portable/GCC/ARM_CM4F/port.c
+++ b/portable/GCC/ARM_CM4F/port.c
@@ -251,11 +251,11 @@
void vPortSVCHandler( void )
{
__asm volatile (
- " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */
- " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
- " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
- " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
- " msr psp, r0 \n"/* Restore the task stack pointer. */
+ " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
+ " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
+ " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
+ " msr psp, r0 \n" /* Restore the task stack pointer. */
" isb \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
@@ -274,17 +274,17 @@
* would otherwise result in the unnecessary leaving of space in the SVC stack
* for lazy saving of FPU registers. */
__asm volatile (
- " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */
+ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
- " msr msp, r0 \n"/* Set the msp back to the start of the stack. */
- " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */
+ " msr msp, r0 \n" /* Set the msp back to the start of the stack. */
+ " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
" msr control, r0 \n"
- " cpsie i \n"/* Globally enable interrupts. */
+ " cpsie i \n" /* Globally enable interrupts. */
" cpsie f \n"
" dsb \n"
" isb \n"
- " svc 0 \n"/* System call to start first task. */
+ " svc 0 \n" /* System call to start first task. */
" nop \n"
" .ltorg \n"
);
@@ -305,6 +305,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -336,20 +337,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -358,7 +385,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -453,15 +480,15 @@
" mrs r0, psp \n"
" isb \n"
" \n"
- " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
+ " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3] \n"
" \n"
- " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */
+ " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
" it eq \n"
" vstmdbeq r0!, {s16-s31} \n"
" \n"
- " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */
- " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */
+ " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
+ " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
" \n"
" stmdb sp!, {r0, r3} \n"
" mov r0, %0 \n"
@@ -473,12 +500,12 @@
" msr basepri, r0 \n"
" ldmia sp!, {r0, r3} \n"
" \n"
- " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
+ " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldr r0, [r1] \n"
" \n"
- " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */
+ " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */
" \n"
- " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */
+ " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */
" it eq \n"
" vldmiaeq r0!, {s16-s31} \n"
" \n"
@@ -772,10 +799,10 @@
{
__asm volatile
(
- " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */
+ " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */
" ldr r1, [r0] \n"
" \n"
- " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */
+ " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */
" str r1, [r0] \n"
" bx r14 \n"
" .ltorg \n"
diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c
old mode 100644
new mode 100755
index 57d0ea5..682b64e
--- a/portable/GCC/ARM_CM4_MPU/port.c
+++ b/portable/GCC/ARM_CM4_MPU/port.c
@@ -428,6 +428,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -459,20 +460,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -481,7 +508,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -1046,4 +1073,4 @@
}
#endif /* configASSERT_DEFINED */
-/*-----------------------------------------------------------*/
+/*-----------------------------------------------------------*/
\ No newline at end of file
diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c
old mode 100644
new mode 100755
index c602bd2..25a06bf
--- a/portable/GCC/ARM_CM7/r0p1/port.c
+++ b/portable/GCC/ARM_CM7/r0p1/port.c
@@ -245,11 +245,11 @@
void vPortSVCHandler( void )
{
__asm volatile (
- " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */
- " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
- " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
- " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
- " msr psp, r0 \n"/* Restore the task stack pointer. */
+ " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
+ " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
+ " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
+ " msr psp, r0 \n" /* Restore the task stack pointer. */
" isb \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
@@ -268,17 +268,17 @@
* would otherwise result in the unnecessary leaving of space in the SVC stack
* for lazy saving of FPU registers. */
__asm volatile (
- " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */
+ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
- " msr msp, r0 \n"/* Set the msp back to the start of the stack. */
- " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */
+ " msr msp, r0 \n" /* Set the msp back to the start of the stack. */
+ " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
" msr control, r0 \n"
- " cpsie i \n"/* Globally enable interrupts. */
+ " cpsie i \n" /* Globally enable interrupts. */
" cpsie f \n"
" dsb \n"
" isb \n"
- " svc 0 \n"/* System call to start first task. */
+ " svc 0 \n" /* System call to start first task. */
" nop \n"
" .ltorg \n"
);
@@ -293,6 +293,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -324,20 +325,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -346,7 +373,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
@@ -441,34 +468,34 @@
" mrs r0, psp \n"
" isb \n"
" \n"
- " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
+ " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3] \n"
" \n"
- " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */
+ " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
" it eq \n"
" vstmdbeq r0!, {s16-s31} \n"
" \n"
- " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */
- " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */
+ " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
+ " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
" \n"
" stmdb sp!, {r0, r3} \n"
" mov r0, %0 \n"
- " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ " cpsid i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" msr basepri, r0 \n"
" dsb \n"
" isb \n"
- " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ " cpsie i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
" ldmia sp!, {r0, r3} \n"
" \n"
- " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
+ " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldr r0, [r1] \n"
" \n"
- " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */
+ " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */
" \n"
- " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */
+ " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */
" it eq \n"
" vldmiaeq r0!, {s16-s31} \n"
" \n"
@@ -762,10 +789,10 @@
{
__asm volatile
(
- " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */
+ " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */
" ldr r1, [r0] \n"
" \n"
- " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */
+ " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */
" str r1, [r0] \n"
" bx r14 \n"
" .ltorg \n"
diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c
old mode 100644
new mode 100755
index f35ee98..a7a5ad8
--- a/portable/IAR/ARM_CM3/port.c
+++ b/portable/IAR/ARM_CM3/port.c
@@ -211,6 +211,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -242,20 +243,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -264,7 +291,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c
old mode 100644
new mode 100755
index 90be11d..9b4ed52
--- a/portable/IAR/ARM_CM4F/port.c
+++ b/portable/IAR/ARM_CM4F/port.c
@@ -249,6 +249,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -280,20 +281,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -302,7 +329,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c
old mode 100644
new mode 100755
index dd6bde2..6aec5b3
--- a/portable/IAR/ARM_CM4F_MPU/port.c
+++ b/portable/IAR/ARM_CM4F_MPU/port.c
@@ -194,7 +194,7 @@
/**
* @brief Enter critical section.
*/
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
#else
void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
@@ -203,7 +203,7 @@
/**
* @brief Exit from critical section.
*/
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
#else
void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
@@ -316,9 +316,9 @@
{
__asm volatile
(
- " mrs r1, control \n"/* Obtain current control value. */
- " bic r1, r1, #1 \n"/* Set privilege bit. */
- " msr control, r1 \n"/* Write back new control value. */
+ " mrs r1, control \n" /* Obtain current control value. */
+ " bic r1, r1, #1 \n" /* Set privilege bit. */
+ " msr control, r1 \n" /* Write back new control value. */
::: "r1", "memory"
);
}
@@ -328,9 +328,9 @@
case portSVC_RAISE_PRIVILEGE:
__asm volatile
(
- " mrs r1, control \n"/* Obtain current control value. */
- " bic r1, r1, #1 \n"/* Set privilege bit. */
- " msr control, r1 \n"/* Write back new control value. */
+ " mrs r1, control \n" /* Obtain current control value. */
+ " bic r1, r1, #1 \n" /* Set privilege bit. */
+ " msr control, r1 \n" /* Write back new control value. */
::: "r1", "memory"
);
break;
@@ -352,6 +352,7 @@
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
#else
+
/* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
* configENABLE_ERRATA_837070_WORKAROUND to 1 in your
* FreeRTOSConfig.h. */
@@ -360,74 +361,101 @@
#endif
#if ( configASSERT_DEFINED == 1 )
+ {
+ volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
+ volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
+ volatile uint8_t ucMaxPriorityValue;
+
+ /* Determine the maximum priority from which ISR safe FreeRTOS API
+ * functions can be called. ISR safe functions are those that end in
+ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
+ * ensure interrupt entry is as fast and simple as possible.
+ *
+ * Save the interrupt priority value that is about to be clobbered. */
+ ulOriginalPriority = *pucFirstUserPriorityRegister;
+
+ /* Determine the number of priority bits available. First write to all
+ * possible bits. */
+ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
+
+ /* Read the value back to see how many bits stuck. */
+ ucMaxPriorityValue = *pucFirstUserPriorityRegister;
+
+ /* Use the same mask on the maximum system call priority. */
+ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
+
+ /* Check that the maximum system call priority is nonzero after
+ * accounting for the number of priority bits supported by the
+ * hardware. A priority of 0 is invalid because setting the BASEPRI
+ * register to 0 unmasks all interrupts, and interrupts with priority 0
+ * cannot be masked using BASEPRI.
+ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
+ configASSERT( ucMaxSysCallPriority );
+
+ /* Calculate the maximum acceptable priority group value for the number
+ * of bits read back. */
+
+ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- volatile uint32_t ulOriginalPriority;
- volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
- volatile uint8_t ucMaxPriorityValue;
-
- /* Determine the maximum priority from which ISR safe FreeRTOS API
- * functions can be called. ISR safe functions are those that end in
- * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
- * ensure interrupt entry is as fast and simple as possible.
- *
- * Save the interrupt priority value that is about to be clobbered. */
- ulOriginalPriority = *pucFirstUserPriorityRegister;
-
- /* Determine the number of priority bits available. First write to all
- * possible bits. */
- *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
-
- /* Read the value back to see how many bits stuck. */
- ucMaxPriorityValue = *pucFirstUserPriorityRegister;
-
- /* Use the same mask on the maximum system call priority. */
- ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
-
- /* Check that the maximum system call priority is nonzero after
- * accounting for the number of priority bits supported by the
- * hardware. A priority of 0 is invalid because setting the BASEPRI
- * register to 0 unmasks all interrupts, and interrupts with priority 0
- * cannot be masked using BASEPRI.
- * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
- configASSERT( ucMaxSysCallPriority );
-
- /* Calculate the maximum acceptable priority group value for the number
- * of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
-
- while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
- {
- ulMaxPRIGROUPValue--;
- ucMaxPriorityValue <<= ( uint8_t ) 0x01;
- }
-
- #ifdef __NVIC_PRIO_BITS
- {
- /* Check the CMSIS configuration that defines the number of
- * priority bits matches the number of priority bits actually queried
- * from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
- }
- #endif
-
- #ifdef configPRIO_BITS
- {
- /* Check the FreeRTOS configuration that defines the number of
- * priority bits matches the number of priority bits actually queried
- * from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
- }
- #endif
-
- /* Shift the priority group value back to its position within the AIRCR
- * register. */
- ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
- ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
-
- /* Restore the clobbered interrupt priority register to its original
- * value. */
- *pucFirstUserPriorityRegister = ulOriginalPriority;
+ ulImplementedPrioBits++;
+ ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
+ #ifdef __NVIC_PRIO_BITS
+ {
+ /* Check the CMSIS configuration that defines the number of
+ * priority bits matches the number of priority bits actually queried
+ * from the hardware. */
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
+ }
+ #endif
+
+ #ifdef configPRIO_BITS
+ {
+ /* Check the FreeRTOS configuration that defines the number of
+ * priority bits matches the number of priority bits actually queried
+ * from the hardware. */
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
+ }
+ #endif
+
+ /* Shift the priority group value back to its position within the AIRCR
+ * register. */
+ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
+ ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
+
+ /* Restore the clobbered interrupt priority register to its original
+ * value. */
+ *pucFirstUserPriorityRegister = ulOriginalPriority;
+ }
#endif /* configASSERT_DEFINED */
/* Make PendSV and SysTick the lowest priority interrupts. */
@@ -468,14 +496,49 @@
void vPortEnterCritical( void )
{
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
- if( portIS_PRIVILEGED() == pdFALSE )
- {
- portRAISE_PRIVILEGE();
- portMEMORY_BARRIER();
+ #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ if( portIS_PRIVILEGED() == pdFALSE )
+ {
+ portRAISE_PRIVILEGE();
+ portMEMORY_BARRIER();
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+
+ /* This is not the interrupt safe version of the enter critical function so
+ * assert() if it is being called from an interrupt context. Only API
+ * functions that end in "FromISR" can be used in an interrupt. Only assert if
+ * the critical nesting count is 1 to protect against recursive calls if the
+ * assert function also uses a critical section. */
+ if( uxCriticalNesting == 1 )
+ {
+ configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
+ }
+
+ portMEMORY_BARRIER();
+
+ portRESET_PRIVILEGE();
+ portMEMORY_BARRIER();
+ }
+ else
+ {
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+
+ /* This is not the interrupt safe version of the enter critical function so
+ * assert() if it is being called from an interrupt context. Only API
+ * functions that end in "FromISR" can be used in an interrupt. Only assert if
+ * the critical nesting count is 1 to protect against recursive calls if the
+ * assert function also uses a critical section. */
+ if( uxCriticalNesting == 1 )
+ {
+ configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
+ }
+ }
+ #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
+
/* This is not the interrupt safe version of the enter critical function so
* assert() if it is being called from an interrupt context. Only API
* functions that end in "FromISR" can be used in an interrupt. Only assert if
@@ -485,49 +548,42 @@
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
- portMEMORY_BARRIER();
-
- portRESET_PRIVILEGE();
- portMEMORY_BARRIER();
- }
- else
- {
- portDISABLE_INTERRUPTS();
- uxCriticalNesting++;
- /* This is not the interrupt safe version of the enter critical function so
- * assert() if it is being called from an interrupt context. Only API
- * functions that end in "FromISR" can be used in an interrupt. Only assert if
- * the critical nesting count is 1 to protect against recursive calls if the
- * assert function also uses a critical section. */
- if( uxCriticalNesting == 1 )
- {
- configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
- }
- }
-#else
- portDISABLE_INTERRUPTS();
- uxCriticalNesting++;
- /* This is not the interrupt safe version of the enter critical function so
- * assert() if it is being called from an interrupt context. Only API
- * functions that end in "FromISR" can be used in an interrupt. Only assert if
- * the critical nesting count is 1 to protect against recursive calls if the
- * assert function also uses a critical section. */
- if( uxCriticalNesting == 1 )
- {
- configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
- }
-#endif
+ #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
- if( portIS_PRIVILEGED() == pdFALSE )
- {
- portRAISE_PRIVILEGE();
- portMEMORY_BARRIER();
+ #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ if( portIS_PRIVILEGED() == pdFALSE )
+ {
+ portRAISE_PRIVILEGE();
+ portMEMORY_BARRIER();
+ configASSERT( uxCriticalNesting );
+ uxCriticalNesting--;
+
+ if( uxCriticalNesting == 0 )
+ {
+ portENABLE_INTERRUPTS();
+ }
+
+ portMEMORY_BARRIER();
+
+ portRESET_PRIVILEGE();
+ portMEMORY_BARRIER();
+ }
+ else
+ {
+ configASSERT( uxCriticalNesting );
+ uxCriticalNesting--;
+
+ if( uxCriticalNesting == 0 )
+ {
+ portENABLE_INTERRUPTS();
+ }
+ }
+ #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
@@ -535,30 +591,7 @@
{
portENABLE_INTERRUPTS();
}
- portMEMORY_BARRIER();
-
- portRESET_PRIVILEGE();
- portMEMORY_BARRIER();
- }
- else
- {
- configASSERT( uxCriticalNesting );
- uxCriticalNesting--;
-
- if( uxCriticalNesting == 0 )
- {
- portENABLE_INTERRUPTS();
- }
- }
-#else
- configASSERT( uxCriticalNesting );
- uxCriticalNesting--;
-
- if( uxCriticalNesting == 0 )
- {
- portENABLE_INTERRUPTS();
- }
-#endif
+ #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/
@@ -710,7 +743,7 @@
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
( portMPU_REGION_VALID ) |
- ( portSTACK_REGION ); /* Region number. */
+ ( portSTACK_REGION ); /* Region number. */
xMPUSettings->xRegion[ 0 ].ulRegionAttribute =
( portMPU_REGION_READ_WRITE ) |
diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c
old mode 100644
new mode 100755
index e9e3805..1c53fa9
--- a/portable/IAR/ARM_CM7/r0p1/port.c
+++ b/portable/IAR/ARM_CM7/r0p1/port.c
@@ -237,6 +237,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -268,20 +269,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -290,7 +317,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c
old mode 100644
new mode 100755
index 886913f..8e314b6
--- a/portable/MikroC/ARM_CM4F/port.c
+++ b/portable/MikroC/ARM_CM4F/port.c
@@ -299,6 +299,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -330,20 +331,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -352,7 +379,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c
old mode 100644
new mode 100755
index ac4bef2..e1bfc6a
--- a/portable/RVDS/ARM_CM3/port.c
+++ b/portable/RVDS/ARM_CM3/port.c
@@ -264,6 +264,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -295,20 +296,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -317,7 +344,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c
old mode 100644
new mode 100755
index cdc063d..5233533
--- a/portable/RVDS/ARM_CM4F/port.c
+++ b/portable/RVDS/ARM_CM4F/port.c
@@ -330,6 +330,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -361,20 +362,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -383,7 +410,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c
old mode 100644
new mode 100755
index b9c7f90..d9978a9
--- a/portable/RVDS/ARM_CM4_MPU/port.c
+++ b/portable/RVDS/ARM_CM4_MPU/port.c
@@ -201,7 +201,7 @@
/**
* @brief Enter critical section.
*/
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
#else
void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
@@ -210,7 +210,7 @@
/**
* @brief Exit from critical section.
*/
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
#else
void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
@@ -412,6 +412,7 @@
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
#else
+
/* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
* configENABLE_ERRATA_837070_WORKAROUND to 1 in your
* FreeRTOSConfig.h. */
@@ -420,74 +421,101 @@
#endif
#if ( configASSERT_DEFINED == 1 )
+ {
+ volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
+ volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
+ volatile uint8_t ucMaxPriorityValue;
+
+ /* Determine the maximum priority from which ISR safe FreeRTOS API
+ * functions can be called. ISR safe functions are those that end in
+ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
+ * ensure interrupt entry is as fast and simple as possible.
+ *
+ * Save the interrupt priority value that is about to be clobbered. */
+ ulOriginalPriority = *pucFirstUserPriorityRegister;
+
+ /* Determine the number of priority bits available. First write to all
+ * possible bits. */
+ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
+
+ /* Read the value back to see how many bits stuck. */
+ ucMaxPriorityValue = *pucFirstUserPriorityRegister;
+
+ /* Use the same mask on the maximum system call priority. */
+ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
+
+ /* Check that the maximum system call priority is nonzero after
+ * accounting for the number of priority bits supported by the
+ * hardware. A priority of 0 is invalid because setting the BASEPRI
+ * register to 0 unmasks all interrupts, and interrupts with priority 0
+ * cannot be masked using BASEPRI.
+ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
+ configASSERT( ucMaxSysCallPriority );
+
+ /* Calculate the maximum acceptable priority group value for the number
+ * of bits read back. */
+
+ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- volatile uint32_t ulOriginalPriority;
- volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
- volatile uint8_t ucMaxPriorityValue;
-
- /* Determine the maximum priority from which ISR safe FreeRTOS API
- * functions can be called. ISR safe functions are those that end in
- * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
- * ensure interrupt entry is as fast and simple as possible.
- *
- * Save the interrupt priority value that is about to be clobbered. */
- ulOriginalPriority = *pucFirstUserPriorityRegister;
-
- /* Determine the number of priority bits available. First write to all
- * possible bits. */
- *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
-
- /* Read the value back to see how many bits stuck. */
- ucMaxPriorityValue = *pucFirstUserPriorityRegister;
-
- /* Use the same mask on the maximum system call priority. */
- ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
-
- /* Check that the maximum system call priority is nonzero after
- * accounting for the number of priority bits supported by the
- * hardware. A priority of 0 is invalid because setting the BASEPRI
- * register to 0 unmasks all interrupts, and interrupts with priority 0
- * cannot be masked using BASEPRI.
- * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
- configASSERT( ucMaxSysCallPriority );
-
- /* Calculate the maximum acceptable priority group value for the number
- * of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
-
- while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
- {
- ulMaxPRIGROUPValue--;
- ucMaxPriorityValue <<= ( uint8_t ) 0x01;
- }
-
- #ifdef __NVIC_PRIO_BITS
- {
- /* Check the CMSIS configuration that defines the number of
- * priority bits matches the number of priority bits actually queried
- * from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
- }
- #endif
-
- #ifdef configPRIO_BITS
- {
- /* Check the FreeRTOS configuration that defines the number of
- * priority bits matches the number of priority bits actually queried
- * from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
- }
- #endif
-
- /* Shift the priority group value back to its position within the AIRCR
- * register. */
- ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
- ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
-
- /* Restore the clobbered interrupt priority register to its original
- * value. */
- *pucFirstUserPriorityRegister = ulOriginalPriority;
+ ulImplementedPrioBits++;
+ ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
+ #ifdef __NVIC_PRIO_BITS
+ {
+ /* Check the CMSIS configuration that defines the number of
+ * priority bits matches the number of priority bits actually queried
+ * from the hardware. */
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
+ }
+ #endif
+
+ #ifdef configPRIO_BITS
+ {
+ /* Check the FreeRTOS configuration that defines the number of
+ * priority bits matches the number of priority bits actually queried
+ * from the hardware. */
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
+ }
+ #endif
+
+ /* Shift the priority group value back to its position within the AIRCR
+ * register. */
+ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
+ ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
+
+ /* Restore the clobbered interrupt priority register to its original
+ * value. */
+ *pucFirstUserPriorityRegister = ulOriginalPriority;
+ }
#endif /* configASSERT_DEFINED */
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
@@ -559,39 +587,63 @@
void vPortEnterCritical( void )
{
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
- if( portIS_PRIVILEGED() == pdFALSE )
- {
- portRAISE_PRIVILEGE();
- portMEMORY_BARRIER();
+ #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ if( portIS_PRIVILEGED() == pdFALSE )
+ {
+ portRAISE_PRIVILEGE();
+ portMEMORY_BARRIER();
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+ portMEMORY_BARRIER();
+
+ portRESET_PRIVILEGE();
+ portMEMORY_BARRIER();
+ }
+ else
+ {
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+ }
+ #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
- portMEMORY_BARRIER();
-
- portRESET_PRIVILEGE();
- portMEMORY_BARRIER();
- }
- else
- {
- portDISABLE_INTERRUPTS();
- uxCriticalNesting++;
- }
-#else
- portDISABLE_INTERRUPTS();
- uxCriticalNesting++;
-#endif
+ #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
-#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
- if( portIS_PRIVILEGED() == pdFALSE )
- {
- portRAISE_PRIVILEGE();
- portMEMORY_BARRIER();
+ #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ if( portIS_PRIVILEGED() == pdFALSE )
+ {
+ portRAISE_PRIVILEGE();
+ portMEMORY_BARRIER();
+ configASSERT( uxCriticalNesting );
+ uxCriticalNesting--;
+
+ if( uxCriticalNesting == 0 )
+ {
+ portENABLE_INTERRUPTS();
+ }
+
+ portMEMORY_BARRIER();
+
+ portRESET_PRIVILEGE();
+ portMEMORY_BARRIER();
+ }
+ else
+ {
+ configASSERT( uxCriticalNesting );
+ uxCriticalNesting--;
+
+ if( uxCriticalNesting == 0 )
+ {
+ portENABLE_INTERRUPTS();
+ }
+ }
+ #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
@@ -599,30 +651,7 @@
{
portENABLE_INTERRUPTS();
}
- portMEMORY_BARRIER();
-
- portRESET_PRIVILEGE();
- portMEMORY_BARRIER();
- }
- else
- {
- configASSERT( uxCriticalNesting );
- uxCriticalNesting--;
-
- if( uxCriticalNesting == 0 )
- {
- portENABLE_INTERRUPTS();
- }
- }
-#else
- configASSERT( uxCriticalNesting );
- uxCriticalNesting--;
-
- if( uxCriticalNesting == 0 )
- {
- portENABLE_INTERRUPTS();
- }
-#endif
+ #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/
@@ -910,7 +939,7 @@
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
( portMPU_REGION_VALID ) |
- ( portSTACK_REGION ); /* Region number. */
+ ( portSTACK_REGION ); /* Region number. */
xMPUSettings->xRegion[ 0 ].ulRegionAttribute =
( portMPU_REGION_READ_WRITE ) |
diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c
old mode 100644
new mode 100755
index 7dadb9a..ee456d8
--- a/portable/RVDS/ARM_CM7/r0p1/port.c
+++ b/portable/RVDS/ARM_CM7/r0p1/port.c
@@ -314,6 +314,7 @@
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
+ volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue;
@@ -345,20 +346,46 @@
/* Calculate the maximum acceptable priority group value for the number
* of bits read back. */
- ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
- ulMaxPRIGROUPValue--;
+ ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
+ if( ulImplementedPrioBits == 8 )
+ {
+ /* When the hardware implements 8 priority bits, there is no way for
+ * the software to configure PRIGROUP to not have sub-priorities. As
+ * a result, the least significant bit is always used for sub-priority
+ * and there are 128 preemption priorities and 2 sub-priorities.
+ *
+ * This may cause some confusion in some cases - for example, if
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
+ * priority interrupts will be masked in Critical Sections as those
+ * are at the same preemption priority. This may appear confusing as
+ * 4 is higher (numerically lower) priority than
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
+ * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
+ * to 4, this confusion does not happen and the behaviour remains the same.
+ *
+ * The following assert ensures that the sub-priority bit in the
+ * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
+ * confusion. */
+ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
+ ulMaxPRIGROUPValue = 0;
+ }
+ else
+ {
+ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
+ }
+
#ifdef __NVIC_PRIO_BITS
{
/* Check the CMSIS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+ configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
}
#endif
@@ -367,7 +394,7 @@
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
- configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+ configASSERT( ulImplementedPrioBits == configPRIO_BITS );
}
#endif
diff --git a/portable/Tasking/ARM_CM4F/port.c b/portable/Tasking/ARM_CM4F/port.c
old mode 100644
new mode 100755
index 66b0d62..4ba5da7
--- a/portable/Tasking/ARM_CM4F/port.c
+++ b/portable/Tasking/ARM_CM4F/port.c
@@ -266,5 +266,4 @@
/* Configure SysTick to interrupt at the requested rate. */
*( portNVIC_SYSTICK_LOAD ) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
*( portNVIC_SYSTICK_CTRL ) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
-}
-/*-----------------------------------------------------------*/
+}
\ No newline at end of file