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>
This commit is contained in:
kar-rahul-aws 2023-03-23 15:06:33 +05:30 committed by GitHub
parent 9488ba22d8
commit 99797e14e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 826 additions and 387 deletions

63
portable/CCS/ARM_CM3/port.c Normal file → Executable file
View file

@ -219,6 +219,7 @@ BaseType_t xPortStartScheduler( void )
#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 @@ BaseType_t xPortStartScheduler( void )
/* 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 @@ BaseType_t xPortStartScheduler( void )
/* 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 @@ void xPortSysTickHandler( void )
/* 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 @@ void xPortSysTickHandler( void )
{
/* Re-enable interrupts - see comments above the cpsid instruction
* above. */
__asm( " cpsie i");
__asm( " cpsie i" );
}
else
{
@ -450,9 +477,9 @@ void xPortSysTickHandler( void )
if( xModifiableIdleTime > 0 )
{
__asm( " dsb");
__asm( " wfi");
__asm( " isb");
__asm( " dsb" );
__asm( " wfi" );
__asm( " isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
@ -460,17 +487,17 @@ void xPortSysTickHandler( void )
/* 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 @@ void xPortSysTickHandler( void )
vTaskStepTick( ulCompleteTickPeriods );
/* Exit with interrupts enabled. */
__asm( " cpsie i");
__asm( " cpsie i" );
}
}