X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS%2FSource%2Fportable%2FIAR%2FARM_CM3%2Fport.c;h=1f4b0ab2e32b132911bf71c66f8541a60892c4d6;hb=b473fddd0a6a35390132c46400b32af8c7ef36e9;hp=2278e480cc2236caacd43106970feecc5e98c90f;hpb=0ed9f20288711a2f38fac733bab950efd2dc9744;p=freertos diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c index 2278e480c..1f4b0ab2e 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c @@ -1,5 +1,5 @@ /* - FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd. + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. All rights reserved VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. @@ -24,10 +24,10 @@ the terms of the GNU General Public License (version 2) as published by the Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS @@ -89,10 +89,10 @@ #endif /* Constants required to manipulate the core. Registers first... */ -#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) ) -#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) ) -#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) ) -#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) ) +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) /* ...then bits in the registers. */ #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) @@ -100,19 +100,22 @@ #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) -#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) /* Constants required to check the validity of an interrupt priority. */ #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) -#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) -#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff ) -#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 ) -#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) @@ -133,7 +136,7 @@ FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ /* Each task maintains its own interrupt status in the critical nesting variable. */ -static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; /* * Setup the timer to generate the tick interrupts. The implementation in this @@ -163,7 +166,7 @@ static void prvTaskExitError( void ); * The number of SysTick increments that make up one tick period. */ #if configUSE_TICKLESS_IDLE == 1 - static unsigned long ulTimerCountsForOneTick = 0; + static uint32_t ulTimerCountsForOneTick = 0; #endif /* configUSE_TICKLESS_IDLE */ /* @@ -171,7 +174,7 @@ static void prvTaskExitError( void ); * 24 bit resolution of the SysTick timer. */ #if configUSE_TICKLESS_IDLE == 1 - static unsigned long xMaximumPossibleSuppressedTicks = 0; + static uint32_t xMaximumPossibleSuppressedTicks = 0; #endif /* configUSE_TICKLESS_IDLE */ /* @@ -179,7 +182,7 @@ static void prvTaskExitError( void ); * power functionality only. */ #if configUSE_TICKLESS_IDLE == 1 - static unsigned long ulStoppedTimerCompensation = 0; + static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /* @@ -188,9 +191,9 @@ static void prvTaskExitError( void ); * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ #if ( configASSERT_DEFINED == 1 ) - static unsigned char ucMaxSysCallPriority = 0; - static unsigned long ulMaxPRIGROUPValue = 0; - static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ @@ -198,18 +201,18 @@ static void prvTaskExitError( void ); /* * See header file for description. */ -portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Simulate the stack frame as it would be created by a context switch interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */ + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; @@ -233,13 +236,13 @@ static void prvTaskExitError( void ) /* * See header file for description. */ -portBASE_TYPE xPortStartScheduler( void ) +BaseType_t xPortStartScheduler( void ) { #if( configASSERT_DEFINED == 1 ) { - volatile unsigned long ulOriginalPriority; - volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); - volatile unsigned char ucMaxPriorityValue; + 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 @@ -247,14 +250,14 @@ portBASE_TYPE xPortStartScheduler( void ) ensure interrupt entry is as fast and simple as possible. Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pcFirstUserPriorityRegister; + ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ - *pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pcFirstUserPriorityRegister; + ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -265,7 +268,7 @@ portBASE_TYPE xPortStartScheduler( void ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; - ucMaxPriorityValue <<= ( unsigned char ) 0x01; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; } /* Shift the priority group value back to its position within the AIRCR @@ -275,7 +278,7 @@ portBASE_TYPE xPortStartScheduler( void ) /* Restore the clobbered interrupt priority register to its original value. */ - *pcFirstUserPriorityRegister = ulOriginalPriority; + *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* conifgASSERT_DEFINED */ @@ -324,6 +327,16 @@ void vPortEnterCritical( void ) uxCriticalNesting++; __DSB(); __ISB(); + + /* 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 ); + } } /*-----------------------------------------------------------*/ @@ -360,10 +373,10 @@ void xPortSysTickHandler( void ) #if configUSE_TICKLESS_IDLE == 1 - __weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime ) + __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { - unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; - portTickType xModifiableIdleTime; + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; /* Make sure the SysTick reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) @@ -449,7 +462,7 @@ void xPortSysTickHandler( void ) if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { - unsigned long ulCalculatedLoadValue; + uint32_t ulCalculatedLoadValue; /* The tick interrupt has already executed, and the SysTick count reloaded with ulReloadValue. Reset the @@ -526,7 +539,7 @@ __weak void vPortSetupTimerInterrupt( void ) #endif /* configUSE_TICKLESS_IDLE */ /* Configure SysTick to interrupt at the requested rate. */ - portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;; + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); } /*-----------------------------------------------------------*/ @@ -535,8 +548,8 @@ __weak void vPortSetupTimerInterrupt( void ) void vPortValidateInterruptPriority( void ) { - unsigned long ulCurrentInterrupt; - unsigned char ucCurrentPriority; + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; /* Obtain the number of the currently executing interrupt. */ __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );