Add "is inside interrupt" function to MPU ports.

Make clock setup functions weak symbols in ARMv8-M ports.
Update Cortex-M33 ports to use an interrupt mask in place of globally disabling interrupts, as per the other Cortex-M ports.
This commit is contained in:
Richard Barry 2020-02-07 01:56:25 +00:00
parent 8e5addee1e
commit 28efb5449c
52 changed files with 719 additions and 270 deletions

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -201,7 +201,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
@ -213,7 +213,7 @@ uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGE
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -196,7 +196,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
@ -208,7 +208,7 @@ uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGE
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -176,24 +176,29 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr basepri, r0 \n" /* basepri = ulMask. */
" bx lr \n" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
::: "memory" ::: "memory"
); );
} }
@ -266,9 +271,13 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" select_next_task: \n" " select_next_task: \n"
" cpsid i \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n"
" isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " mov r0, #0 \n" /* r0 = 0. */
" msr basepri, r0 \n" /* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
@ -352,6 +361,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -171,24 +171,29 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr basepri, r0 \n" /* basepri = ulMask. */
" bx lr \n" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
::: "memory" ::: "memory"
); );
} }
@ -221,9 +226,13 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */
" \n" " \n"
" cpsid i \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n"
" isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " mov r0, #0 \n" /* r0 = 0. */
" msr basepri, r0 \n" /* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
@ -284,6 +293,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -38,8 +38,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
@ -181,13 +181,13 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -34,8 +34,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
@ -169,13 +169,13 @@ vStartFirstTask:
nop nop
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -24,6 +24,12 @@
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h"
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN xSecureContext EXTERN xSecureContext
@ -38,8 +44,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
@ -156,15 +162,20 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, basepri /* r0 = basepri. Return original basepri value. */
cpsid i mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bx lr msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr basepri, r0 /* basepri = ulMask. */
bx lr dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
@ -227,9 +238,13 @@ PendSV_Handler:
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
select_next_task: select_next_task:
cpsid i mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -24,6 +24,12 @@
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h"
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN vTaskSwitchContext EXTERN vTaskSwitchContext
@ -34,8 +40,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -142,15 +148,20 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, basepri /* r0 = basepri. Return original basepri value. */
cpsid i mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bx lr msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr basepri, r0 /* basepri = ulMask. */
bx lr dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
@ -175,9 +186,13 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
cpsid i mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -201,7 +201,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
@ -213,7 +213,7 @@ uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGE
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -196,7 +196,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
@ -208,7 +208,7 @@ uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGE
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -176,24 +176,29 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr basepri, r0 \n" /* basepri = ulMask. */
" bx lr \n" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
::: "memory" ::: "memory"
); );
} }
@ -266,9 +271,13 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" select_next_task: \n" " select_next_task: \n"
" cpsid i \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n"
" isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " mov r0, #0 \n" /* r0 = 0. */
" msr basepri, r0 \n" /* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
@ -352,6 +361,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -171,24 +171,29 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr basepri, r0 \n" /* basepri = ulMask. */
" bx lr \n" " dsb \n"
" isb \n"
" bx lr \n" /* Return. */
::: "memory" ::: "memory"
); );
} }
@ -221,9 +226,13 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */
" \n" " \n"
" cpsid i \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n"
" isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " mov r0, #0 \n" /* r0 = 0. */
" msr basepri, r0 \n" /* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
@ -284,6 +293,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -38,8 +38,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
@ -181,13 +181,13 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -34,8 +34,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
@ -169,13 +169,13 @@ vStartFirstTask:
nop nop
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,8 +219,8 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -25,6 +25,13 @@
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h"
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN xSecureContext EXTERN xSecureContext
EXTERN vTaskSwitchContext EXTERN vTaskSwitchContext
@ -38,8 +45,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
@ -156,15 +163,20 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, basepri /* r0 = basepri. Return original basepri value. */
cpsid i mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bx lr msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr basepri, r0 /* basepri = ulMask. */
bx lr dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
@ -227,9 +239,13 @@ PendSV_Handler:
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
select_next_task: select_next_task:
cpsid i mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -257,11 +257,6 @@
#define portNO_SECURE_CONTEXT 0 #define portNO_SECURE_CONTEXT 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* @brief Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/** /**
* @brief Used to catch tasks that attempt to return from their implementing * @brief Used to catch tasks that attempt to return from their implementing
* function. * function.
@ -282,6 +277,22 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
/**
* @brief Setup the timer to generate the tick interrupts.
*
* The implementation in this file is weak to allow application writers to
* change the timer used to generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
/**
* @brief Checks whether the current execution context is interrupt.
*
* @return pdTRUE if the current execution context is interrupt, pdFALSE
* otherwise.
*/
BaseType_t xPortIsInsideInterrupt( void );
/** /**
* @brief Yield the processor. * @brief Yield the processor.
*/ */
@ -323,7 +334,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
{ {
/* Stop and reset the SysTick. */ /* Stop and reset the SysTick. */
*( portNVIC_SYSTICK_CTRL ) = 0UL; *( portNVIC_SYSTICK_CTRL ) = 0UL;
@ -773,7 +784,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
/* 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. */
prvSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialize the critical nesting count ready for the first task. */ /* Initialize the critical nesting count ready for the first task. */
ulCriticalNesting = 0; ulCriticalNesting = 0;
@ -897,3 +908,26 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. Interrupt Program
* Status Register (IPSR) holds the exception number of the currently-executing
* exception or zero for Thread mode.*/
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -78,12 +78,12 @@ void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Disables interrupts. * @brief Disables interrupts.
*/ */
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.

View file

@ -25,6 +25,13 @@
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h"
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN vTaskSwitchContext EXTERN vTaskSwitchContext
EXTERN vPortSVCHandler_C EXTERN vPortSVCHandler_C
@ -34,8 +41,8 @@
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -142,15 +149,20 @@ vStartFirstTask:
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, basepri /* r0 = basepri. Return original basepri value. */
cpsid i mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bx lr msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr basepri, r0 /* basepri = ulMask. */
bx lr dsb
isb
bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
@ -175,9 +187,13 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
cpsid i mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
isb
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */

View file

@ -103,13 +103,15 @@ typedef unsigned long UBaseType_t;
/** /**
* @brief Extern declarations. * @brief Extern declarations.
*/ */
extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) #if( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
@ -217,10 +219,10 @@ typedef struct MPU_SETTINGS
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -24,7 +24,11 @@
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include <FreeRTOSConfig.h> #include <FreeRTOSConfig.h>
RSEG CODE:CODE(2) RSEG CODE:CODE(2)

View file

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://www.freertos.org/FreeRTOS-V10.3.x.html