mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Detect more startup config errors on Cortex M (#832)
Verify that the application has correctly installed PendSV and SVCall handlers. The application can choose to disable these checks by setting configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h.
This commit is contained in:
parent
553caa18ce
commit
30e6b8a5ea
|
@ -365,6 +365,17 @@
|
||||||
#define configPRECONDITION_DEFINED 1
|
#define configPRECONDITION_DEFINED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configCHECK_HANDLER_INSTALLATION
|
||||||
|
#define configCHECK_HANDLER_INSTALLATION 1
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* The application has explicitly defined configCHECK_HANDLER_INSTALLATION
|
||||||
|
* to 1. The checks requires configASSERT() to be defined. */
|
||||||
|
#if ( ( configCHECK_HANDLER_INSTALLATION == 1 ) && ( configASSERT_DEFINED == 0 ) )
|
||||||
|
#error You must define configASSERT() when configCHECK_HANDLER_INSTALLATION is 1.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef portMEMORY_BARRIER
|
#ifndef portMEMORY_BARRIER
|
||||||
#define portMEMORY_BARRIER()
|
#define portMEMORY_BARRIER()
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the NVIC. */
|
/* Constants required to manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -51,6 +54,10 @@
|
||||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
#define portNVIC_SYSTICK_PRI ( 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_PENDSV ( 14 )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
|
@ -200,20 +207,20 @@ void vPortSVCHandler( void )
|
||||||
|
|
||||||
void vPortStartFirstTask( void )
|
void vPortStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
/* Don't reset the MSP stack as is done on CM3/4 devices. The vector table
|
||||||
* table offset register that can be used to locate the initial stack value.
|
* in some CM0 devices cannot be modified and thus may not hold the
|
||||||
* Not all M0 parts have the application vector table at address 0. */
|
* application's initial MSP value. */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
||||||
" ldr r3, [r2] \n"
|
" ldr r3, [r2] \n"
|
||||||
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" movs r0, #2 \n" /* Switch to the psp stack. */
|
" movs r0, #2 \n" /* Switch to the psp stack. */
|
||||||
" msr CONTROL, r0 \n"
|
" msr CONTROL, r0 \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
||||||
" mov lr, r5 \n" /* lr is now in r5. */
|
" mov lr, r5 \n" /* lr is now in r5. */
|
||||||
" pop {r3} \n" /* Return address is now in r3. */
|
" pop {r3} \n" /* Return address is now in r3. */
|
||||||
" pop {r2} \n" /* Pop and discard XPSR. */
|
" pop {r2} \n" /* Pop and discard XPSR. */
|
||||||
|
@ -231,7 +238,42 @@ void vPortStartFirstTask( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the function xPortPendSVHandler for PendSV
|
||||||
|
* interrupt.
|
||||||
|
* 2. Indirect Routing - Install separate handler for PendSV interrupt and
|
||||||
|
* route program control from that handler to xPortPendSVHandler function.
|
||||||
|
*
|
||||||
|
* 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 )
|
||||||
|
{
|
||||||
|
/* Point pxVectorTable to the interrupt vector table. Systems without
|
||||||
|
* a VTOR register provide the value zero in the VTOR register and
|
||||||
|
* the vector table itself is located at the address 0x00000000. */
|
||||||
|
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||||
|
|
||||||
|
/* Validate that the application has correctly installed the FreeRTOS
|
||||||
|
* handler for PendSV interrupt. 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 handler. For help installing the FreeRTOS handler, 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_PENDSV ] == xPortPendSVHandler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
|
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,10 +34,14 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -52,6 +56,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -259,6 +268,40 @@ static void prvPortStartFirstTask( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -343,9 +386,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,6 +58,9 @@
|
||||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to access and manipulate the NVIC. */
|
/* Constants required to access and manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -87,7 +90,6 @@
|
||||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
@ -95,6 +97,11 @@
|
||||||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||||
|
|
||||||
|
/* 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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -414,7 +421,6 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
|
||||||
prvRestoreContextOfFirstTask();
|
prvRestoreContextOfFirstTask();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -737,6 +743,40 @@ static void prvRestoreContextOfFirstTask( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -821,11 +861,12 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
* handler higher priority so it can be used to exit a critical section (where
|
* the highest priority. */
|
||||||
* lower priorities are masked). */
|
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
|
|
||||||
/* Configure the regions in the MPU that are common to all tasks. */
|
/* Configure the regions in the MPU that are common to all tasks. */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
|
@ -38,10 +38,14 @@
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -62,6 +66,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -302,6 +311,40 @@ BaseType_t xPortStartScheduler( void )
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
|
|
||||||
|
/* 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -386,9 +429,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to access and manipulate the NVIC. */
|
/* Constants required to access and manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -97,7 +100,6 @@
|
||||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
||||||
|
@ -109,6 +111,11 @@
|
||||||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||||
|
|
||||||
|
/* 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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -448,7 +455,6 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
|
||||||
prvRestoreContextOfFirstTask();
|
prvRestoreContextOfFirstTask();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -823,6 +829,40 @@ BaseType_t xPortStartScheduler( void )
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -907,11 +947,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
* handler higher priority so it can be used to exit a critical section (where
|
* the highest priority. */
|
||||||
* lower priorities are masked). */
|
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Configure the regions in the MPU that are common to all tasks. */
|
/* Configure the regions in the MPU that are common to all tasks. */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,10 +38,14 @@
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -56,6 +60,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -290,6 +299,40 @@ static void prvPortStartFirstTask( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -374,9 +417,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the NVIC. */
|
/* Constants required to manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -53,6 +56,10 @@
|
||||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
#define portNVIC_SYSTICK_PRI ( 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_PENDSV ( 14 )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
|
@ -121,6 +128,10 @@ extern void vPortStartFirstTask( void );
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( void );
|
static void prvTaskExitError( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeRTOS handlers implemented in assembly.
|
||||||
|
*/
|
||||||
|
extern void xPortPendSVHandler( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,6 +179,41 @@ static void prvTaskExitError( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the function xPortPendSVHandler for PendSV
|
||||||
|
* interrupt.
|
||||||
|
* 2. Indirect Routing - Install separate handler for PendSV interrupt and
|
||||||
|
* route program control from that handler to xPortPendSVHandler function.
|
||||||
|
*
|
||||||
|
* 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 )
|
||||||
|
{
|
||||||
|
/* Point pxVectorTable to the interrupt vector table. Systems without
|
||||||
|
* a VTOR register provide the value zero in the VTOR register and
|
||||||
|
* the vector table itself is located at the address 0x00000000. */
|
||||||
|
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||||
|
|
||||||
|
/* Validate that the application has correctly installed the FreeRTOS
|
||||||
|
* handler for PendSV interrupt. 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 handler. For help installing the FreeRTOS handler, 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_PENDSV ] == xPortPendSVHandler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
|
@ -91,15 +91,15 @@ xPortPendSVHandler:
|
||||||
|
|
||||||
vPortSVCHandler;
|
vPortSVCHandler;
|
||||||
/* This function is no longer used, but retained for backward
|
/* This function is no longer used, but retained for backward
|
||||||
compatibility. */
|
* compatibility. */
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
vPortStartFirstTask
|
vPortStartFirstTask
|
||||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
/* Don't reset the MSP stack as is done on CM3/4 devices. The vector table
|
||||||
table offset register that can be used to locate the initial stack value.
|
* in some CM0 devices cannot be modified and thus may not hold the
|
||||||
Not all M0 parts have the application vector table at address 0. */
|
* application's initial MSP value. */
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
||||||
ldr r1, [r3]
|
ldr r1, [r3]
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,10 +41,14 @@
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -59,6 +63,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -121,6 +130,11 @@ extern void vPortStartFirstTask( void );
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( 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
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
@ -208,6 +222,40 @@ static void prvTaskExitError( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -292,9 +340,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -69,6 +73,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -141,6 +150,11 @@ extern void vPortEnableVFP( void );
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( 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
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
@ -246,6 +260,40 @@ BaseType_t xPortStartScheduler( void )
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
|
|
||||||
|
/* 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -330,9 +378,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -69,6 +69,9 @@
|
||||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -108,7 +111,11 @@
|
||||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
|
@ -282,6 +289,11 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION;
|
||||||
*/
|
*/
|
||||||
void vPortSwitchToUserMode( void );
|
void vPortSwitchToUserMode( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeRTOS handlers implemented in assembly.
|
||||||
|
*/
|
||||||
|
extern void vPortSVCHandler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
extern void xPortPendSVHandler( void ) PRIVILEGED_FUNCTION;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
@ -384,7 +396,6 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
|
||||||
vPortRestoreContextOfFirstTask();
|
vPortRestoreContextOfFirstTask();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -713,6 +724,40 @@ BaseType_t xPortStartScheduler( void )
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -797,9 +842,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Configure the regions in the MPU that are common to all tasks. */
|
/* Configure the regions in the MPU that are common to all tasks. */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
#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 ) )
|
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
@ -63,6 +67,11 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -135,6 +144,11 @@ extern void vPortEnableVFP( void );
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( 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
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
@ -234,6 +248,40 @@ static void prvTaskExitError( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -318,9 +366,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#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_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
* here already. */
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,12 @@
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||||
|
*/
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
|
@ -101,10 +107,18 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||||
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||||
|
*/
|
||||||
|
#define portVECTOR_INDEX_SVC ( 11 )
|
||||||
|
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to check the validity of an interrupt priority.
|
* @brief Constants required to check the validity of an interrupt priority.
|
||||||
*/
|
*/
|
||||||
|
@ -1598,22 +1612,52 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
|
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||||
|
* folllowing ways:
|
||||||
|
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||||
|
* 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
|
||||||
|
* SVC_Handler and PendSV_Handler 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 ] == SVC_Handler );
|
||||||
|
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||||
|
}
|
||||||
|
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||||
|
|
||||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
|
||||||
volatile uint32_t ulImplementedPrioBits = 0;
|
volatile uint32_t ulImplementedPrioBits = 0;
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
* functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
* ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
*
|
*
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
* First, determine the number of priority bits available. Write to all
|
||||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
* possible bits in the priority setting for SVCall. */
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
* possible bits. */
|
|
||||||
portNVIC_SHPR2_REG = 0xFF000000;
|
portNVIC_SHPR2_REG = 0xFF000000;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
* of bits read back. */
|
* of bits read back. */
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulImplementedPrioBits++;
|
ulImplementedPrioBits++;
|
||||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
* value. */
|
|
||||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
|
||||||
}
|
}
|
||||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||||
|
|
||||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||||
|
* the highest priority. */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||||
|
typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
/* Constants required to access and manipulate the NVIC. */
|
/* Constants required to access and manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
|
@ -87,7 +90,6 @@
|
||||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
||||||
|
@ -99,6 +101,11 @@
|
||||||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||||
|
|
||||||
|
/* 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. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
|
@ -386,7 +393,6 @@ void vSVCHandler_C( uint32_t * pulParam )
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
|
||||||
prvRestoreContextOfFirstTask();
|
prvRestoreContextOfFirstTask();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -822,6 +828,40 @@ BaseType_t xPortStartScheduler( void )
|
||||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 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 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
|
@ -907,10 +947,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
||||||
* handler higher priority so it can be used to exit a critical section (where
|
* handler highest priority so it can be used to exit a critical section
|
||||||
* lower priorities are masked). */
|
* (where lower priorities are masked). */
|
||||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
portNVIC_SHPR2_REG = 0;
|
||||||
|
|
||||||
/* Configure the regions in the MPU that are common to all tasks. */
|
/* Configure the regions in the MPU that are common to all tasks. */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
@ -1196,6 +1237,7 @@ __asm void vPortEnableVFP( void )
|
||||||
orr r1, r1, #( 0xf << 20 ) /* Enable CP10 and CP11 coprocessors, then save back. */
|
orr r1, r1, #( 0xf << 20 ) /* Enable CP10 and CP11 coprocessors, then save back. */
|
||||||
str r1, [ r0 ]
|
str r1, [ r0 ]
|
||||||
bx r14
|
bx r14
|
||||||
|
nop
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue