From: richardbarry Date: Thu, 20 Jun 2013 12:47:21 +0000 (+0000) Subject: RVDS ARM Cortex-A port layer. X-Git-Tag: V7.5.0~56 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e6b9212bd8edac00ad9caf80837c29963d4e2513;p=freertos RVDS ARM Cortex-A port layer. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1934 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c new file mode 100644 index 000000000..fbcb52759 --- /dev/null +++ b/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c @@ -0,0 +1,434 @@ +/* + FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not it can be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +/* Standard includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS + #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://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 http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#ifndef configUNIQUE_INTERRUPT_PRIORITIES + #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#ifndef configSETUP_TICK_INTERRUPT + #error configSETUP_TICK_INTERRUPT() must be defined. See http://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 http://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 +#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 +#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. + #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 ) +#endif + +/* The number of bits to shift for an interrupt priority is dependent on the +number of bits implemented by the interrupt controller. */ +#if configUNIQUE_INTERRUPT_PRIORITIES == 16 + #define portPRIORITY_SHIFT 4 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 32 + #define portPRIORITY_SHIFT 3 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 64 + #define portPRIORITY_SHIFT 2 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 128 + #define portPRIORITY_SHIFT 1 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 + #define portPRIORITY_SHIFT 0 +#else + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware +#endif + +/* A critical section is exited when the critical section nesting count reaches +this value. */ +#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 ) + +/* In all GICs 255 can be written to the priority mask register to unmask all +(but the lowest) interrupt priority. */ +#define portUNMASK_VALUE ( 0xFF ) + +/* 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 ( ( portSTACK_TYPE ) 0 ) + +/* Interrupt controller access addresses. */ +#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) +#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) +#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) +#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) +#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile unsigned long * ) ( 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 ) + +/* Constants required to setup the initial task context. */ +#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ +#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 ) +#define portINTERRUPT_ENABLE_BIT ( 0x80UL ) +#define portTHUMB_MODE_ADDRESS ( 0x01UL ) + +/* Masks all bits in the APSR other than the mode bits. */ +#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 ) + +/* Macro to unmask all interrupt priorities. */ +#define portCLEAR_INTERRUPT_MASK() \ +{ \ + __disable_irq(); \ + portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ + __asm( "DSB \n" \ + "ISB \n" ); \ + __enable_irq(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Starts the first task executing. This function is necessarily written in + * assembly code so is implemented in portASM.s. + */ +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. */ +volatile unsigned long ulCriticalNesting = 9999UL; + +/* The value to be written to the interrupt controllers priority mask register +to mask interrupts that can use the FreeRTOS API without masking higher priority +interrupts. */ +const unsigned long ulPortAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); + +/* Used to pass constants into the ASM code. The address at which variables are +placed is the constant value so indirect loads in the asm code are not +required. */ +unsigned long ulICCIAR __attribute__( ( at( portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ) ) ); +unsigned long ulICCEOIR __attribute__( ( at( portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ) ) ); +unsigned long ulICCPMR __attribute__( ( at( portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ) ) ); +unsigned long ulAsmAPIPriorityMask __attribute__( ( at( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) ); + +/* 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. */ +unsigned long ulPortTaskHasFPUContext = pdFALSE; + +/* Set to 1 to pend a context switch from an ISR. */ +unsigned long ulPortYieldRequired = pdFALSE; + +/* Counts the interrupt nesting depth. A context switch is only performed if +if the nesting depth is 0. */ +unsigned long ulPortInterruptNesting = 0UL; + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE 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. */ + *pxTopOfStack = NULL; + pxTopOfStack--; + *pxTopOfStack = NULL; + pxTopOfStack--; + *pxTopOfStack = NULL; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR; + + if( ( ( unsigned long ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) + { + /* The task will start in THUMB mode. */ + *pxTopOfStack |= portTHUMB_MODE_BIT; + } + + pxTopOfStack--; + + /* Next the return address, which in this case is the start of the task. */ + *pxTopOfStack = ( portSTACK_TYPE ) pxCode; + pxTopOfStack--; + + /* Next all the registers other than the stack pointer. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */ + pxTopOfStack--; + + /* The task will start with a critical nesting count of 0 as interrupts are + 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. */ + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ +unsigned long ulAPSR; + + /* Only continue if the CPU is not in User mode. The CPU must be in a + Privileged mode for the scheduler to start. */ + __asm( "MRS ulAPSR, APSR" ); + ulAPSR &= portAPSR_MODE_BITS_MASK; + configASSERT( ulAPSR != portAPSR_USER_MODE ); + + if( ulAPSR != portAPSR_USER_MODE ) + { + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + __enable_irq(); + vPortRestoreTaskContext(); + } + + /* Will only get here if xTaskStartScheduler() was called with the CPU in + a non-privileged mode. */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the ARM port will require this function as there + is nothing to return to. */ +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ + 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. */ + ulCriticalNesting++; +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + if( ulCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as the critical section is being + exited. */ + ulCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + priorities must be re-enabled. */ + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) + { + /* Critical nesting has reached zero so all interrupt priorities + should be unmasked. */ + portCLEAR_INTERRUPT_MASK(); + } + } +} +/*-----------------------------------------------------------*/ + +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. */ + __disable_irq(); + portICCPMR_PRIORITY_MASK_REGISTER = ulPortAPIPriorityMask; + __asm( "DSB \n" + "ISB \n" ); + __enable_irq(); + + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + ulPortYieldRequired = pdTRUE; + } + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_MASK(); +} +/*-----------------------------------------------------------*/ + +void vPortTaskUsesFPU( void ) +{ +unsigned long 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). */ + ulPortTaskHasFPUContext = pdTRUE; + + /* Initialise the floating point status register. */ + __asm( "FMXR FPSCR, ulInitialFPSCR" ); +} +/*-----------------------------------------------------------*/ + +void vPortClearInterruptMask( unsigned long ulNewMaskValue ) +{ + if( ulNewMaskValue == pdFALSE ) + { + portCLEAR_INTERRUPT_MASK(); + } +} +/*-----------------------------------------------------------*/ + +unsigned long ulPortSetInterruptMask( void ) +{ +unsigned long ulReturn; + + __disable_irq(); + if( portICCPMR_PRIORITY_MASK_REGISTER == ulPortAPIPriorityMask ) + { + /* Interrupts were already masked. */ + ulReturn = pdTRUE; + } + else + { + ulReturn = pdFALSE; + portICCPMR_PRIORITY_MASK_REGISTER = ulPortAPIPriorityMask; + __asm( "DSB \n" + "ISB \n" ); + } + __enable_irq(); + + return ulReturn; +} + + diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s new file mode 100644 index 000000000..fdaeed0c9 --- /dev/null +++ b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s @@ -0,0 +1,190 @@ +;/* +; FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd. +; +; +; *************************************************************************** +; * * +; * FreeRTOS tutorial books are available in pdf and paperback. * +; * Complete, revised, and edited pdf reference manuals are also * +; * available. * +; * * +; * Purchasing FreeRTOS documentation will not only help you, by * +; * ensuring you get running as quickly as possible and with an * +; * in-depth knowledge of how to use FreeRTOS, it will also help * +; * the FreeRTOS project to continue with its mission of providing * +; * professional grade, cross platform, de facto standard solutions * +; * for microcontrollers - completely free of charge! * +; * * +; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * +; * * +; * Thank you for using FreeRTOS, and thank you for your support! * +; * * +; *************************************************************************** +; +; +; This file is part of the FreeRTOS distribution. +; +; FreeRTOS is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License (version 2) as published by the +; Free Software Foundation AND MODIFIED BY the FreeRTOS exception. +; >>>NOTE<<< The modification to the GPL is included to allow you to +; distribute a combined work that includes FreeRTOS without being obliged to +; provide the source code for proprietary components outside of the FreeRTOS +; kernel. FreeRTOS is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. You should have received a copy of the GNU General Public +; License and the FreeRTOS license exception along with FreeRTOS; if not it +; can be viewed here: http://www.freertos.org/a00114.html and also obtained +; by writing to Richard Barry, contact details for whom are available on the +; FreeRTOS WEB site. +; +; 1 tab == 4 spaces! +; +; http://www.FreeRTOS.org - Documentation, latest information, license and +; contact details. +; +; http://www.SafeRTOS.com - A version that is certified for use in safety +; critical systems. +; +; http://www.OpenRTOS.com - Commercial support, development, porting, +; licensing and training services. +;*/ + + INCLUDE portmacro.inc + + IMPORT vApplicationIRQHandler + IMPORT vTaskSwitchContext + IMPORT ulPortYieldRequired + IMPORT ulPortInterruptNesting + IMPORT vTaskSwitchContext + IMPORT ulICCIAR + IMPORT ulICCEOIR + + EXPORT FreeRTOS_SWI_Handler + EXPORT FreeRTOS_IRQ_Handler + EXPORT vPortRestoreTaskContext + + ARM + AREA PORT_ASM, CODE, READONLY + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; SVC handler is used to start the scheduler and yield a task. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FreeRTOS_SWI_Handler + + PRESERVE8 + + ; Save the context of the current task and select a new task to run. + portSAVE_CONTEXT + LDR R0, =vTaskSwitchContext + BLX R0 + +vPortRestoreTaskContext + portRESTORE_CONTEXT + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PL390 GIC interrupt handler +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FreeRTOS_IRQ_Handler + + ; Return to the interrupted instruction. + SUB lr, lr, #4 + + ; Push the return address and SPSR + PUSH {lr} + MRS lr, SPSR + PUSH {lr} + + ; Change to supervisor mode to allow reentry. + CPS #SVC_MODE + + ; Push used registers. + PUSH {r0-r4, r12} + + ; Increment nesting count. r3 holds the address of ulPortInterruptNesting + ; for future use. r1 holds the original ulPortInterruptNesting value for + ; future use. + LDR r3, =ulPortInterruptNesting + LDR r1, [r3] + ADD r4, r1, #1 + STR r4, [r3] + + ; Read value from the interrupt acknowledge register, which is stored in r0 + ; for future parameter and interrupt clearing use. + LDR r2, =ulICCIAR + LDR r0, [r2] + + ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for + ; future use. + MOV r2, sp + AND r2, r2, #4 + SUB sp, sp, r2 + + ; Call the interrupt handler + PUSH {r0-r3, lr} + BL vApplicationIRQHandler + POP {r0-r3, lr} + ADD sp, sp, r2 + + ; Write the value read from ICCIAR to ICCEOIR + LDR r4, =ulICCEOIR + STR r0, [r4] + + ; Restore the old nesting count + STR r1, [r3] + + ; A context switch is never performed if the nesting count is not 0 + CMP r1, #0 + BNE exit_without_switch + + ; Did the interrupt request a context switch? r1 holds the address of + ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future + ; use. + LDR r1, =ulPortYieldRequired + LDR r0, [r1] + CMP r0, #0 + BNE switch_before_exit + +exit_without_switch + ; No context switch. Restore used registers, LR_irq and SPSR before + ; returning. + POP {r0-r4, r12} + CPS #IRQ_MODE + POP {LR} + MSR SPSR_cxsf, LR + POP {LR} + MOVS PC, LR + +switch_before_exit + ; A context swtich is to be performed. Clear the context switch pending + ; flag. + MOV r0, #0 + STR r0, [r1] + + ; Restore used registers, LR-irq and SPSR before saving the context + ; to the task stack. + POP {r0-r4, r12} + CPS #IRQ_MODE + POP {LR} + MSR SPSR_cxsf, LR + POP {LR} + portSAVE_CONTEXT + + ; Call the function that selects the new task to execute. + ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD + ; instructions, or 8 byte aligned stack allocated data. LR does not need + ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. + BL vTaskSwitchContext + + ; Restore the context of, and branch to, the task selected to execute next. + portRESTORE_CONTEXT + + + END + + + + diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h new file mode 100644 index 000000000..8c177cd07 --- /dev/null +++ b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h @@ -0,0 +1,192 @@ +/* + FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not it can be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE unsigned long +#define portBASE_TYPE portLONG + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned short portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned long portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Hardware specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 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 unsigned long ulPortYieldRequired; \ + \ + if( xSwitchRequired != pdFALSE ) \ + { \ + ulPortYieldRequired = pdTRUE; \ + } \ +} + +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +#define portYIELD() __asm( "SWI 0" ); + + +/*----------------------------------------------------------- + * Critical section control + *----------------------------------------------------------*/ + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern unsigned long ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( unsigned long ulNewMaskValue ); + +/* 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) + +/*-----------------------------------------------------------*/ + +/* 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 ) + +/* Prototype of the FreeRTOS tick handler. This must be installed as the +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. */ +void vPortTaskUsesFPU( void ); +#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() + +#define portLOWEST_INTERRUPT_PRIORITY ( ( ( unsigned long ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) + +/* Architecture specific optimisations. */ +#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 ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( uxReadyPriorities ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +#define portNOP() __nop() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc new file mode 100644 index 000000000..331d6f690 --- /dev/null +++ b/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc @@ -0,0 +1,149 @@ +;/* +; FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd. +; +; +; *************************************************************************** +; * * +; * FreeRTOS tutorial books are available in pdf and paperback. * +; * Complete, revised, and edited pdf reference manuals are also * +; * available. * +; * * +; * Purchasing FreeRTOS documentation will not only help you, by * +; * ensuring you get running as quickly as possible and with an * +; * in-depth knowledge of how to use FreeRTOS, it will also help * +; * the FreeRTOS project to continue with its mission of providing * +; * professional grade, cross platform, de facto standard solutions * +; * for microcontrollers - completely free of charge! * +; * * +; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * +; * * +; * Thank you for using FreeRTOS, and thank you for your support! * +; * * +; *************************************************************************** +; +; +; This file is part of the FreeRTOS distribution. +; +; FreeRTOS is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License (version 2) as published by the +; Free Software Foundation AND MODIFIED BY the FreeRTOS exception. +; >>>NOTE<<< The modification to the GPL is included to allow you to +; distribute a combined work that includes FreeRTOS without being obliged to +; provide the source code for proprietary components outside of the FreeRTOS +; kernel. FreeRTOS is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. You should have received a copy of the GNU General Public +; License and the FreeRTOS license exception along with FreeRTOS; if not it +; can be viewed here: http://www.freertos.org/a00114.html and also obtained +; by writing to Richard Barry, contact details for whom are available on the +; FreeRTOS WEB site. +; +; 1 tab == 4 spaces! +; +; http://www.FreeRTOS.org - Documentation, latest information, license and +; contact details. +; +; http://www.SafeRTOS.com - A version that is certified for use in safety +; critical systems. +; +; http://www.OpenRTOS.com - Commercial support, development, porting, +; licensing and training services. +;*/ + +SYS_MODE EQU 0x1f +SVC_MODE EQU 0x13 +IRQ_MODE EQU 0x12 + + IMPORT ulCriticalNesting + IMPORT pxCurrentTCB + IMPORT ulPortTaskHasFPUContext + IMPORT ulAsmAPIPriorityMask + IMPORT ulICCPMR + + + MACRO + portSAVE_CONTEXT + + ; Save the LR and SPSR onto the system mode stack before switching to + ; system mode to save the remaining system mode registers + SRSDB sp!, #SYS_MODE + CPS #SYS_MODE + PUSH {R0-R12, R14} + + ; Push the critical nesting count + LDR R2, =ulCriticalNesting + LDR R1, [R2] + PUSH {R1} + + ; Does the task have a floating point context that needs saving? If + ; ulPortTaskHasFPUContext is 0 then no. + LDR R2, =ulPortTaskHasFPUContext + LDR R3, [R2] + CMP R3, #0 + + ; Save the floating point context, if any + FMRXNE R1, FPSCR + VPUSHNE {D0-D15} + VPUSHNE {D16-D31} + PUSHNE {R1} + + ; Save ulPortTaskHasFPUContext itself + PUSH {R3} + + ; Save the stack pointer in the TCB + LDR R0, =pxCurrentTCB + LDR R1, [R0] + STR SP, [R1] + + MEND + +; /**********************************************************************/ + + MACRO + portRESTORE_CONTEXT + + ; Switch to system mode + CPS #SYS_MODE + + ; Set the SP to point to the stack of the task being restored. + LDR R0, =pxCurrentTCB + LDR R1, [R0] + LDR SP, [R1] + + ; Is there a floating point context to restore? If the restored + ; ulPortTaskHasFPUContext is zero then no. + LDR R0, =ulPortTaskHasFPUContext + POP {R1} + STR R1, [R0] + CMP R1, #0 + + ; Restore the floating point context, if any + LDMFDNE SP!, {R0} + VPOPNE {D16-D31} + VPOPNE {D0-D15} + VMSRNE FPSCR, R0 + + ; Restore the critical section nesting depth + LDR R0, =ulCriticalNesting + POP {R1} + STR R1, [R0] + + ; Ensure the priority mask is correct for the critical nesting depth + LDR R2, =ulICCPMR + CMP R1, #0 + MOVEQ R4, #255 + LDRNE R4, =ulAsmAPIPriorityMask + STR R4, [r2] + + ; Restore all system mode registers other than the SP (which is already + ; being used) + POP {R0-R12, R14} + + ; Return to the task code, loading CPSR on the way. + RFEIA sp! + + MEND + + END +