mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-20 18:18:32 -04:00
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:
parent
9488ba22d8
commit
99797e14e3
17 changed files with 826 additions and 387 deletions
73
portable/GCC/ARM_CM4F/port.c
Normal file → Executable file
73
portable/GCC/ARM_CM4F/port.c
Normal file → Executable file
|
@ -251,11 +251,11 @@ static void prvTaskExitError( void )
|
|||
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 @@ static void prvPortStartFirstTask( void )
|
|||
* 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 @@ BaseType_t xPortStartScheduler( void )
|
|||
#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 @@ 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
|
||||
|
||||
|
@ -358,7 +385,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
|
||||
|
||||
|
@ -453,15 +480,15 @@ void xPortPendSVHandler( void )
|
|||
" 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 @@ void xPortPendSVHandler( void )
|
|||
" 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 @@ static void vPortEnableVFP( void )
|
|||
{
|
||||
__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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue