mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-01-16 23:00:34 -05:00
CI-CD Updates (#768)
* Use new version of CI-CD Actions * Use cSpell spell check, and use ubuntu-20.04 for formatting check * Format and spell check all files in the portable directory * Remove the https:// from #errors and #warnings as uncrustify attempts to change it to /* * Use checkout@v3 instead of checkout@v2 on all jobs ---------
This commit is contained in:
parent
d6bccb1f4c
commit
5fb9b50da8
485 changed files with 108790 additions and 107581 deletions
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||
* port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||
* port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
|
@ -50,11 +50,11 @@
|
|||
#include "tc.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portTICK_PRIORITY_6 ( 6 )
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portTICK_PRIORITY_6 ( 6 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
|
|
@ -74,61 +74,63 @@ extern void vPortISRStartFirstTask( void );
|
|||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* start of the task. The offset is added to make the return address appear
|
||||
* as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
|
@ -141,9 +143,9 @@ StackType_t *pxOriginalTOS;
|
|||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
means the interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
* means the interrupt flags cannot always be stored on the stack and will
|
||||
* instead be stored in a variable, which is then saved as part of the
|
||||
* tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -153,7 +155,7 @@ StackType_t *pxOriginalTOS;
|
|||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
|
|
@ -167,7 +169,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -176,7 +178,7 @@ void vPortEndScheduler( void )
|
|||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
volatile uint32_t ulDummy;
|
||||
volatile uint32_t ulDummy;
|
||||
|
||||
/* Enable clock to the tick timer... */
|
||||
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||
|
|
@ -191,17 +193,17 @@ volatile uint32_t ulDummy;
|
|||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
||||
/* Store interrupt handler function address in tick timer vector register...
|
||||
The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* The ISR installed depends on whether the preemptive or cooperative
|
||||
* scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vPreemptiveTick;
|
||||
extern void( vPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vPreemptiveTick;
|
||||
}
|
||||
#else // else use cooperative scheduler
|
||||
#else // else use cooperative scheduler
|
||||
{
|
||||
extern void ( vNonPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vNonPreemptiveTick;
|
||||
extern void( vNonPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vNonPreemptiveTick;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -209,27 +211,27 @@ volatile uint32_t ulDummy;
|
|||
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||
|
||||
/* Enable the tick timer interrupt...
|
||||
|
||||
First at timer level */
|
||||
*
|
||||
* First at timer level */
|
||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||
|
||||
/* Then at the AIC level. */
|
||||
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
||||
AT91C_BASE_AIC->AIC_IECR = ( 1 << portTIMER_AIC_CHANNEL );
|
||||
|
||||
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
||||
if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF )
|
||||
{
|
||||
/* The tick rate is fast enough for us to use the faster timer input
|
||||
clock (main clock / 2). */
|
||||
* clock (main clock / 2). */
|
||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We must use a slower timer input clock (main clock / 8) because the
|
||||
tick rate is too slow for the faster input clock. */
|
||||
* tick rate is too slow for the faster input clock. */
|
||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 );
|
||||
}
|
||||
|
||||
/* Start tick timer... */
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
* Changes from V3.2.4
|
||||
*
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
|
|
@ -46,16 +46,16 @@
|
|||
#include "task.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
|
|
@ -67,7 +67,7 @@ void vPortISRStartFirstTask( void );
|
|||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -83,8 +83,8 @@ void vPortISRStartFirstTask( void )
|
|||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* Within an IRQ ISR the link register has an offset from the true return
|
||||
address, but an SWI ISR does not. Add the offset manually so the same
|
||||
ISR return code can be used in both cases. */
|
||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||
* ISR return code can be used in both cases. */
|
||||
asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
|
|
@ -105,12 +105,12 @@ void vPortYieldProcessor( void )
|
|||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
static volatile uint32_t ulDummy;
|
||||
static volatile uint32_t ulDummy;
|
||||
|
||||
/* Clear tick timer interrupt indication. */
|
||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
|
@ -121,25 +121,25 @@ void vPortYieldProcessor( void )
|
|||
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else /* else preemption is turned on */
|
||||
#else /* else preemption is turned on */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||
if you must! */
|
||||
* if you must! */
|
||||
static volatile uint32_t ulDummy;
|
||||
|
||||
/* Clear tick timer interrupt indication. */
|
||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
* task that is ready to run. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
|
|
@ -152,7 +152,7 @@ void vPortYieldProcessor( void )
|
|||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -163,50 +163,50 @@ void vPortYieldProcessor( void )
|
|||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
be saved to the stack. Instead the critical section nesting level is stored
|
||||
in a variable, which is then saved as part of the stack context. */
|
||||
* different optimisation levels. The interrupt flags can therefore not always
|
||||
* be saved to the stack. Instead the critical section nesting level is stored
|
||||
* in a variable, which is then saved as part of the stack context. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
|
|
@ -218,16 +218,16 @@ void vPortExitCritical( void )
|
|||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,27 +27,27 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
+ replaced them with hard coded registers. This will ensure the
|
||||
+ assembler does not select the link register as the temp register as
|
||||
+ was occasionally happening previously.
|
||||
+
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
+
|
||||
+ Changes from V4.5.0
|
||||
+
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
+ macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
|
@ -69,35 +69,35 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portYIELD() asm volatile ( "SWI 0" )
|
||||
#define portNOP() asm volatile ( "NOP" )
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portYIELD() asm volatile ( "SWI 0" )
|
||||
#define portNOP() asm volatile ( "NOP" )
|
||||
|
||||
/*
|
||||
* These define the timer to use for generating the tick interrupt.
|
||||
|
|
@ -118,90 +118,90 @@ typedef unsigned long UBaseType_t;
|
|||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
|
||||
/* Critical section handling. */
|
||||
|
||||
|
|
@ -214,43 +214,43 @@ extern volatile uint32_t ulCriticalNesting; \
|
|||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,50 +1,50 @@
|
|||
//* ----------------------------------------------------------------------------
|
||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* File Name : lib_AT91SAM7X256.h
|
||||
//* Object : AT91SAM7X256 inlined functions
|
||||
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
|
||||
//*
|
||||
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
|
||||
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
|
||||
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
|
||||
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
|
||||
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
|
||||
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
|
||||
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
|
||||
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
|
||||
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
|
||||
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
|
||||
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
|
||||
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
|
||||
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
|
||||
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
|
||||
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
|
||||
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
|
||||
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
|
||||
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
|
||||
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
|
||||
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
|
||||
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
|
||||
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
||||
//* ----------------------------------------------------------------------------
|
||||
/** ---------------------------------------------------------------------------- */
|
||||
/** ATMEL Microcontroller Software Support - ROUSSET - */
|
||||
/** ---------------------------------------------------------------------------- */
|
||||
/** DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
|
||||
/** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
||||
/** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
|
||||
/** DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
||||
/** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
||||
/** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
||||
/** OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
|
||||
/** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
||||
/** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
||||
/** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
/** ---------------------------------------------------------------------------- */
|
||||
/** File Name : lib_AT91SAM7X256.h */
|
||||
/** Object : AT91SAM7X256 inlined functions */
|
||||
/** Generated : AT91 SW Application Group 05/20/2005 (16:22:29) */
|
||||
/** */
|
||||
/** CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// */
|
||||
/** CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// */
|
||||
/** CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// */
|
||||
/** CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// */
|
||||
/** CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// */
|
||||
/** CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// */
|
||||
/** CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// */
|
||||
/** CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// */
|
||||
/** CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// */
|
||||
/** CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// */
|
||||
/** CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// */
|
||||
/** CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// */
|
||||
/** CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// */
|
||||
/** CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// */
|
||||
/** CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// */
|
||||
/** CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// */
|
||||
/** CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// */
|
||||
/** CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// */
|
||||
/** CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// */
|
||||
/** CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// */
|
||||
/** CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// */
|
||||
/** CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// */
|
||||
/** ---------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "AT91SAM7X256.h"
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_AIC_ConfigureIt
|
||||
//* \brief Interrupt Handler Initialization
|
||||
//*----------------------------------------------------------------------------
|
||||
/**---------------------------------------------------------------------------- */
|
||||
/** \fn AT91F_AIC_ConfigureIt */
|
||||
/** \brief Interrupt Handler Initialization */
|
||||
/**---------------------------------------------------------------------------- */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -28,12 +28,12 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
|
@ -46,24 +46,24 @@
|
|||
#include "AT91SAM7X256.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the PIT. */
|
||||
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
|
||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
|
||||
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
|
||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
|
||||
|
||||
#define portINT_LEVEL_SENSITIVE 0
|
||||
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
|
||||
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
|
||||
#define portINT_LEVEL_SENSITIVE 0
|
||||
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
|
||||
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
|
|
@ -83,61 +83,63 @@ extern void vPortISRStartFirstTask( void );
|
|||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* start of the task. The offset is added to make the return address appear
|
||||
* as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
|
@ -150,9 +152,9 @@ StackType_t *pxOriginalTOS;
|
|||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
means the interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
* means the interrupt flags cannot always be stored on the stack and will
|
||||
* instead be stored in a variable, which is then saved as part of the
|
||||
* tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -162,7 +164,7 @@ StackType_t *pxOriginalTOS;
|
|||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
|
|
@ -176,7 +178,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -185,27 +187,23 @@ void vPortEndScheduler( void )
|
|||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||
|
||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||
on whether the preemptive or cooperative scheduler is being used. */
|
||||
* on whether the preemptive or cooperative scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
extern void ( vNonPreemptiveTick ) ( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
||||
|
||||
extern void( vNonPreemptiveTick ) ( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick );
|
||||
#else
|
||||
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
||||
|
||||
extern void( vPreemptiveTick )( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick );
|
||||
#endif
|
||||
|
||||
/* Configure the PIT period. */
|
||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||
|
||||
/* Enable the interrupt. Global interrupts are disabled at this point so
|
||||
this is safe. */
|
||||
* this is safe. */
|
||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
* Changes from V3.2.4
|
||||
*
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
|
@ -47,17 +47,17 @@
|
|||
#include "AT91SAM7X256.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
|
|
@ -69,7 +69,7 @@ void vPortISRStartFirstTask( void );
|
|||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -85,8 +85,8 @@ void vPortISRStartFirstTask( void )
|
|||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* Within an IRQ ISR the link register has an offset from the true return
|
||||
address, but an SWI ISR does not. Add the offset manually so the same
|
||||
ISR return code can be used in both cases. */
|
||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||
* ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
|
|
@ -107,16 +107,16 @@ void vPortYieldProcessor( void )
|
|||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
uint32_t ulDummy;
|
||||
|
||||
/* Increment the tick count - which may wake some tasks but as the
|
||||
preemptive scheduler is not being used any woken task is not given
|
||||
processor time no matter what its priority. */
|
||||
* preemptive scheduler is not being used any woken task is not given
|
||||
* processor time no matter what its priority. */
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Clear the PIT interrupt. */
|
||||
|
|
@ -126,11 +126,11 @@ void vPortYieldProcessor( void )
|
|||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 0 */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the current task. */
|
||||
|
|
@ -149,7 +149,7 @@ void vPortYieldProcessor( void )
|
|||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -158,49 +158,49 @@ void vPortYieldProcessor( void )
|
|||
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||
*/
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
be saved to the stack. Instead the critical section nesting level is stored
|
||||
in a variable, which is then saved as part of the stack context. */
|
||||
* different optimisation levels. The interrupt flags can therefore not always
|
||||
* be saved to the stack. Instead the critical section nesting level is stored
|
||||
* in a variable, which is then saved as part of the stack context. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
|
|
@ -212,16 +212,16 @@ void vPortExitCritical( void )
|
|||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,27 +27,27 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
+ replaced them with hard coded registers. This will ensure the
|
||||
+ assembler does not select the link register as the temp register as
|
||||
+ was occasionally happening previously.
|
||||
+
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
+
|
||||
+ Changes from V4.5.0
|
||||
+
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
+ macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
|
@ -69,34 +69,34 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -109,92 +109,92 @@ typedef unsigned long UBaseType_t;
|
|||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -209,42 +209,42 @@ extern volatile uint32_t ulCriticalNesting; \
|
|||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
|
|
@ -44,21 +44,21 @@
|
|||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the VIC for the tick ISR. */
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -79,61 +79,63 @@ extern void vPortISRStartFirstTask( void );
|
|||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* start of the task. The offset is added to make the return address appear
|
||||
* as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
|
|
@ -145,9 +147,9 @@ StackType_t *pxOriginalTOS;
|
|||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
means the interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
* means the interrupt flags cannot always be stored on the stack and will
|
||||
* instead be stored in a variable, which is then saved as part of the
|
||||
* tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -157,7 +159,7 @@ StackType_t *pxOriginalTOS;
|
|||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
|
|
@ -171,7 +173,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -180,18 +182,19 @@ void vPortEndScheduler( void )
|
|||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
uint32_t ulCompareMatch;
|
||||
extern void ( vTickISR )( void );
|
||||
uint32_t ulCompareMatch;
|
||||
|
||||
extern void( vTickISR )( void );
|
||||
|
||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||
defaulted to zero but can be used if necessary. */
|
||||
* defaulted to zero but can be used if necessary. */
|
||||
T0_PR = portPRESCALE_VALUE;
|
||||
|
||||
/* Calculate the match value required for our wanted tick rate. */
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Protect against divide by zero. Using an if() statement still results
|
||||
in a warning - hence the #if. */
|
||||
* in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
|
|
@ -207,13 +210,13 @@ extern void ( vTickISR )( void );
|
|||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* scheduler is being used. */
|
||||
|
||||
VICVectAddr0 = ( int32_t ) vTickISR;
|
||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
* so it is okay to do this here. */
|
||||
T0_TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -28,45 +28,45 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V2.5.2
|
||||
|
||||
+ The critical section management functions have been changed. These no
|
||||
longer modify the stack and are safe to use at all optimisation levels.
|
||||
The functions are now also the same for both ARM and THUMB modes.
|
||||
|
||||
Changes from V2.6.0
|
||||
|
||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||
allow the demo to link when using the cooperative scheduler.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
* Changes from V2.5.2
|
||||
*
|
||||
+ The critical section management functions have been changed. These no
|
||||
+ longer modify the stack and are safe to use at all optimisation levels.
|
||||
+ The functions are now also the same for both ARM and THUMB modes.
|
||||
+
|
||||
+ Changes from V2.6.0
|
||||
+
|
||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||
+ allow the demo to link when using the cooperative scheduler.
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
|
|
@ -78,7 +78,7 @@ void vPortISRStartFirstTask( void );
|
|||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -94,8 +94,8 @@ void vPortISRStartFirstTask( void )
|
|||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* Within an IRQ ISR the link register has an offset from the true return
|
||||
address, but an SWI ISR does not. Add the offset manually so the same
|
||||
ISR return code can be used in both cases. */
|
||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||
* ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
|
|
@ -112,14 +112,14 @@ void vPortYieldProcessor( void )
|
|||
/*
|
||||
* The ISR used for the scheduler tick.
|
||||
*/
|
||||
void vTickISR( void ) __attribute__((naked));
|
||||
void vTickISR( void ) __attribute__( ( naked ) );
|
||||
void vTickISR( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
* task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n" \
|
||||
|
|
@ -146,50 +146,50 @@ void vTickISR( void )
|
|||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
be saved to the stack. Instead the critical section nesting level is stored
|
||||
in a variable, which is then saved as part of the stack context. */
|
||||
* different optimisation levels. The interrupt flags can therefore not always
|
||||
* be saved to the stack. Instead the critical section nesting level is stored
|
||||
* in a variable, which is then saved as part of the stack context. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
|
|
@ -201,16 +201,16 @@ void vPortExitCritical( void )
|
|||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,34 +46,34 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -86,92 +86,92 @@ typedef unsigned long UBaseType_t;
|
|||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
extern void vTaskSwitchContext( void );
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -186,42 +186,42 @@ extern void vTaskSwitchContext( void );
|
|||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
|
|
@ -44,21 +44,21 @@
|
|||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the VIC for the tick ISR. */
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -79,61 +79,63 @@ extern void vPortISRStartFirstTask( void );
|
|||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* start of the task. The offset is added to make the return address appear
|
||||
* as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
|
|
@ -145,9 +147,9 @@ StackType_t *pxOriginalTOS;
|
|||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
means the interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
* means the interrupt flags cannot always be stored on the stack and will
|
||||
* instead be stored in a variable, which is then saved as part of the
|
||||
* tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -157,7 +159,7 @@ StackType_t *pxOriginalTOS;
|
|||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
|
|
@ -171,7 +173,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -180,21 +182,21 @@ void vPortEndScheduler( void )
|
|||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
uint32_t ulCompareMatch;
|
||||
uint32_t ulCompareMatch;
|
||||
|
||||
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
||||
T0TCR = 2; /* Stop and reset the timer */
|
||||
T0CTCR = 0; /* Timer mode */
|
||||
PCLKSEL0 = ( PCLKSEL0 & ( ~( 0x3 << 2 ) ) ) | ( 0x01 << 2 );
|
||||
T0TCR = 2; /* Stop and reset the timer */
|
||||
T0CTCR = 0; /* Timer mode */
|
||||
|
||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||
defaulted to zero but can be used if necessary. */
|
||||
* defaulted to zero but can be used if necessary. */
|
||||
T0PR = portPRESCALE_VALUE;
|
||||
|
||||
/* Calculate the match value required for our wanted tick rate. */
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Protect against divide by zero. Using an if() statement still results
|
||||
in a warning - hence the #if. */
|
||||
* in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
|
|
@ -203,21 +205,21 @@ uint32_t ulCompareMatch;
|
|||
T0MR1 = ulCompareMatch;
|
||||
|
||||
/* Generate tick with timer 0 compare match. */
|
||||
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
||||
T0MCR = ( 3 << 3 ); /* Reset timer on match and generate interrupt */
|
||||
|
||||
/* Setup the VIC for the timer. */
|
||||
VICIntEnable = 0x00000010;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
extern void( vPreemptiveTick )( void );
|
||||
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
||||
}
|
||||
#else
|
||||
{
|
||||
extern void ( vNonPreemptiveTick )( void );
|
||||
extern void( vNonPreemptiveTick )( void );
|
||||
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -225,7 +227,7 @@ uint32_t ulCompareMatch;
|
|||
VICVectCntl4 = 1;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
* so it is okay to do this here. */
|
||||
T0TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -28,27 +28,27 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
|
|
@ -60,7 +60,7 @@ void vPortISRStartFirstTask( void );
|
|||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -76,15 +76,15 @@ void vPortISRStartFirstTask( void )
|
|||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* Within an IRQ ISR the link register has an offset from the true return
|
||||
address, but an SWI ISR does not. Add the offset manually so the same
|
||||
ISR return code can be used in both cases. */
|
||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||
* ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
__asm volatile( "bl vTaskSwitchContext" );
|
||||
__asm volatile ( "bl vTaskSwitchContext" );
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
|
|
@ -99,9 +99,9 @@ void vPortYieldProcessor( void )
|
|||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
|
|
@ -109,18 +109,18 @@ void vPortYieldProcessor( void )
|
|||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 0 */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
* task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n" \
|
||||
|
|
@ -138,7 +138,7 @@ void vPortYieldProcessor( void )
|
|||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -149,50 +149,50 @@ void vPortYieldProcessor( void )
|
|||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
be saved to the stack. Instead the critical section nesting level is stored
|
||||
in a variable, which is then saved as part of the stack context. */
|
||||
* different optimisation levels. The interrupt flags can therefore not always
|
||||
* be saved to the stack. Instead the critical section nesting level is stored
|
||||
* in a variable, which is then saved as part of the stack context. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
|
|
@ -204,16 +204,16 @@ void vPortExitCritical( void )
|
|||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,27 +27,27 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
+ replaced them with hard coded registers. This will ensure the
|
||||
+ assembler does not select the link register as the temp register as
|
||||
+ was occasionally happening previously.
|
||||
+
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
+ than each line having its own asm block.
|
||||
+
|
||||
+ Changes from V4.5.0
|
||||
+
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
+ macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
|
@ -69,34 +69,34 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -109,92 +109,92 @@ typedef unsigned long UBaseType_t;
|
|||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -209,42 +209,42 @@ extern volatile uint32_t ulCriticalNesting; \
|
|||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -34,104 +34,104 @@
|
|||
#include "task.h"
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
/* Check the configuration. */
|
||||
#if( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||
#endif
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/* In case security extensions are implemented. */
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
portmacro.h. */
|
||||
* portmacro.h. */
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
(but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
* (but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
floating point context after they have been created. A variable is stored as
|
||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
does not have an FPU context, or any other value if the task does have an FPU
|
||||
context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||
|
||||
#if defined( GUEST )
|
||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||
#else
|
||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||
/* At the time of writing, the BSP only supports EL3. */
|
||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||
#endif
|
||||
|
||||
|
||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
* point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||
|
||||
/* The I bit in the DAIF bits. */
|
||||
#define portDAIF_I ( 0x80 )
|
||||
#define portDAIF_I ( 0x80 )
|
||||
|
||||
/* Macro to unmask all interrupt priorities. */
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
portDISABLE_INTERRUPTS(); \
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||
__asm volatile ( "DSB SY \n" \
|
||||
"ISB SY \n" ); \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
}
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
portDISABLE_INTERRUPTS(); \
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||
__asm volatile ( "DSB SY \n" \
|
||||
"ISB SY \n" ); \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
}
|
||||
|
||||
/* Hardware specifics used when sanity checking the configuration. */
|
||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -144,104 +144,106 @@ extern void vPortRestoreTaskContext( void );
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
* variable has to be stored as part of the task context and must be initialised to
|
||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
* the scheduler starts. As it is stored as part of the task context it will
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||
|
||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||
then floating point context must be saved and restored for the task. */
|
||||
* then floating point context must be saved and restored for the task. */
|
||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
uint64_t ullPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
if the nesting depth is 0. */
|
||||
* if the nesting depth is 0. */
|
||||
uint64_t ullPortInterruptNesting = 0;
|
||||
|
||||
/* Used in the ASM code. */
|
||||
__attribute__(( used )) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__attribute__( ( used ) ) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First all the general purpose registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_PSTATE;
|
||||
|
|
@ -251,13 +253,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
enabled. */
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start without a floating point context. A task that uses
|
||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
any floating point instructions. */
|
||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
* any floating point instructions. */
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -266,21 +268,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
uint32_t ulAPSR;
|
||||
uint32_t ulAPSR;
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine how many priority bits are implemented in the GIC.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to
|
||||
all possible bits. */
|
||||
* all possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
|
@ -293,13 +295,13 @@ uint32_t ulAPSR;
|
|||
}
|
||||
|
||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
value. */
|
||||
* value. */
|
||||
|
||||
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
||||
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
|
@ -309,26 +311,28 @@ uint32_t ulAPSR;
|
|||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||
|
||||
#if defined( GUEST )
|
||||
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
||||
configASSERT( ulAPSR == portEL1 );
|
||||
if( ulAPSR == portEL1 )
|
||||
#else
|
||||
configASSERT( ulAPSR == portEL3 );
|
||||
if( ulAPSR == portEL3 )
|
||||
#endif
|
||||
#if defined( GUEST )
|
||||
#warning "Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH."
|
||||
configASSERT( ulAPSR == portEL1 );
|
||||
|
||||
if( ulAPSR == portEL1 )
|
||||
#else
|
||||
configASSERT( ulAPSR == portEL3 );
|
||||
|
||||
if( ulAPSR == portEL3 )
|
||||
#endif
|
||||
{
|
||||
/* Only continue if the binary point value is set to its lowest possible
|
||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
more information. */
|
||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
* more information. */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
|
||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||
not execute while the scheduler is being started. Interrupts are
|
||||
automatically turned back on in the CPU when the first task starts
|
||||
executing. */
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
|
|
@ -346,7 +350,7 @@ uint32_t ulAPSR;
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ullCriticalNesting == 1000ULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -357,15 +361,15 @@ void vPortEnterCritical( void )
|
|||
uxPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ullCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
* assert() if it is being called from an interrupt context. Only API
|
||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
* the critical nesting count is 1 to protect against recursive calls if the
|
||||
* assert function also uses a critical section. */
|
||||
if( ullCriticalNesting == 1ULL )
|
||||
{
|
||||
configASSERT( ullPortInterruptNesting == 0 );
|
||||
|
|
@ -378,15 +382,15 @@ void vPortExitCritical( void )
|
|||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
exited. */
|
||||
* exited. */
|
||||
ullCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
priorities must be re-enabled. */
|
||||
* priorities must be re-enabled. */
|
||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
should be unmasked. */
|
||||
* should be unmasked. */
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
|
|
@ -403,23 +407,23 @@ void FreeRTOS_Tick_Handler( void )
|
|||
#endif
|
||||
|
||||
/* Interrupts should not be enabled before this point. */
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
uint32_t ulMaskBits;
|
||||
|
||||
__asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" );
|
||||
__asm volatile ( "mrs %0, daif" : "=r" ( ulMaskBits )::"memory" );
|
||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
so there is no need to save and restore the current mask value. It is
|
||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
updated. */
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n" ::: "memory" );
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n" ::: "memory" );
|
||||
|
||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||
configCLEAR_TICK_INTERRUPT();
|
||||
|
|
@ -439,11 +443,11 @@ void FreeRTOS_Tick_Handler( void )
|
|||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (which is saved as part of the task context). */
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
ullPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Consider initialising the FPSR here - but probably not necessary in
|
||||
AArch64. */
|
||||
* AArch64. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -458,11 +462,12 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
|||
|
||||
UBaseType_t uxPortSetInterruptMask( void )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
uint32_t ulReturn;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
updated. */
|
||||
* updated. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
{
|
||||
/* Interrupts were already masked. */
|
||||
|
|
@ -472,45 +477,46 @@ uint32_t ulReturn;
|
|||
{
|
||||
ulReturn = pdFALSE;
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n" ::: "memory" );
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n" ::: "memory" );
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible. */
|
||||
* an interrupt that has been assigned a priority above
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||
* from interrupts that have been assigned a priority at or below
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* Numerically low interrupt priority numbers represent logically high
|
||||
* interrupt priorities, therefore the priority of the interrupt must
|
||||
* be set to a value equal to or numerically *higher* than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
|
||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||
that define each interrupt's priority to be split between bits that
|
||||
define the interrupt's pre-emption priority bits and bits that define
|
||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
to be pre-emption priority bits. The following assertion will fail if
|
||||
this is not the case (if some bits represent a sub-priority).
|
||||
|
||||
The priority grouping is configured by the GIC's binary point register
|
||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
possible value (which may be above 0). */
|
||||
* that define each interrupt's priority to be split between bits that
|
||||
* define the interrupt's pre-emption priority bits and bits that define
|
||||
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
* to be pre-emption priority bits. The following assertion will fail if
|
||||
* this is not the case (if some bits represent a sub-priority).
|
||||
*
|
||||
* The priority grouping is configured by the GIC's binary point register
|
||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
* possible value (which may be above 0). */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,57 +46,58 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE size_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE size_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef uint64_t UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef uint64_t UBaseType_t;
|
||||
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 16
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 16
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||
{ \
|
||||
extern uint64_t ullPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ullPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern uint64_t ullPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ullPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#if defined( GUEST )
|
||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||
#else
|
||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
|
@ -104,106 +105,106 @@ extern UBaseType_t uxPortSetInterruptMask( void );
|
|||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
__asm volatile ( "ISB SY" );
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
__asm volatile ( "ISB SY" );
|
||||
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
not required for this port but included in case common demo code that uses these
|
||||
macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||
before any floating point instructions are executed. */
|
||||
* before any floating point instructions are executed. */
|
||||
void vPortTaskUsesFPU( void );
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif /* configASSERT */
|
||||
|
||||
#define portNOP() __asm volatile( "NOP" )
|
||||
#define portINLINE __inline
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
#define portINLINE __inline
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
number of bits implemented by the interrupt controller. */
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
/* Interrupt controller access addresses. */
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -34,92 +34,92 @@
|
|||
#include "task.h"
|
||||
|
||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
/* Check the configuration. */
|
||||
#if( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||
#endif
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/* In case security extensions are implemented. */
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
portmacro.h. */
|
||||
* portmacro.h. */
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
(but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
* (but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
floating point context after they have been created. A variable is stored as
|
||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
does not have an FPU context, or any other value if the task does have an FPU
|
||||
context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||
|
||||
#if defined( GUEST )
|
||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||
#else
|
||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||
/* At the time of writing, the BSP only supports EL3. */
|
||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||
#endif
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||
|
||||
/* The I bit in the DAIF bits. */
|
||||
#define portDAIF_I ( 0x80 )
|
||||
#define portDAIF_I ( 0x80 )
|
||||
|
||||
/* Macro to unmask all interrupt priorities. */
|
||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
__asm volatile ( "MSR DAIFSET, #2 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
"MSR s3_0_c4_c6_0, %0 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
"MSR DAIFCLR, #2 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
::"r"( portUNMASK_VALUE ) ); \
|
||||
}
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
__asm volatile ( "MSR DAIFSET, #2 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
"MSR s3_0_c4_c6_0, %0 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
"MSR DAIFCLR, #2 \n" \
|
||||
"DSB SY \n" \
|
||||
"ISB SY \n" \
|
||||
::"r" ( portUNMASK_VALUE ) ); \
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -132,101 +132,103 @@ extern void vPortRestoreTaskContext( void );
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
* variable has to be stored as part of the task context and must be initialised to
|
||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
* the scheduler starts. As it is stored as part of the task context it will
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||
|
||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||
then floating point context must be saved and restored for the task. */
|
||||
* then floating point context must be saved and restored for the task. */
|
||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
uint64_t ullPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
if the nesting depth is 0. */
|
||||
* if the nesting depth is 0. */
|
||||
uint64_t ullPortInterruptNesting = 0;
|
||||
|
||||
/* Used in the ASM code. */
|
||||
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First all the general purpose registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_PSTATE;
|
||||
|
|
@ -236,13 +238,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
enabled. */
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start without a floating point context. A task that uses
|
||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
any floating point instructions. */
|
||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
* any floating point instructions. */
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
|
@ -251,23 +253,26 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
uint32_t ulAPSR;
|
||||
uint32_t ulAPSR;
|
||||
|
||||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||
|
||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||
|
||||
#if defined( GUEST )
|
||||
configASSERT( ulAPSR == portEL1 );
|
||||
if( ulAPSR == portEL1 )
|
||||
#else
|
||||
configASSERT( ulAPSR == portEL3 );
|
||||
if( ulAPSR == portEL3 )
|
||||
#endif
|
||||
#if defined( GUEST )
|
||||
configASSERT( ulAPSR == portEL1 );
|
||||
|
||||
if( ulAPSR == portEL1 )
|
||||
#else
|
||||
configASSERT( ulAPSR == portEL3 );
|
||||
|
||||
if( ulAPSR == portEL3 )
|
||||
#endif
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||
not execute while the scheduler is being started. Interrupts are
|
||||
automatically turned back on in the CPU when the first task starts
|
||||
executing. */
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
|
|
@ -284,7 +289,7 @@ uint32_t ulAPSR;
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ullCriticalNesting == 1000ULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -295,15 +300,15 @@ void vPortEnterCritical( void )
|
|||
uxPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ullCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
* assert() if it is being called from an interrupt context. Only API
|
||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
* the critical nesting count is 1 to protect against recursive calls if the
|
||||
* assert function also uses a critical section. */
|
||||
if( ullCriticalNesting == 1ULL )
|
||||
{
|
||||
configASSERT( ullPortInterruptNesting == 0 );
|
||||
|
|
@ -316,15 +321,15 @@ void vPortExitCritical( void )
|
|||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
exited. */
|
||||
* exited. */
|
||||
ullCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
priorities must be re-enabled. */
|
||||
* priorities must be re-enabled. */
|
||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
should be unmasked. */
|
||||
* should be unmasked. */
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
|
|
@ -344,25 +349,25 @@ void FreeRTOS_Tick_Handler( void )
|
|||
#endif
|
||||
|
||||
/* Interrupts should not be enabled before this point. */
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
uint32_t ulMaskBits;
|
||||
|
||||
__asm volatile( "MRS %0, DAIF" : "=r"( ulMaskBits ) :: "memory" );
|
||||
__asm volatile ( "MRS %0, DAIF" : "=r" ( ulMaskBits )::"memory" );
|
||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
so there is no need to save and restore the current mask value. It is
|
||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
updated. */
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
||||
"DSB SY \n"
|
||||
"ISB SY \n"
|
||||
:: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||
::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||
|
||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||
configCLEAR_TICK_INTERRUPT();
|
||||
|
|
@ -382,11 +387,11 @@ void FreeRTOS_Tick_Handler( void )
|
|||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (which is saved as part of the task context). */
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
ullPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Consider initialising the FPSR here - but probably not necessary in
|
||||
AArch64. */
|
||||
* AArch64. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -401,14 +406,15 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
|||
|
||||
UBaseType_t uxPortSetInterruptMask( void )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
uint64_t ullPMRValue;
|
||||
uint32_t ulReturn;
|
||||
uint64_t ullPMRValue;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
updated. */
|
||||
* updated. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||
__asm volatile ( "MRS %0, s3_0_c4_c6_0" : "=r" ( ullPMRValue ) );
|
||||
|
||||
if( ullPMRValue == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
{
|
||||
/* Interrupts were already masked. */
|
||||
|
|
@ -421,7 +427,7 @@ uint64_t ullPMRValue;
|
|||
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
||||
"DSB SY \n"
|
||||
"ISB SY \n"
|
||||
:: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||
::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
|
@ -430,27 +436,28 @@ uint64_t ullPMRValue;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible. */
|
||||
* an interrupt that has been assigned a priority above
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||
* from interrupts that have been assigned a priority at or below
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* Numerically low interrupt priority numbers represent logically high
|
||||
* interrupt priorities, therefore the priority of the interrupt must
|
||||
* be set to a value equal to or numerically *higher* than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
uint64_t ullRunningInterruptPriority;
|
||||
/* s3_0_c12_c11_3 is ICC_RPR_EL1. */
|
||||
__asm volatile ( "MRS %0, s3_0_c12_c11_3" : "=r" ( ullRunningInterruptPriority ) );
|
||||
|
||||
configASSERT( ullRunningInterruptPriority >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,57 +46,58 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE size_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE size_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef uint64_t UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef uint64_t UBaseType_t;
|
||||
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 16
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 16
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||
{ \
|
||||
extern uint64_t ullPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ullPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern uint64_t ullPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ullPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#if defined( GUEST )
|
||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||
#else
|
||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
|
@ -104,91 +105,91 @@ extern UBaseType_t uxPortSetInterruptMask( void );
|
|||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
__asm volatile ( "ISB SY" );
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||
__asm volatile ( "DSB SY" ); \
|
||||
__asm volatile ( "ISB SY" );
|
||||
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
not required for this port but included in case common demo code that uses these
|
||||
macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||
before any floating point instructions are executed. */
|
||||
* before any floating point instructions are executed. */
|
||||
void vPortTaskUsesFPU( void );
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif /* configASSERT */
|
||||
|
||||
#define portNOP() __asm volatile( "NOP" )
|
||||
#define portINLINE __inline
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
#define portINLINE __inline
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
number of bits implemented by the interrupt controller. */
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -35,123 +35,123 @@
|
|||
#include "task.h"
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
/* Check the configuration. */
|
||||
#if( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||
#endif
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/* In case security extensions are implemented. */
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
portmacro.h. */
|
||||
* portmacro.h. */
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
(but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
* (but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
floating point context after they have been created. A variable is stored as
|
||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
does not have an FPU context, or any other value if the task does have an FPU
|
||||
context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )
|
||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )
|
||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||
|
||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
* point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||
|
||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||
mode. */
|
||||
#define portAPSR_USER_MODE ( 0x10 )
|
||||
* mode. */
|
||||
#define portAPSR_USER_MODE ( 0x10 )
|
||||
|
||||
/* The critical section macros only mask interrupts up to an application
|
||||
determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||
the CPU itself before modifying certain hardware registers. */
|
||||
#define portCPU_IRQ_DISABLE() \
|
||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||
__asm volatile ( "DSB" ); \
|
||||
* determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||
* the CPU itself before modifying certain hardware registers. */
|
||||
#define portCPU_IRQ_DISABLE() \
|
||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||
__asm volatile ( "DSB" ); \
|
||||
__asm volatile ( "ISB" );
|
||||
|
||||
#define portCPU_IRQ_ENABLE() \
|
||||
__asm volatile ( "CPSIE i" ::: "memory" ); \
|
||||
__asm volatile ( "DSB" ); \
|
||||
#define portCPU_IRQ_ENABLE() \
|
||||
__asm volatile ( "CPSIE i" ::: "memory" ); \
|
||||
__asm volatile ( "DSB" ); \
|
||||
__asm volatile ( "ISB" );
|
||||
|
||||
|
||||
/* Macro to unmask all interrupt priorities. */
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
portCPU_IRQ_DISABLE(); \
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||
__asm volatile ( "DSB \n" \
|
||||
"ISB \n" ); \
|
||||
portCPU_IRQ_ENABLE(); \
|
||||
}
|
||||
#define portCLEAR_INTERRUPT_MASK() \
|
||||
{ \
|
||||
portCPU_IRQ_DISABLE(); \
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||
__asm volatile ( "DSB \n" \
|
||||
"ISB \n" ); \
|
||||
portCPU_IRQ_ENABLE(); \
|
||||
}
|
||||
|
||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
|
||||
/* Let the user override the pre-loading of the initial LR with the address of
|
||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||
debugger. */
|
||||
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||
* debugger. */
|
||||
#ifdef configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#else
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
||||
registers, plus a 32-bit status register. */
|
||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||
* registers, plus a 32-bit status register. */
|
||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -185,47 +185,49 @@ static void prvTaskExitError( void );
|
|||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||
* called vApplicationIRQHandler().
|
||||
*/
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
* variable has to be stored as part of the task context and must be initialised to
|
||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
* the scheduler starts. As it is stored as part of the task context it will
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||
a floating point context must be saved and restored for the task. */
|
||||
* a floating point context must be saved and restored for the task. */
|
||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
if the nesting depth is 0. */
|
||||
* if the nesting depth is 0. */
|
||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||
|
||||
/* Used in the asm file. */
|
||||
__attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||
__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__attribute__( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||
__attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro.
|
||||
|
||||
The fist real value on the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||
GDB does not try decoding a non-existent return address. */
|
||||
* expected by the portRESTORE_CONTEXT() macro.
|
||||
*
|
||||
* The fist real value on the stack is the status register, which is set for
|
||||
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||
* GDB does not try decoding a non-existent return address. */
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
|
|
@ -247,51 +249,51 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
pxTopOfStack--;
|
||||
|
||||
/* Next all the registers other than the stack pointer. */
|
||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */
|
||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
enabled. */
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
#if( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
{
|
||||
/* The task will start without a floating point context. A task that
|
||||
uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
executing any floating point instructions. */
|
||||
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
* executing any floating point instructions. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
}
|
||||
#elif( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
{
|
||||
/* The task will start with a floating point context. Leave enough
|
||||
space for the registers - and ensure they are initialised to 0. */
|
||||
* space for the registers - and ensure they are initialised to 0. */
|
||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||
|
||||
|
|
@ -299,11 +301,11 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
*pxTopOfStack = pdTRUE;
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
}
|
||||
#else
|
||||
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
{
|
||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
||||
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
|
|
@ -312,34 +314,37 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
its caller as there is nothing to return to. If a task wants to exit it
|
||||
should instead call vTaskDelete( NULL ).
|
||||
|
||||
Artificially force an assert() to be triggered if configASSERT() is
|
||||
defined, then stop here so application writers can catch the error. */
|
||||
* its caller as there is nothing to return to. If a task wants to exit it
|
||||
* should instead call vTaskDelete( NULL ).
|
||||
*
|
||||
* Artificially force an assert() to be triggered if configASSERT() is
|
||||
* defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
uint32_t ulAPSR;
|
||||
uint32_t ulAPSR;
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine how many priority bits are implemented in the GIC.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to
|
||||
all possible bits. */
|
||||
* all possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
|
@ -352,35 +357,35 @@ uint32_t ulAPSR;
|
|||
}
|
||||
|
||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
value. */
|
||||
* value. */
|
||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
|
||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||
Privileged mode for the scheduler to start. */
|
||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
|
||||
* Privileged mode for the scheduler to start. */
|
||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||
|
||||
if( ulAPSR != portAPSR_USER_MODE )
|
||||
{
|
||||
/* Only continue if the binary point value is set to its lowest possible
|
||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
more information. */
|
||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
* more information. */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
|
||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||
not execute while the scheduler is being started. Interrupts are
|
||||
automatically turned back on in the CPU when the first task starts
|
||||
executing. */
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
|
|
@ -392,10 +397,10 @@ uint32_t ulAPSR;
|
|||
}
|
||||
|
||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||
a non-privileged mode or the binary point register was not set to its lowest
|
||||
possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
warning about it being defined but not referenced in the case that the user
|
||||
defines their own exit address. */
|
||||
* a non-privileged mode or the binary point register was not set to its lowest
|
||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
* warning about it being defined but not referenced in the case that the user
|
||||
* defines their own exit address. */
|
||||
( void ) prvTaskExitError;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -404,7 +409,7 @@ uint32_t ulAPSR;
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -414,16 +419,16 @@ void vPortEnterCritical( void )
|
|||
/* Mask interrupts up to the max syscall interrupt priority. */
|
||||
ulPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
* assert() if it is being called from an interrupt context. Only API
|
||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
* the critical nesting count is 1 to protect against recursive calls if the
|
||||
* assert function also uses a critical section. */
|
||||
if( ulCriticalNesting == 1 )
|
||||
{
|
||||
configASSERT( ulPortInterruptNesting == 0 );
|
||||
|
|
@ -436,15 +441,15 @@ void vPortExitCritical( void )
|
|||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
exited. */
|
||||
* exited. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
priorities must be re-enabled. */
|
||||
* priorities must be re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
should be unmasked. */
|
||||
* should be unmasked. */
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
|
|
@ -454,14 +459,14 @@ void vPortExitCritical( void )
|
|||
void FreeRTOS_Tick_Handler( void )
|
||||
{
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
so there is no need to save and restore the current mask value. It is
|
||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
updated. */
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb \n"
|
||||
"isb \n" ::: "memory" );
|
||||
__asm volatile ( "dsb \n"
|
||||
"isb \n" ::: "memory" );
|
||||
portCPU_IRQ_ENABLE();
|
||||
|
||||
/* Increment the RTOS tick. */
|
||||
|
|
@ -476,18 +481,18 @@ void FreeRTOS_Tick_Handler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
uint32_t ulInitialFPSCR = 0;
|
||||
uint32_t ulInitialFPSCR = 0;
|
||||
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (which is saved as part of the task context). */
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Initialise the floating point status register. */
|
||||
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
|
||||
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
|
|
@ -504,11 +509,12 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
|||
|
||||
uint32_t ulPortSetInterruptMask( void )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
uint32_t ulReturn;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
updated. */
|
||||
* updated. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
{
|
||||
/* Interrupts were already masked. */
|
||||
|
|
@ -518,45 +524,46 @@ uint32_t ulReturn;
|
|||
{
|
||||
ulReturn = pdFALSE;
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb \n"
|
||||
"isb \n" ::: "memory" );
|
||||
__asm volatile ( "dsb \n"
|
||||
"isb \n" ::: "memory" );
|
||||
}
|
||||
|
||||
portCPU_IRQ_ENABLE();
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible. */
|
||||
* an interrupt that has been assigned a priority above
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||
* from interrupts that have been assigned a priority at or below
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* Numerically low interrupt priority numbers represent logically high
|
||||
* interrupt priorities, therefore the priority of the interrupt must
|
||||
* be set to a value equal to or numerically *higher* than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
|
||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||
that define each interrupt's priority to be split between bits that
|
||||
define the interrupt's pre-emption priority bits and bits that define
|
||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
to be pre-emption priority bits. The following assertion will fail if
|
||||
this is not the case (if some bits represent a sub-priority).
|
||||
|
||||
The priority grouping is configured by the GIC's binary point register
|
||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
possible value (which may be above 0). */
|
||||
* that define each interrupt's priority to be split between bits that
|
||||
* define the interrupt's pre-emption priority bits and bits that define
|
||||
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
* to be pre-emption priority bits. The following assertion will fail if
|
||||
* this is not the case (if some bits represent a sub-priority).
|
||||
*
|
||||
* The priority grouping is configured by the GIC's binary point register
|
||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
* possible value (which may be above 0). */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,54 +46,54 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||
{ \
|
||||
extern uint32_t ulPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ulPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern uint32_t ulPortYieldRequired; \
|
||||
\
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ulPortYieldRequired = pdTRUE; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
|
@ -102,105 +102,106 @@ extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
|||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
not required for this port but included in case common demo code that uses these
|
||||
macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||
created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||
themselves an FPU context before using any FPU instructions. If
|
||||
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||
by default. */
|
||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
* created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||
* themselves an FPU context before using any FPU instructions. If
|
||||
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||
* by default. */
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
void vPortTaskUsesFPU( void );
|
||||
#else
|
||||
/* Each task has an FPU context already, so define this function away to
|
||||
nothing to prevent it being called accidentally. */
|
||||
|
||||
/* Each task has an FPU context already, so define this function away to
|
||||
* nothing to prevent it being called accidentally. */
|
||||
#define vPortTaskUsesFPU()
|
||||
#endif
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif /* configASSERT */
|
||||
|
||||
#define portNOP() __asm volatile( "NOP" )
|
||||
#define portINLINE __inline
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
#define portINLINE __inline
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
number of bits implemented by the interrupt controller. */
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
/* Interrupt controller access addresses. */
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -205,20 +205,20 @@ void vPortStartFirstTask( void )
|
|||
* Not all M0 parts have the application vector table at address 0. */
|
||||
__asm volatile (
|
||||
" .syntax unified \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
||||
" ldr r3, [r2] \n"
|
||||
" ldr r0, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" movs r0, #2 \n"/* Switch to the psp stack. */
|
||||
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" movs r0, #2 \n" /* Switch to the psp stack. */
|
||||
" msr CONTROL, r0 \n"
|
||||
" isb \n"
|
||||
" pop {r0-r5} \n"/* Pop the registers that are saved automatically. */
|
||||
" mov lr, r5 \n"/* lr is now in r5. */
|
||||
" pop {r3} \n"/* Return address is now in r3. */
|
||||
" pop {r2} \n"/* Pop and discard XPSR. */
|
||||
" cpsie i \n"/* The first task has its context and interrupts can be enabled. */
|
||||
" bx r3 \n"/* Finally, jump to the user defined task code. */
|
||||
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
||||
" mov lr, r5 \n" /* lr is now in r5. */
|
||||
" pop {r3} \n" /* Return address is now in r3. */
|
||||
" pop {r2} \n" /* Pop and discard XPSR. */
|
||||
" cpsie i \n" /* The first task has its context and interrupts can be enabled. */
|
||||
" bx r3 \n" /* Finally, jump to the user defined task code. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
||||
|
|
@ -330,13 +330,13 @@ void xPortPendSVHandler( void )
|
|||
" .syntax unified \n"
|
||||
" mrs r0, psp \n"
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||
" ldr r2, [r3] \n"
|
||||
" \n"
|
||||
" subs r0, r0, #32 \n"/* Make space for the remaining low registers. */
|
||||
" str r0, [r2] \n"/* Save the new top of stack. */
|
||||
" stmia r0!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
||||
" mov r4, r8 \n"/* Store the high registers. */
|
||||
" subs r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
||||
" str r0, [r2] \n" /* Save the new top of stack. */
|
||||
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
||||
" mov r4, r8 \n" /* Store the high registers. */
|
||||
" mov r5, r9 \n"
|
||||
" mov r6, r10 \n"
|
||||
" mov r7, r11 \n"
|
||||
|
|
@ -346,21 +346,21 @@ void xPortPendSVHandler( void )
|
|||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" pop {r2, r3} \n"/* lr goes in r3. r2 now holds tcb pointer. */
|
||||
" pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */
|
||||
" \n"
|
||||
" ldr r1, [r2] \n"
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, r0, #16 \n"/* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n"/* Pop the high registers. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, r0, #16 \n" /* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
||||
" mov r8, r4 \n"
|
||||
" mov r9, r5 \n"
|
||||
" mov r10, r6 \n"
|
||||
" mov r11, r7 \n"
|
||||
" \n"
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" \n"
|
||||
" subs r0, r0, #32 \n"/* Go back for the low registers that are not automatically restored. */
|
||||
" ldmia r0!, {r4-r7} \n"/* Pop low registers. */
|
||||
" subs r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
||||
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
||||
" \n"
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ extern void vPortYield( void );
|
|||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
||||
while( 0 )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
||||
while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
|
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* Seal the created secure process stack. */
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
|
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Ensure to never return 0 as a valid context handle. */
|
||||
|
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||
|
||||
/* Check if adding a and b will result in overflow. */
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
|
||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||
|
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
|||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
|||
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||
|
||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||
* that we can enable/disable lazy stacking in port.c file. */
|
||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -46,127 +46,127 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r3, #5 \n" /* r3 = 5. */
|
||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r3, #6 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r3, #7 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" subs r1, #16 \n"
|
||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||
" subs r1, #16 \n"
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" mov lr, r5 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||
" subs r1, #48 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||
" subs r1, #16 \n"
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r3, #5 \n" /* r3 = 5. */
|
||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r3, #6 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r3, #7 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" subs r1, #16 \n"
|
||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||
" subs r1, #16 \n"
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" mov lr, r5 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||
" subs r1, #48 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||
" subs r1, #16 \n"
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n"/* r1 = 2. */
|
||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -177,15 +177,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" movs r1, #1 \n"/* r1 = 1. */
|
||||
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
||||
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" running_privileged: \n"
|
||||
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "r1", "memory"
|
||||
|
|
@ -199,11 +199,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" movs r1, #1 \n"/* r1 = 1. */
|
||||
" bics r0, r1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -215,11 +215,11 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" movs r1, #1 \n"/* r1 = 1. */
|
||||
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -231,14 +231,14 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -277,254 +277,254 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
||||
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" mov r5, lr \n" /* r5 = LR. */
|
||||
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r3, #5 \n" /* r3 = 5. */
|
||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r3, #6 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r3, #7 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" subs r1, #16 \n"
|
||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||
" subs r1, #16 \n"
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" mov lr, r5 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||
" subs r1, #48 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||
" subs r1, #16 \n"
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
||||
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" mov r5, lr \n" /* r5 = LR. */
|
||||
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r3, #5 \n" /* r3 = 5. */
|
||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r3, #6 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r3, #7 \n" /* r3 = 6. */
|
||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r3, #1 \n" /* r3 = 1. */
|
||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" subs r1, #16 \n"
|
||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||
" subs r1, #16 \n"
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" mov lr, r5 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||
" subs r1, #48 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" subs r1, #32 \n"
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||
" subs r1, #16 \n"
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||
" mov r4, r8 \n"/* r4 = r8. */
|
||||
" mov r5, r9 \n"/* r5 = r9. */
|
||||
" mov r6, r10 \n"/* r6 = r10. */
|
||||
" mov r7, r11 \n"/* r7 = r11. */
|
||||
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||
" \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" adds r0, r0, #24 \n"/* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||
" mov r8, r4 \n"/* r8 = r4. */
|
||||
" mov r9, r5 \n"/* r9 = r5. */
|
||||
" mov r10, r6 \n"/* r10 = r6. */
|
||||
" mov r11, r7 \n"/* r11 = r7. */
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
|
||||
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||
" \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
||||
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"movs r0, #4 \n"
|
||||
"mov r1, lr \n"
|
||||
"tst r0, r1 \n"
|
||||
"beq stack_on_msp \n"
|
||||
"stack_on_psp: \n"
|
||||
" mrs r0, psp \n"
|
||||
" b route_svc \n"
|
||||
"stack_on_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" b route_svc \n"
|
||||
" \n"
|
||||
"route_svc: \n"
|
||||
" ldr r2, [r0, #24] \n"
|
||||
" subs r2, #2 \n"
|
||||
" ldrb r3, [r2, #0] \n"
|
||||
" cmp r3, %0 \n"
|
||||
" beq system_call_enter \n"
|
||||
" cmp r3, %1 \n"
|
||||
" beq system_call_enter_1 \n"
|
||||
" cmp r3, %2 \n"
|
||||
" beq system_call_exit \n"
|
||||
" b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"system_call_enter: \n"
|
||||
" b vSystemCallEnter \n"
|
||||
"system_call_enter_1: \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
"system_call_exit: \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "r3", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"movs r0, #4 \n"
|
||||
"mov r1, lr \n"
|
||||
"tst r0, r1 \n"
|
||||
"beq stack_on_msp \n"
|
||||
"stack_on_psp: \n"
|
||||
" mrs r0, psp \n"
|
||||
" b route_svc \n"
|
||||
"stack_on_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" b route_svc \n"
|
||||
" \n"
|
||||
"route_svc: \n"
|
||||
" ldr r2, [r0, #24] \n"
|
||||
" subs r2, #2 \n"
|
||||
" ldrb r3, [r2, #0] \n"
|
||||
" cmp r3, %0 \n"
|
||||
" beq system_call_enter \n"
|
||||
" cmp r3, %1 \n"
|
||||
" beq system_call_enter_1 \n"
|
||||
" cmp r3, %2 \n"
|
||||
" beq system_call_exit \n"
|
||||
" b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"system_call_enter: \n"
|
||||
" b vSystemCallEnter \n"
|
||||
"system_call_enter_1: \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
"system_call_exit: \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "r3", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" movs r0, #4 \n"
|
||||
" mov r1, lr \n"
|
||||
" tst r0, r1 \n"
|
||||
" beq stacking_used_msp \n"
|
||||
" mrs r0, psp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" stacking_used_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" movs r0, #4 \n"
|
||||
" mov r1, lr \n"
|
||||
" tst r0, r1 \n"
|
||||
" beq stacking_used_msp \n"
|
||||
" mrs r0, psp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" stacking_used_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -219,11 +219,11 @@ static void prvTaskExitError( void )
|
|||
void vPortSVCHandler( void )
|
||||
{
|
||||
__asm volatile (
|
||||
" ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */
|
||||
" ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" ldmia r0!, {r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||
" msr psp, r0 \n"/* Restore the task stack pointer. */
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"
|
||||
|
|
@ -239,15 +239,15 @@ void vPortSVCHandler( void )
|
|||
static void prvPortStartFirstTask( void )
|
||||
{
|
||||
__asm volatile (
|
||||
" ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"
|
||||
" ldr r0, [r0] \n"
|
||||
" msr msp, r0 \n"/* Set the msp back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc 0 \n"/* System call to start first task. */
|
||||
" svc 0 \n" /* System call to start first task. */
|
||||
" nop \n"
|
||||
" .ltorg \n"
|
||||
);
|
||||
|
|
@ -308,22 +308,22 @@ BaseType_t xPortStartScheduler( void )
|
|||
if( ulImplementedPrioBits == 8 )
|
||||
{
|
||||
/* When the hardware implements 8 priority bits, there is no way for
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
||||
ulMaxPRIGROUPValue = 0;
|
||||
}
|
||||
|
|
@ -417,11 +417,11 @@ void xPortPendSVHandler( void )
|
|||
" mrs r0, psp \n"
|
||||
" isb \n"
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||
" ldr r2, [r3] \n"
|
||||
" \n"
|
||||
" stmdb r0!, {r4-r11} \n"/* Save the remaining registers. */
|
||||
" str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */
|
||||
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
|
||||
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||
" \n"
|
||||
" stmdb sp!, {r3, r14} \n"
|
||||
" mov r0, %0 \n"
|
||||
|
|
@ -430,10 +430,10 @@ void xPortPendSVHandler( void )
|
|||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"
|
||||
" ldmia sp!, {r3, r14} \n"
|
||||
" \n"/* Restore the context, including the critical nesting count. */
|
||||
" \n" /* Restore the context, including the critical nesting count. */
|
||||
" ldr r1, [r3] \n"
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" ldmia r0!, {r4-r11} \n"/* Pop the registers. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||
" msr psp, r0 \n"
|
||||
" isb \n"
|
||||
" bx r14 \n"
|
||||
|
|
@ -769,4 +769,4 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
|||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -47,42 +47,42 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
|
|
@ -93,156 +93,156 @@
|
|||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not necessary for to use this port. They are defined so the common demo files
|
||||
* (which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Generic helper function. */
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
#define portNOP()
|
||||
|
||||
#define portINLINE __inline
|
||||
#define portINLINE __inline
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n"\
|
||||
" msr basepri, %0 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n"\
|
||||
" mov %1, %2 \n"\
|
||||
" msr basepri, %1 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n" \
|
||||
" msr basepri, %0 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,116 +42,116 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -162,12 +162,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -181,10 +181,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -196,10 +196,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -211,15 +211,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -235,12 +235,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -263,320 +263,320 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n"/* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||
" mov lr, r3 \n"/* LR = r3. */
|
||||
" lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n"/* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n"/* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n"/* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -587,8 +587,8 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -600,12 +600,12 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||
" it ne \n"
|
||||
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -60,8 +60,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
|
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* Seal the created secure process stack. */
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
|
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Ensure to never return 0 as a valid context handle. */
|
||||
|
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||
|
||||
/* Check if adding a and b will result in overflow. */
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
|
||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||
|
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
|||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
|||
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||
|
||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||
* that we can enable/disable lazy stacking in port.c file. */
|
||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,111 +42,111 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n"/* r1 = 2. */
|
||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -157,12 +157,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -176,10 +176,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -191,10 +191,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -206,15 +206,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -230,12 +230,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -247,10 +247,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -258,246 +258,246 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -60,8 +60,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,116 +42,116 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -162,12 +162,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -181,10 +181,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -196,10 +196,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -211,15 +211,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -235,12 +235,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -263,320 +263,320 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n"/* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||
" mov lr, r3 \n"/* LR = r3. */
|
||||
" lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n"/* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n"/* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n"/* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -587,8 +587,8 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -600,12 +600,12 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||
" it ne \n"
|
||||
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M35P"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M35P"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -60,8 +60,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
|
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* Seal the created secure process stack. */
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
|
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Ensure to never return 0 as a valid context handle. */
|
||||
|
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||
|
||||
/* Check if adding a and b will result in overflow. */
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
|
||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||
|
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
|||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
|||
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||
|
||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||
* that we can enable/disable lazy stacking in port.c file. */
|
||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,111 +42,111 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n"/* r1 = 2. */
|
||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -157,12 +157,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -176,10 +176,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -191,10 +191,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -206,15 +206,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -230,12 +230,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -247,10 +247,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -258,246 +258,246 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M35P"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M35P"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -60,8 +60,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -47,123 +47,123 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* MPU specific constants. */
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
|
||||
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL )
|
||||
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL )
|
||||
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
||||
|
||||
#define portSTACK_REGION ( 3UL )
|
||||
#define portGENERAL_PERIPHERALS_REGION ( 4UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 5UL )
|
||||
#define portPRIVILEGED_FLASH_REGION ( 6UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 7UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 0UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 2UL )
|
||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||
#define portSTACK_REGION ( 3UL )
|
||||
#define portGENERAL_PERIPHERALS_REGION ( 4UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 5UL )
|
||||
#define portPRIVILEGED_FLASH_REGION ( 6UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 7UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 0UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 2UL )
|
||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||
|
||||
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
|
||||
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
|
||||
|
||||
typedef struct MPU_REGION_REGISTERS
|
||||
typedef struct MPU_REGION_REGISTERS
|
||||
{
|
||||
uint32_t ulRegionBaseAddress;
|
||||
uint32_t ulRegionAttribute;
|
||||
} xMPU_REGION_REGISTERS;
|
||||
|
||||
typedef struct MPU_REGION_SETTINGS
|
||||
{
|
||||
uint32_t ulRegionStartAddress;
|
||||
uint32_t ulRegionEndAddress;
|
||||
uint32_t ulRegionPermissions;
|
||||
} xMPU_REGION_SETTINGS;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
||||
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulRegionBaseAddress;
|
||||
uint32_t ulRegionAttribute;
|
||||
} xMPU_REGION_REGISTERS;
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
uint32_t * pulSystemCallStack;
|
||||
uint32_t * pulTaskStack;
|
||||
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||
} xSYSTEM_CALL_STACK_INFO;
|
||||
|
||||
typedef struct MPU_REGION_SETTINGS
|
||||
{
|
||||
uint32_t ulRegionStartAddress;
|
||||
uint32_t ulRegionEndAddress;
|
||||
uint32_t ulRegionPermissions;
|
||||
} xMPU_REGION_SETTINGS;
|
||||
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
#define MAX_CONTEXT_SIZE 20
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
|
||||
xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ];
|
||||
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||
uint32_t ulTaskFlags;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
||||
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
uint32_t * pulSystemCallStack;
|
||||
uint32_t * pulTaskStack;
|
||||
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||
} xSYSTEM_CALL_STACK_INFO;
|
||||
|
||||
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
#define MAX_CONTEXT_SIZE 20
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
|
||||
xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ];
|
||||
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||
uint32_t ulTaskFlags;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||
#endif
|
||||
} xMPU_SETTINGS;
|
||||
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||
#endif
|
||||
} xMPU_SETTINGS;
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* SVC numbers for various services. */
|
||||
#define portSVC_START_SCHEDULER 0
|
||||
#define portSVC_YIELD 1
|
||||
#define portSVC_RAISE_PRIVILEGE 2
|
||||
#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_EXIT 5
|
||||
#define portSVC_START_SCHEDULER 0
|
||||
#define portSVC_YIELD 1
|
||||
#define portSVC_RAISE_PRIVILEGE 2
|
||||
#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_EXIT 5
|
||||
|
||||
/* Scheduler utilities. */
|
||||
|
||||
#define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" )
|
||||
#define portYIELD_WITHIN_API() \
|
||||
#define portYIELD() __asm volatile ( " SVC %0 \n" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||
#define portYIELD_WITHIN_API() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
|
|
@ -174,185 +174,187 @@
|
|||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
||||
while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not necessary for to use this port. They are defined so the common demo files
|
||||
* (which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Generic helper function. */
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
#define portNOP()
|
||||
|
||||
#define portINLINE __inline
|
||||
#define portINLINE __inline
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
extern BaseType_t xIsPrivileged( void );
|
||||
extern void vResetPrivilege( void );
|
||||
extern BaseType_t xIsPrivileged( void );
|
||||
extern void vResetPrivilege( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n"\
|
||||
" msr basepri, %0 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n"\
|
||||
" mov %1, %2 \n"\
|
||||
" msr basepri, %1 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n" \
|
||||
" msr basepri, %0 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. *www.FreeRTOS.org/FreeRTOS-V10.3.x.html"
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
||||
#endif
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. *www.FreeRTOS.org/FreeRTOS-V10.3.x.html"
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -351,22 +351,22 @@ BaseType_t xPortStartScheduler( void )
|
|||
if( ulImplementedPrioBits == 8 )
|
||||
{
|
||||
/* When the hardware implements 8 priority bits, there is no way for
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
||||
ulMaxPRIGROUPValue = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -47,45 +47,45 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL
|
||||
#else /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
|
|
@ -96,154 +96,154 @@
|
|||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not necessary for to use this port. They are defined so the common demo files
|
||||
* (which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Generic helper function. */
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
#define portNOP()
|
||||
|
||||
#define portINLINE __inline
|
||||
#define portINLINE __inline
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n"\
|
||||
" msr basepri, %0 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n" \
|
||||
" msr basepri, %0 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n"\
|
||||
" mov %1, %2 \n"\
|
||||
" msr basepri, %1 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
|
|||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
|
|
@ -71,13 +71,13 @@ typedef unsigned long UBaseType_t;
|
|||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#error "configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width."
|
||||
#endif
|
||||
|
||||
/* Errata 837070 workaround must be enabled on Cortex-M7 r0p0
|
||||
* and r0p1 cores. */
|
||||
#ifndef configENABLE_ERRATA_837070_WORKAROUND
|
||||
#define configENABLE_ERRATA_837070_WORKAROUND 0
|
||||
#define configENABLE_ERRATA_837070_WORKAROUND 0
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ typedef struct MPU_REGION_SETTINGS
|
|||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
||||
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#error "configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2."
|
||||
#endif
|
||||
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
|
|
@ -221,11 +221,11 @@ typedef struct MPU_REGION_SETTINGS
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
#define MAX_CONTEXT_SIZE 52
|
||||
#define MAX_CONTEXT_SIZE 52
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -247,16 +247,16 @@ typedef struct MPU_SETTINGS
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* SVC numbers for various services. */
|
||||
#define portSVC_START_SCHEDULER 0
|
||||
#define portSVC_YIELD 1
|
||||
#define portSVC_RAISE_PRIVILEGE 2
|
||||
#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_EXIT 5
|
||||
#define portSVC_START_SCHEDULER 0
|
||||
#define portSVC_YIELD 1
|
||||
#define portSVC_RAISE_PRIVILEGE 2
|
||||
#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */
|
||||
#define portSVC_SYSTEM_CALL_EXIT 5
|
||||
|
||||
/* Scheduler utilities. */
|
||||
|
||||
#define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" )
|
||||
#define portYIELD() __asm volatile ( " SVC %0 \n" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||
#define portYIELD_WITHIN_API() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
|
|
@ -270,8 +270,10 @@ typedef struct MPU_SETTINGS
|
|||
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
||||
while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
|
|
@ -312,7 +314,7 @@ extern void vPortExitCritical( void );
|
|||
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
|
|
@ -371,7 +373,7 @@ extern BaseType_t xPortIsTaskPrivileged( void );
|
|||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
|
|
@ -404,13 +406,13 @@ portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
|||
(
|
||||
" mov %0, %1 \n"
|
||||
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
|
||||
" cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
" cpsid i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
#endif
|
||||
" msr basepri, %0 \n"
|
||||
" isb \n"
|
||||
" dsb \n"
|
||||
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
|
||||
" cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
" cpsie i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
#endif
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
|
@ -427,13 +429,13 @@ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
|||
" mrs %0, basepri \n"
|
||||
" mov %1, %2 \n"
|
||||
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
|
||||
" cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
" cpsid i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
#endif
|
||||
" msr basepri, %1 \n"
|
||||
" isb \n"
|
||||
" dsb \n"
|
||||
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
|
||||
" cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
" cpsie i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
|
||||
#endif
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
|
@ -448,7 +450,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
|||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||
" msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -456,7 +458,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
|||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html"
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. www.FreeRTOS.org/FreeRTOS-V10.3.x.html"
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,116 +42,116 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -162,12 +162,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -181,10 +181,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -196,10 +196,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -211,15 +211,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -235,12 +235,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -263,320 +263,320 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n"/* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||
" mov lr, r3 \n"/* LR = r3. */
|
||||
" lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n"/* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n"/* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n"/* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -587,8 +587,8 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -600,12 +600,12 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||
" it ne \n"
|
||||
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M55"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M55"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -65,8 +65,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
|
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* Seal the created secure process stack. */
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
|
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Ensure to never return 0 as a valid context handle. */
|
||||
|
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||
|
||||
/* Check if adding a and b will result in overflow. */
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
|
||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||
|
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
|||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
|||
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||
|
||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||
* that we can enable/disable lazy stacking in port.c file. */
|
||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,111 +42,111 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n"/* r1 = 2. */
|
||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -157,12 +157,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -176,10 +176,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -191,10 +191,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -206,15 +206,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -230,12 +230,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -247,10 +247,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -258,246 +258,246 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||
" mrs r2, psp \n" /* r2 = PSP. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
" msr control, r4 \n"
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M55"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M55"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -65,8 +65,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
32
portable/GCC/ARM_CM7/r0p1/port.c
Executable file → Normal file
32
portable/GCC/ARM_CM7/r0p1/port.c
Executable file → Normal file
|
|
@ -339,22 +339,22 @@ BaseType_t xPortStartScheduler( void )
|
|||
if( ulImplementedPrioBits == 8 )
|
||||
{
|
||||
/* When the hardware implements 8 priority bits, there is no way for
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||
* a result, the least significant bit is always used for sub-priority
|
||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||
*
|
||||
* This may cause some confusion in some cases - for example, if
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||
* priority interrupts will be masked in Critical Sections as those
|
||||
* are at the same preemption priority. This may appear confusing as
|
||||
* 4 is higher (numerically lower) priority than
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||
*
|
||||
* The following assert ensures that the sub-priority bit in the
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||
* confusion. */
|
||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
||||
ulMaxPRIGROUPValue = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -47,42 +47,42 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
|
|
@ -93,158 +93,158 @@
|
|||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not necessary for to use this port. They are defined so the common demo files
|
||||
* (which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Generic helper function. */
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
#define portNOP()
|
||||
|
||||
#define portINLINE __inline
|
||||
#define portINLINE __inline
|
||||
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||
#endif
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n"\
|
||||
" cpsid i \n"\
|
||||
" msr basepri, %0 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
" cpsie i \n"\
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n" \
|
||||
" cpsid i \n" \
|
||||
" msr basepri, %0 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
" cpsie i \n" \
|
||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||
{
|
||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n"\
|
||||
" mov %1, %2 \n"\
|
||||
" cpsid i \n"\
|
||||
" msr basepri, %1 \n"\
|
||||
" isb \n"\
|
||||
" dsb \n"\
|
||||
" cpsie i \n"\
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" cpsid i \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
" cpsie i \n" \
|
||||
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -42,116 +42,116 @@
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" program_mpu_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context_first_task: \n"
|
||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" \n"
|
||||
" restore_general_regs_first_task: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
" \n"
|
||||
" restore_context_done_first_task: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst2: .word xSecureContext \n"
|
||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
" xRNRConst2: .word 0xe000ed98 \n"
|
||||
" xRBARConst2: .word 0xe000ed9c \n"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||
" isb \n"
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -162,12 +162,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n"/* Return. */
|
||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
|
|
@ -181,10 +181,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -196,10 +196,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||
" msr control, r0 \n"/* CONTROL = r0. */
|
||||
" bx lr \n"/* Return to the caller. */
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -211,15 +211,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n"/* Globally enable interrupts. */
|
||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n"/* System call to start the first task. */
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
|
|
@ -235,12 +235,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" bx lr \n"/* Return. */
|
||||
" bx lr \n" /* Return. */
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -263,320 +263,320 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" save_s_context: \n"
|
||||
" push {r0-r2, lr} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r2, lr} \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" save_general_regs: \n"
|
||||
" mrs r3, psp \n"
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
" \n"
|
||||
" save_special_regs: \n"
|
||||
" mrs r3, psp \n" /* r3 = PSP. */
|
||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" program_mpu: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||
" \n"
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r1, [r2] \n" /* Program MAIR0. */
|
||||
" \n"
|
||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" \n"
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" \n"
|
||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||
" movs r3, #8 \n" /* r3 = 8. */
|
||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
" movs r3, #12 \n" /* r3 = 12. */
|
||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||
" \n"
|
||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||
" str r2, [r1] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
" \n"
|
||||
" restore_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||
" msr psp, r3 \n"
|
||||
" msr psplim, r4 \n"
|
||||
" msr control, r5 \n"
|
||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||
" \n"
|
||||
" restore_s_context: \n"
|
||||
" push {r1-r3, lr} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r1-r3, lr} \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||
" \n"
|
||||
" restore_general_regs: \n"
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"
|
||||
" ittt eq \n"
|
||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" restore_context_done: \n"
|
||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
" xSecureContextConst: .word xSecureContext \n"
|
||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||
" xRNRConst: .word 0xe000ed98 \n"
|
||||
" xRBARConst: .word 0xe000ed9c \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#else /* configENABLE_MPU */
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n"/* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||
" mov lr, r3 \n"/* LR = r3. */
|
||||
" lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n"/* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n"/* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n"/* r0 = 0. */
|
||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n"/* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n"/* LR = r4. */
|
||||
" lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
|
||||
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
|
||||
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
|
||||
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
" \n"
|
||||
" select_next_task: \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"
|
||||
" mov r0, #0 \n" /* r0 = 0. */
|
||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||
" \n"
|
||||
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||
" push {r2, r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||
" pop {r2, r4} \n"
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
".syntax unified \n"
|
||||
".extern vPortSVCHandler_C \n"
|
||||
".extern vSystemCallEnter \n"
|
||||
".extern vSystemCallEnter_1 \n"
|
||||
".extern vSystemCallExit \n"
|
||||
" \n"
|
||||
"tst lr, #4 \n"
|
||||
"ite eq \n"
|
||||
"mrseq r0, msp \n"
|
||||
"mrsne r0, psp \n"
|
||||
" \n"
|
||||
"ldr r1, [r0, #24] \n"
|
||||
"ldrb r2, [r1, #-2] \n"
|
||||
"cmp r2, %0 \n"
|
||||
"beq syscall_enter \n"
|
||||
"cmp r2, %1 \n"
|
||||
"beq syscall_enter_1 \n"
|
||||
"cmp r2, %2 \n"
|
||||
"beq syscall_exit \n"
|
||||
"b vPortSVCHandler_C \n"
|
||||
" \n"
|
||||
"syscall_enter: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter \n"
|
||||
" \n"
|
||||
"syscall_enter_1: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallEnter_1 \n"
|
||||
" \n"
|
||||
"syscall_exit: \n"
|
||||
" mov r1, lr \n"
|
||||
" b vSystemCallExit \n"
|
||||
" \n"
|
||||
: /* No outputs. */
|
||||
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||
: "r0", "r1", "r2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -587,8 +587,8 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
@ -600,12 +600,12 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR
|
|||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||
" it ne \n"
|
||||
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n"/* Return. */
|
||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@
|
|||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M85"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
#define portARCH_NAME "Cortex-M85"
|
||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ARMv8-M common port configurations. */
|
||||
|
|
@ -65,8 +65,8 @@
|
|||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
|||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#else
|
||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||
|
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
|||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||
|
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
/**
|
||||
* @brief System call stack.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
|
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
|
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* Tasks are not created with a secure context. Any task that is going to call
|
||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||
* secure context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
|
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
|
||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
/**
|
||||
* @brief Checks whether or not the calling task is privileged.
|
||||
*
|
||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
#endif /* configENABLE_MPU == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
* based on whether or not Mainline extension is implemented. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#else
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of leading zeros in a 32-bit value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
|
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
return ulReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
/**
|
||||
* @brief Store/clear the ready priorities in a bit map.
|
||||
*/
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
/**
|
||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||
*/
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
* @brief Maximum number of secure contexts.
|
||||
*/
|
||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
|
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte for stack (excluding the space for seal values)
|
||||
* because the hardware decrements the stack pointer before
|
||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* Seal the created secure process stack. */
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
|
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Ensure to never return 0 as a valid context handle. */
|
||||
|
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint32_t ulIPSR, ulSecureContextIndex;
|
||||
|
||||
|
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle )
|
||||
{
|
||||
uint8_t * pucStackLimit;
|
||||
uint32_t ulSecureContextIndex;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
/**
|
||||
* @brief PSP value when no secure context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Invalid context ID.
|
||||
*/
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
|
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
|
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
|||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||
void * pvTaskHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||
|
||||
/* Check if adding a and b will result in overflow. */
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||
|
||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||
|
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
|||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue