summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2008-11-28 15:41:07 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2008-11-28 15:41:07 +0000
commit24d545993ed673ffd75531773e0522432a120358 (patch)
tree90ca72ef32bb3d6a58b947564ade98510afa191e /Source
parenteb53d0bd711e29e0c54c52d98ebde24adf050b7d (diff)
downloadfreertos-24d545993ed673ffd75531773e0522432a120358.tar.gz
freertos-24d545993ed673ffd75531773e0522432a120358.tar.bz2
freertos-24d545993ed673ffd75531773e0522432a120358.tar.xz
New demo being added - work in progress.
git-svn-id: https://freertos.svn.sourceforge.net/svnroot/freertos/trunk@587 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'Source')
-rw-r--r--Source/portable/IAR/AtmelSAM9XE/ISR_Support.h78
-rw-r--r--Source/portable/IAR/AtmelSAM9XE/port.c280
-rw-r--r--Source/portable/IAR/AtmelSAM9XE/portasm.s7958
-rw-r--r--Source/portable/IAR/AtmelSAM9XE/portmacro.h131
4 files changed, 547 insertions, 0 deletions
diff --git a/Source/portable/IAR/AtmelSAM9XE/ISR_Support.h b/Source/portable/IAR/AtmelSAM9XE/ISR_Support.h
new file mode 100644
index 00000000..4a32f397
--- /dev/null
+++ b/Source/portable/IAR/AtmelSAM9XE/ISR_Support.h
@@ -0,0 +1,78 @@
+ EXTERN pxCurrentTCB
+ EXTERN ulCriticalNesting
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Context save and restore macro definitions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+portSAVE_CONTEXT MACRO
+
+ ; Push R0 as we are going to use the register.
+ STMDB SP!, {R0}
+
+ ; Set R0 to point to the task stack pointer.
+ STMDB SP, {SP}^
+ NOP
+ SUB SP, SP, #4
+ LDMIA SP!, {R0}
+
+ ; Push the return address onto the stack.
+ STMDB R0!, {LR}
+
+ ; Now we have saved LR we can use it instead of R0.
+ MOV LR, R0
+
+ ; Pop R0 so we can save it onto the system mode stack.
+ LDMIA SP!, {R0}
+
+ ; Push all the system mode registers onto the task stack.
+ STMDB LR, {R0-LR}^
+ NOP
+ SUB LR, LR, #60
+
+ ; Push the SPSR onto the task stack.
+ MRS R0, SPSR
+ STMDB LR!, {R0}
+
+ LDR R0, =ulCriticalNesting
+ LDR R0, [R0]
+ STMDB LR!, {R0}
+
+ ; Store the new top of stack for the task.
+ LDR R1, =pxCurrentTCB
+ LDR R0, [R1]
+ STR LR, [R0]
+
+ ENDM
+
+
+portRESTORE_CONTEXT MACRO
+
+ ; Set the LR to the task stack.
+ LDR R1, =pxCurrentTCB
+ LDR R0, [R1]
+ LDR LR, [R0]
+
+ ; The critical nesting depth is the first item on the stack.
+ ; Load it into the ulCriticalNesting variable.
+ LDR R0, =ulCriticalNesting
+ LDMFD LR!, {R1}
+ STR R1, [R0]
+
+ ; Get the SPSR from the stack.
+ LDMFD LR!, {R0}
+ MSR SPSR_cxsf, R0
+
+ ; Restore all system mode registers for the task.
+ LDMFD LR, {R0-R14}^
+ NOP
+
+ ; Restore the return address.
+ LDR LR, [LR, #+60]
+
+ ; And return - correcting the offset in the LR to obtain the
+ ; correct address.
+ SUBS PC, LR, #4
+
+ ENDM
+
diff --git a/Source/portable/IAR/AtmelSAM9XE/port.c b/Source/portable/IAR/AtmelSAM9XE/port.c
new file mode 100644
index 00000000..0004c97b
--- /dev/null
+++ b/Source/portable/IAR/AtmelSAM9XE/port.c
@@ -0,0 +1,280 @@
+/*
+ FreeRTOS.org V5.1.1 - Copyright (C) 2003-2008 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org 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
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ ***************************************************************************
+ * *
+ * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *
+ * and even write all or part of your application on your behalf. *
+ * See http://www.OpenRTOS.com for details of the services we provide to *
+ * expedite your project. *
+ * *
+ ***************************************************************************
+ ***************************************************************************
+
+ Please ensure to read the configuration and relevant port sections of the
+ online documentation.
+
+ 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.
+*/
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the Atmel ARM7 port.
+ *----------------------------------------------------------*/
+
+
+/* Standard includes. */
+#include <stdlib.h>
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Hardware includes. */
+#include <board.h>
+#include <pio/pio.h>
+#include <pio/pio_it.h>
+#include <pit/pit.h>
+#include <aic/aic.h>
+#include <tc/tc.h>
+#include <utility/led.h>
+#include <utility/trace.h>
+
+/*-----------------------------------------------------------*/
+
+/* Constants required to setup the initial stack. */
+#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
+
+/* Constants required to setup the PIT. */
+#define port1MHz_IN_Hz ( 1000000ul )
+#define port1SECOND_IN_uS ( 1000000ul )
+
+/* Constants required to handle critical sections. */
+#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
+
+
+#define portINT_LEVEL_SENSITIVE 0
+#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
+#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
+/*-----------------------------------------------------------*/
+
+/* Setup the PIT to generate the tick interrupts. */
+static void prvSetupTimerInterrupt( void );
+
+/* ulCriticalNesting will get set to zero when the first task starts. It
+cannot be initialised to 0 as this will cause interrupts to be enabled
+during the kernel initialisation process. */
+unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Initialise the stack of a task to look exactly as if a call to
+ * portSAVE_CONTEXT had been called.
+ *
+ * See header file for description.
+ */
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
+{
+portSTACK_TYPE *pxOriginalTOS;
+
+ pxOriginalTOS = pxTopOfStack;
+
+ /* Setup the initial stack of the task. The stack is set exactly as
+ 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. */
+ *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
+ pxTopOfStack--;
+
+ *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
+ pxTopOfStack--;
+ *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
+ 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--;
+
+ /* When the task starts is will expect to find the function parameter in
+ R0. */
+ *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
+ pxTopOfStack--;
+
+ /* The status register is set for system mode, with interrupts enabled. */
+ *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
+ pxTopOfStack--;
+
+ /* 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_NESTING;
+
+ return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xPortStartScheduler( void )
+{
+extern void vPortStartFirstTask( void );
+
+ /* Start the timer that generates the tick ISR. Interrupts are disabled
+ here already. */
+ prvSetupTimerInterrupt();
+
+ /* Start the first task. */
+ vPortStartFirstTask();
+
+ /* Should not get here! */
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler( void )
+{
+ /* It is unlikely that the ARM port will require this function as there
+ is nothing to return to. */
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_PREEMPTION == 0
+
+ /* The cooperative scheduler requires a normal IRQ service routine to
+ simply increment the system tick. */
+ static __arm __irq void vPortNonPreemptiveTick( void );
+ static __arm __irq void vPortNonPreemptiveTick( void )
+ {
+ unsigned portLONG 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. */
+ vTaskIncrementTick();
+
+ /* Clear the PIT interrupt. */
+ ulDummy = AT91C_BASE_PITC->PITC_PIVR;
+
+ /* End the interrupt in the AIC. */
+ AT91C_BASE_AIC->AIC_EOICR = ulDummy;
+ }
+
+#else
+
+ /* Currently the IAR port requires the preemptive tick function to be
+ defined in an asm file. */
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+static void prvSetupTimerInterrupt( void )
+{
+const unsigned portLONG ulPeriodIn_uS = ( 1 / configTICK_RATE_HZ ) * port1SECOND_IN_uS;
+
+ /* Setup the PIT for the required frequency. */
+ PIT_Init( ulPeriodIn_uS, BOARD_MCK / port1MHz_IN_Hz );
+
+ /* Setup the PIT interrupt. */
+ AIC_DisableIT( AT91C_ID_SYS );
+
+ #if configUSE_PREEMPTION == 0
+ AIC_ConfigureIT( AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, vPortNonPreemptiveTick );
+ #else
+ extern void ( vPortPreemptiveTick )( void );
+ AIC_ConfigureIT( AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, vPortPreemptiveTick );
+ #endif
+
+ AIC_EnableIT( AT91C_ID_SYS );
+ PIT_EnableIT();
+
+ /* Enable the PIT itself. */
+ PIT_Enable();
+}
+/*-----------------------------------------------------------*/
+
+void vPortEnterCritical( void )
+{
+ /* Disable interrupts first! */
+ __disable_irq();
+
+ /* 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 we are leaving a critical section. */
+ ulCriticalNesting--;
+
+ /* If the nesting level has reached zero then interrupts should be
+ re-enabled. */
+ if( ulCriticalNesting == portNO_CRITICAL_NESTING )
+ {
+ __enable_irq();
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+
+
+
+
+
diff --git a/Source/portable/IAR/AtmelSAM9XE/portasm.s79 b/Source/portable/IAR/AtmelSAM9XE/portasm.s79
new file mode 100644
index 00000000..da118fb5
--- /dev/null
+++ b/Source/portable/IAR/AtmelSAM9XE/portasm.s79
@@ -0,0 +1,58 @@
+ RSEG ICODE:CODE
+ CODE32
+
+ EXTERN vTaskSwitchContext
+ EXTERN vTaskIncrementTick
+
+ PUBLIC vPortYieldProcessor
+ PUBLIC vPortPreemptiveTick
+ PUBLIC vPortStartFirstTask
+
+#include "ISR_Support.h"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Starting the first task is just a matter of restoring the context that
+; was created by pxPortInitialiseStack().
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+vPortStartFirstTask:
+ portRESTORE_CONTEXT
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Manual context switch function. This is the SWI hander.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+vPortYieldProcessor:
+ ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
+ ; as if the context was saved during and IRQ
+ ; handler.
+
+ portSAVE_CONTEXT ; Save the context of the current task...
+ LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
+ mov lr, pc
+ BX R0
+ portRESTORE_CONTEXT ; Restore the context of the selected task.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Preemptive context switch function. This will only ever get installed if
+; portUSE_PREEMPTION is set to 1 in portmacro.h.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+vPortPreemptiveTick:
+ portSAVE_CONTEXT ; Save the context of the current task.
+
+ LDR R0, =vTaskIncrementTick ; Increment the tick count - this may wake a task.
+ mov lr, pc
+ BX R0
+ LDR R0, =vTaskSwitchContext ; Select the next task to execute.
+ mov lr, pc
+ BX R0
+#if 0
+ LDR R14, =AT91C_BASE_PITC ; Clear the PIT interrupt
+ LDR R0, [R14, #PITC_PIVR ]
+
+ LDR R14, =AT91C_BASE_AIC ; Mark the End of Interrupt on the AIC
+ STR R14, [R14, #AIC_EOICR]
+#endif
+ portRESTORE_CONTEXT ; Restore the context of the selected task.
+
+
+ END
+
diff --git a/Source/portable/IAR/AtmelSAM9XE/portmacro.h b/Source/portable/IAR/AtmelSAM9XE/portmacro.h
new file mode 100644
index 00000000..089ad8e6
--- /dev/null
+++ b/Source/portable/IAR/AtmelSAM9XE/portmacro.h
@@ -0,0 +1,131 @@
+/*
+ FreeRTOS.org V5.1.1 - Copyright (C) 2003-2008 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org 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
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ ***************************************************************************
+ * *
+ * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *
+ * and even write all or part of your application on your behalf. *
+ * See http://www.OpenRTOS.com for details of the services we provide to *
+ * expedite your project. *
+ * *
+ ***************************************************************************
+ ***************************************************************************
+
+ Please ensure to read the configuration and relevant port sections of the
+ online documentation.
+
+ 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.
+*/
+
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#include <intrinsics.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 portLONG
+#define portBASE_TYPE portLONG
+
+#if( configUSE_16_BIT_TICKS == 1 )
+ typedef unsigned portSHORT portTickType;
+ #define portMAX_DELAY ( portTickType ) 0xffff
+#else
+ typedef unsigned portLONG 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
+#define portYIELD() asm ( "SWI 0" )
+#define portNOP() asm ( "NOP" )
+/*-----------------------------------------------------------*/
+
+/* Critical section handling. */
+__arm __interwork void vPortDisableInterruptsFromThumb( void );
+__arm __interwork void vPortEnableInterruptsFromThumb( void );
+__arm __interwork void vPortEnterCritical( void );
+__arm __interwork void vPortExitCritical( void );
+
+#define portDISABLE_INTERRUPTS() __disable_irq()
+#define portENABLE_INTERRUPTS() __enable_irq()
+#define portENTER_CRITICAL() vPortEnterCritical()
+#define portEXIT_CRITICAL() vPortExitCritical()
+/*-----------------------------------------------------------*/
+
+/* Task utilities. */
+#define portEND_SWITCHING_ISR( xSwitchRequired ) \
+{ \
+extern void vTaskSwitchContext( void ); \
+ \
+ if( xSwitchRequired ) \
+ { \
+ vTaskSwitchContext(); \
+ } \
+}
+/*-----------------------------------------------------------*/
+
+
+/* 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 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTMACRO_H */
+
+