mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Add barrier instructions to IAR CM3 ports.
This commit is contained in:
parent
be7cae575d
commit
895ee2bb3e
|
@ -76,6 +76,9 @@
|
|||
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* IAR includes. */
|
||||
#include "intrinsics.h"
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
@ -83,12 +86,10 @@
|
|||
/* Constants required to manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
|
||||
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
|
||||
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
|
||||
#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
|
||||
#define portNVIC_SYSTICK_CLK 0x00000004
|
||||
#define portNVIC_SYSTICK_INT 0x00000002
|
||||
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
||||
#define portNVIC_PENDSVSET 0x10000000
|
||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||
|
@ -174,10 +175,15 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldFromISR( void )
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -185,6 +191,8 @@ void vPortEnterCritical( void )
|
|||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -116,11 +116,11 @@ extern "C" {
|
|||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYieldFromISR( void );
|
||||
|
||||
#define portYIELD() vPortYieldFromISR()
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
|
||||
#define portNVIC_PENDSVSET 0x10000000
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
|
@ -95,14 +95,12 @@
|
|||
#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_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
|
@ -219,10 +217,15 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldFromISR( void )
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -230,6 +233,8 @@ void vPortEnterCritical( void )
|
|||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -336,6 +341,8 @@ void xPortSysTickHandler( void )
|
|||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__WFI();
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
|
|
|
@ -115,9 +115,11 @@ extern "C" {
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYieldFromISR( void );
|
||||
#define portYIELD() vPortYieldFromISR()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
|
|
|
@ -99,14 +99,12 @@
|
|||
#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_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
|
@ -244,10 +242,15 @@ void vPortEndScheduler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldFromISR( void )
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -255,6 +258,8 @@ void vPortEnterCritical( void )
|
|||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -361,6 +366,8 @@ void xPortSysTickHandler( void )
|
|||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__WFI();
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
|
|
|
@ -115,9 +115,11 @@ extern "C" {
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYieldFromISR( void );
|
||||
#define portYIELD() vPortYieldFromISR()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
|
|
|
@ -112,16 +112,16 @@ volatile unsigned short usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
|||
|
||||
/*
|
||||
* Sets up the periodic ISR used for the RTOS tick using the interval timer.
|
||||
* The application writer can define configSETUP_TIMER_INTERRUPT() (in
|
||||
* The application writer can define configSETUP_TICK_INTERRUPT() (in
|
||||
* FreeRTOSConfig.h) such that their own tick interrupt configuration is used
|
||||
* in place of prvSetupTimerInterrupt().
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
#ifndef configSETUP_TIMER_INTERRUPT
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
/* The user has not provided their own tick interrupt configuration so use
|
||||
the definition in this file (which uses the interval timer). */
|
||||
#define configSETUP_TIMER_INTERRUPT() prvSetupTimerInterrupt()
|
||||
#endif /* configSETUP_TIMER_INTERRUPT */
|
||||
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
/*
|
||||
* Defined in portasm.s87, this function starts the scheduler by loading the
|
||||
|
@ -218,7 +218,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||
{
|
||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||
this function is called. */
|
||||
configSETUP_TIMER_INTERRUPT();
|
||||
configSETUP_TICK_INTERRUPT();
|
||||
|
||||
/* Restore the context of the first task that is going to run. */
|
||||
vPortStartFirstTask();
|
||||
|
@ -227,7 +227,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||
prvSetupTimerInterrupt() is called here to prevent the compiler outputting
|
||||
a warning about a statically declared function not being referenced in the
|
||||
case that the application writer has provided their own tick interrupt
|
||||
configuration routine (and defined configSETUP_TIMER_INTERRUPT() such that
|
||||
configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
|
||||
their own routine will be called in place of prvSetupTimerInterrupt()). */
|
||||
prvSetupTimerInterrupt();
|
||||
return pdTRUE;
|
||||
|
|
Loading…
Reference in a new issue