Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portable/IAR/ARM_CM7/r0p1/port.c')
-rw-r--r--portable/IAR/ARM_CM7/r0p1/port.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c
index 58129a4df..2790028f4 100644
--- a/portable/IAR/ARM_CM7/r0p1/port.c
+++ b/portable/IAR/ARM_CM7/r0p1/port.c
@@ -45,10 +45,14 @@
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
#endif
+/* Prototype of all Interrupt Service Routines (ISRs). */
+typedef void ( * portISR_t )( void );
+
/* Constants required to manipulate the core. Registers first... */
#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_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
/* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
@@ -63,6 +67,11 @@
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
+/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
+#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
+#define portVECTOR_INDEX_SVC ( 11 )
+#define portVECTOR_INDEX_PENDSV ( 14 )
+
/* Constants required to check the validity of an interrupt priority. */
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
@@ -135,6 +144,11 @@ extern void vPortEnableVFP( void );
*/
static void prvTaskExitError( void );
+/*
+ * FreeRTOS handlers implemented in assembly.
+ */
+extern void vPortSVCHandler( void );
+extern void xPortPendSVHandler( void );
/*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting
@@ -234,6 +248,40 @@ static void prvTaskExitError( void )
*/
BaseType_t xPortStartScheduler( void )
{
+ /* An application can install FreeRTOS interrupt handlers in one of the
+ * folllowing ways:
+ * 1. Direct Routing - Install the functions vPortSVCHandler and
+ * xPortPendSVHandler for SVCall and PendSV interrupts respectively.
+ * 2. Indirect Routing - Install separate handlers for SVCall and PendSV
+ * interrupts and route program control from those handlers to
+ * vPortSVCHandler and xPortPendSVHandler functions.
+ *
+ * Applications that use Indirect Routing must set
+ * configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
+ * routing, which is validated here when configCHECK_HANDLER_INSTALLATION
+ * is 1, should be preferred when possible. */
+ #if ( configCHECK_HANDLER_INSTALLATION == 1 )
+ {
+ const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
+
+ /* Validate that the application has correctly installed the FreeRTOS
+ * handlers for SVCall and PendSV interrupts. We do not check the
+ * installation of the SysTick handler because the application may
+ * choose to drive the RTOS tick using a timer other than the SysTick
+ * timer by overriding the weak function vPortSetupTimerInterrupt().
+ *
+ * Assertion failures here indicate incorrect installation of the
+ * FreeRTOS handlers. For help installing the FreeRTOS handlers, see
+ * https://www.FreeRTOS.org/FAQHelp.html.
+ *
+ * Systems with a configurable address for the interrupt vector table
+ * can also encounter assertion failures or even system faults here if
+ * VTOR is not set correctly to point to the application's vector table. */
+ configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
+ configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
+ }
+ #endif /* configCHECK_HANDLER_INSTALLATION */
+
#if ( configASSERT_DEFINED == 1 )
{
volatile uint8_t ucOriginalPriority;
@@ -318,9 +366,11 @@ BaseType_t xPortStartScheduler( void )
}
#endif /* configASSERT_DEFINED */
- /* Make PendSV and SysTick the lowest priority interrupts. */
+ /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
+ * the highest priority. */
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
+ portNVIC_SHPR2_REG = 0;
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */