summaryrefslogtreecommitdiff
path: root/openpicc/os/core/ARM7_AT91SAM7S/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/os/core/ARM7_AT91SAM7S/port.c')
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/port.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/port.c b/openpicc/os/core/ARM7_AT91SAM7S/port.c
new file mode 100644
index 0000000..75bb567
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/port.c
@@ -0,0 +1,237 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 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.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+
+/*-----------------------------------------------------------
+ * 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.
+ *----------------------------------------------------------*/
+
+/*
+ Changes from V2.5.2
+
+ + ulCriticalNesting is now saved as part of the task context, as is
+ therefore added to the initial task stack during pxPortInitialiseStack.
+*/
+
+
+/* Standard includes. */
+#include <stdlib.h>
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Processor constants. */
+#include "AT91SAM7.h"
+#include "lib_AT91SAM7.h"
+
+/* Constants required to setup the task context. */
+#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
+#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
+#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
+
+/* Constants required to setup the tick ISR. */
+#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
+#define portPRESCALE_VALUE 0x00
+#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
+#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
+
+/* Constants required to setup the PIT. */
+#define portPIT_CLOCK_DIVISOR ( ( unsigned portLONG ) 16 )
+#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
+
+#define portINT_LEVEL_SENSITIVE 0
+#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
+#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
+/*-----------------------------------------------------------*/
+
+/* Setup the timer to generate the tick interrupts. */
+static void prvSetupTimerInterrupt (void);
+
+/*
+ * The scheduler can only be started from ARM mode, so
+ * vPortISRStartFirstSTask() is defined in portISR.c.
+ */
+extern void vPortISRStartFirstTask (void);
+
+/*-----------------------------------------------------------*/
+
+/*
+ * 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 last thing onto the stack is the status register, which is set for
+ system mode, with interrupts enabled. */
+ *pxTopOfStack = (portSTACK_TYPE) portINITIAL_SPSR;
+
+#ifdef THUMB_INTERWORK
+ {
+ /* We want the task to start in thumb mode. */
+ *pxTopOfStack |= portTHUMB_MODE_BIT;
+ }
+#endif
+
+ 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. */
+ *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
+
+ return pxTopOfStack;
+}
+
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE
+xPortStartScheduler (void)
+{
+ /* Start the timer that generates the tick ISR. Interrupts are disabled
+ here already. */
+ prvSetupTimerInterrupt ();
+
+ /* Start the first task. */
+ vPortISRStartFirstTask ();
+
+ /* 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. */
+}
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Setup the timer 0 to generate the tick interrupts at the required frequency.
+ */
+static void
+prvSetupTimerInterrupt (void)
+{
+ 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. */
+#if configUSE_PREEMPTION == 0
+
+ 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);
+
+#endif
+
+ /* Configure the PIT period. */
+ pxPIT->PITC_PIMR =
+ portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
+
+ /* Enable the interrupt. Global interrupts are disables at this point so
+ this is safe. */
+ AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
+}
+
+/*-----------------------------------------------------------*/
personal git repositories of Harald Welte. Your mileage may vary