mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 11:09:01 +01: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
					
				
							
								
								
									
										63
									
								
								portable/CCS/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										63
									
								
								portable/CCS/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable 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" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										63
									
								
								portable/CCS/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										63
									
								
								portable/CCS/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -238,6 +238,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;
 | 
			
		||||
 | 
			
		||||
@ -269,20 +270,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
 | 
			
		||||
 | 
			
		||||
@ -291,7 +318,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
 | 
			
		||||
 | 
			
		||||
@ -404,9 +431,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. */
 | 
			
		||||
@ -414,7 +441,7 @@ void xPortSysTickHandler( void )
 | 
			
		||||
        {
 | 
			
		||||
            /* Re-enable interrupts - see comments above the cpsid instruction
 | 
			
		||||
             * above. */
 | 
			
		||||
            __asm( "    cpsie i");
 | 
			
		||||
            __asm( "    cpsie i" );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
@ -475,9 +502,9 @@ void xPortSysTickHandler( void )
 | 
			
		||||
 | 
			
		||||
            if( xModifiableIdleTime > 0 )
 | 
			
		||||
            {
 | 
			
		||||
                __asm( "    dsb");
 | 
			
		||||
                __asm( "    wfi");
 | 
			
		||||
                __asm( "    isb");
 | 
			
		||||
                __asm( "    dsb" );
 | 
			
		||||
                __asm( "    wfi" );
 | 
			
		||||
                __asm( "    isb" );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
 | 
			
		||||
@ -485,17 +512,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
 | 
			
		||||
@ -603,7 +630,7 @@ void xPortSysTickHandler( void )
 | 
			
		||||
            vTaskStepTick( ulCompleteTickPeriods );
 | 
			
		||||
 | 
			
		||||
            /* Exit with interrupts enabled. */
 | 
			
		||||
            __asm( "    cpsie i");
 | 
			
		||||
            __asm( "    cpsie i" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								portable/GCC/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										37
									
								
								portable/GCC/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -262,6 +262,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;
 | 
			
		||||
 | 
			
		||||
@ -293,20 +294,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
 | 
			
		||||
 | 
			
		||||
@ -315,7 +342,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
 | 
			
		||||
 | 
			
		||||
@ -756,4 +783,4 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
 | 
			
		||||
        configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
							
								
								
									
										37
									
								
								portable/GCC/ARM_CM3_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										37
									
								
								portable/GCC/ARM_CM3_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -385,6 +385,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;
 | 
			
		||||
 | 
			
		||||
@ -416,20 +417,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
 | 
			
		||||
 | 
			
		||||
@ -438,7 +465,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
 | 
			
		||||
 | 
			
		||||
@ -923,4 +950,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										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"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								portable/GCC/ARM_CM4_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										37
									
								
								portable/GCC/ARM_CM4_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -428,6 +428,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;
 | 
			
		||||
 | 
			
		||||
@ -459,20 +460,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
 | 
			
		||||
 | 
			
		||||
@ -481,7 +508,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
 | 
			
		||||
 | 
			
		||||
@ -1046,4 +1073,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										77
									
								
								portable/GCC/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										77
									
								
								portable/GCC/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -245,11 +245,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"
 | 
			
		||||
@ -268,17 +268,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"
 | 
			
		||||
        );
 | 
			
		||||
@ -293,6 +293,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;
 | 
			
		||||
 | 
			
		||||
@ -324,20 +325,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
 | 
			
		||||
 | 
			
		||||
@ -346,7 +373,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
 | 
			
		||||
 | 
			
		||||
@ -441,34 +468,34 @@ 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"
 | 
			
		||||
        "   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 @@ 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"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/IAR/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/IAR/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -211,6 +211,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;
 | 
			
		||||
 | 
			
		||||
@ -242,20 +243,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
 | 
			
		||||
 | 
			
		||||
@ -264,7 +291,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/IAR/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/IAR/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -249,6 +249,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;
 | 
			
		||||
 | 
			
		||||
@ -280,20 +281,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
 | 
			
		||||
 | 
			
		||||
@ -302,7 +329,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										315
									
								
								portable/IAR/ARM_CM4F_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										315
									
								
								portable/IAR/ARM_CM4F_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -194,7 +194,7 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
/**
 | 
			
		||||
 * @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 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
/**
 | 
			
		||||
 * @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 @@ void vPortSVCHandler_C( uint32_t * pulParam )
 | 
			
		||||
                    {
 | 
			
		||||
                        __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 @@ void vPortSVCHandler_C( uint32_t * pulParam )
 | 
			
		||||
                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 @@ BaseType_t xPortStartScheduler( void )
 | 
			
		||||
    #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 @@ BaseType_t xPortStartScheduler( void )
 | 
			
		||||
    #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 vPortEndScheduler( void )
 | 
			
		||||
 | 
			
		||||
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 @@ void vPortEnterCritical( void )
 | 
			
		||||
        {
 | 
			
		||||
            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 @@ void vPortExitCritical( void )
 | 
			
		||||
        {
 | 
			
		||||
            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 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
        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 ) |
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/IAR/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/IAR/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -237,6 +237,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;
 | 
			
		||||
 | 
			
		||||
@ -268,20 +269,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
 | 
			
		||||
 | 
			
		||||
@ -290,7 +317,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/MikroC/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/MikroC/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -299,6 +299,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;
 | 
			
		||||
 | 
			
		||||
@ -330,20 +331,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
 | 
			
		||||
 | 
			
		||||
@ -352,7 +379,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/RVDS/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/RVDS/ARM_CM3/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -264,6 +264,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;
 | 
			
		||||
 | 
			
		||||
@ -295,20 +296,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
 | 
			
		||||
 | 
			
		||||
@ -317,7 +344,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/RVDS/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/RVDS/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -330,6 +330,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;
 | 
			
		||||
 | 
			
		||||
@ -361,20 +362,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
 | 
			
		||||
 | 
			
		||||
@ -383,7 +410,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										263
									
								
								portable/RVDS/ARM_CM4_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										263
									
								
								portable/RVDS/ARM_CM4_MPU/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -201,7 +201,7 @@ void vResetPrivilege( void );
 | 
			
		||||
/**
 | 
			
		||||
 * @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 @@ void vResetPrivilege( void );
 | 
			
		||||
/**
 | 
			
		||||
 * @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 @@ BaseType_t xPortStartScheduler( void )
 | 
			
		||||
    #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 @@ BaseType_t xPortStartScheduler( void )
 | 
			
		||||
    #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 vPortEndScheduler( void )
 | 
			
		||||
 | 
			
		||||
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 @@ void vPortExitCritical( void )
 | 
			
		||||
        {
 | 
			
		||||
            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 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
        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 ) |
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								portable/RVDS/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										35
									
								
								portable/RVDS/ARM_CM7/r0p1/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -314,6 +314,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;
 | 
			
		||||
 | 
			
		||||
@ -345,20 +346,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
 | 
			
		||||
 | 
			
		||||
@ -367,7 +394,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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								portable/Tasking/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										3
									
								
								portable/Tasking/ARM_CM4F/port.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -266,5 +266,4 @@ void prvSetupTimerInterrupt( void )
 | 
			
		||||
    /* 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;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user