summaryrefslogtreecommitdiff
path: root/Source/portable
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2006-05-27 13:58:02 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2006-05-27 13:58:02 +0000
commitfc273d6a436b767839a66e46709378deb98d0ddb (patch)
tree97a4b5bc9c5f89b24608637a9610adab13497dcd /Source/portable
parentb2199f887ab35dfb5ada26217126283866855164 (diff)
downloadfreertos-fc273d6a436b767839a66e46709378deb98d0ddb.tar.gz
New port files for HCS12 using GCC.
git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@8 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'Source/portable')
-rw-r--r--Source/portable/GCC/HCS12/port.c242
-rw-r--r--Source/portable/GCC/HCS12/portmacro.h239
2 files changed, 481 insertions, 0 deletions
diff --git a/Source/portable/GCC/HCS12/port.c b/Source/portable/GCC/HCS12/port.c
new file mode 100644
index 000000000..a4137cc39
--- /dev/null
+++ b/Source/portable/GCC/HCS12/port.c
@@ -0,0 +1,242 @@
+/*
+ FreeRTOS V3.2.3 - Copyright (C) 2003 - 2005 Richard Barry.
+
+ 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 as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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
+ along with FreeRTOS; 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, 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.
+ ***************************************************************************
+*/
+
+/* GCC/HCS12 port by Jefferson L Smith, 2005 */
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Port includes */
+#include <sys/ports_def.h>
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the HCS12 port.
+ *----------------------------------------------------------*/
+
+
+/*
+ * Configure a timer to generate the RTOS tick at the frequency specified
+ * within FreeRTOSConfig.h.
+ */
+static void prvSetupTimerInterrupt( void );
+
+/* NOTE: Interrupt service routines must be in non-banked memory - as does the
+scheduler startup function. */
+#define ATTR_NEAR __attribute__((near))
+
+/* Manual context switch function. This is the SWI ISR. */
+// __attribute__((interrupt))
+void ATTR_NEAR vPortYield( void );
+
+/* Tick context switch function. This is the timer ISR. */
+// __attribute__((interrupt))
+void ATTR_NEAR vPortTickInterrupt( void );
+
+/* Function in non-banked memory which actually switches to first task. */
+portBASE_TYPE ATTR_NEAR xStartSchedulerNear( void );
+
+/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
+critical section should not be left (i.e. interrupts should not be re-enabled)
+until the nesting depth reaches 0. This variable simply tracks the nesting
+depth. Each task maintains it's own critical nesting depth variable so
+uxCriticalNesting is saved and restored from the task stack during a context
+switch. */
+volatile unsigned portBASE_TYPE uxCriticalNesting = 0x80; // un-initialized
+
+/*-----------------------------------------------------------*/
+
+/*
+ * 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. In this case the stack as
+ expected by the HCS12 RTI instruction. */
+
+
+ /* The address of the task function is placed in the stack byte at a time. */
+ *pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );
+ *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );
+
+ /* Next are all the registers that form part of the task context. */
+
+ /* Y register */
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0xff;
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0xee;
+
+ /* X register */
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0xdd;
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0xcc;
+
+ /* A register contains parameter high byte. */
+ *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );
+
+ /* B register contains parameter low byte. */
+ *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );
+
+ /* CCR: Note that when the task starts interrupts will be enabled since
+ "I" bit of CCR is cleared */
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0x80; // keeps Stop disabled (MCU default)
+
+ /* tmp softregs used by GCC. Values right now don't matter. */
+ __asm("\n\
+ movw _.frame, 2,-%0 \n\
+ movw _.tmp, 2,-%0 \n\
+ movw _.z, 2,-%0 \n\
+ movw _.xy, 2,-%0 \n\
+ ;movw _.d2, 2,-%0 \n\
+ ;movw _.d1, 2,-%0 \n\
+ ": "=A"(pxTopOfStack) : "0"(pxTopOfStack) );
+
+ #ifdef BANKED_MODEL
+ /* The page of the task. */
+ *--pxTopOfStack = 0x30; // can only directly start in PPAGE 0x30
+ #endif
+
+ /* The critical nesting depth is initialised with 0 (meaning not in
+ a critical section). */
+ *--pxTopOfStack = ( portSTACK_TYPE ) 0x00;
+
+
+ return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler( void )
+{
+ /* It is unlikely that the HCS12 port will get stopped. */
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupTimerInterrupt( void )
+{
+ /* Enable hardware RTI timer */
+ /* Ignores configTICK_RATE_HZ */
+ RTICTL = 0x50; // 16 MHz xtal: 976.56 Hz, 1024mS
+ CRGINT |= 0x80; // RTIE
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xPortStartScheduler( void )
+{
+ /* xPortStartScheduler() does not start the scheduler directly because
+ the header file containing the xPortStartScheduler() prototype is part
+ of the common kernel code, and therefore cannot use the CODE_SEG pragma.
+ Instead it simply calls the locally defined xNearStartScheduler() -
+ which does use the CODE_SEG pragma. */
+
+ short register d;
+ __asm ("jmp xStartSchedulerNear ; will never return": "=d"(d));
+ return d;
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xStartSchedulerNear( void )
+{
+ /* Configure the timer that will generate the RTOS tick. Interrupts are
+ disabled when this function is called. */
+ prvSetupTimerInterrupt();
+
+ /* Restore the context of the first task. */
+ portRESTORE_CONTEXT();
+
+ portISR_TAIL();
+
+ /* Should not get here! */
+ return pdFALSE;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Context switch functions. These are interrupt service routines.
+ */
+
+/*
+ * Manual context switch forced by calling portYIELD(). This is the SWI
+ * handler.
+ */
+void vPortYield( void )
+{
+ portISR_HEAD();
+ /* NOTE: This is the trap routine (swi) although not defined as a trap.
+ It will fill the stack the same way as an ISR in order to mix preemtion
+ and cooperative yield. */
+
+ portSAVE_CONTEXT();
+ vTaskSwitchContext();
+ portRESTORE_CONTEXT();
+
+ portISR_TAIL();
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * RTOS tick interrupt service routine. If the cooperative scheduler is
+ * being used then this simply increments the tick count. If the
+ * preemptive scheduler is being used a context switch can occur.
+ */
+void vPortTickInterrupt( void )
+{
+ portISR_HEAD();
+
+ /* Clear tick timer flag */
+ CRGFLG = 0x80;
+
+ #if configUSE_PREEMPTION == 1
+ {
+ /* A context switch might happen so save the context. */
+ portSAVE_CONTEXT();
+
+ /* Increment the tick ... */
+ vTaskIncrementTick();
+
+ /* ... then see if the new tick value has necessitated a
+ context switch. */
+ vTaskSwitchContext();
+
+ /* Restore the context of a task - which may be a different task
+ to that interrupted. */
+ portRESTORE_CONTEXT();
+ }
+ #else
+ {
+ vTaskIncrementTick();
+ }
+ #endif
+
+ portISR_TAIL();
+}
+
diff --git a/Source/portable/GCC/HCS12/portmacro.h b/Source/portable/GCC/HCS12/portmacro.h
new file mode 100644
index 000000000..98131cf14
--- /dev/null
+++ b/Source/portable/GCC/HCS12/portmacro.h
@@ -0,0 +1,239 @@
+/*
+ FreeRTOS V3.2.3 - Copyright (C) 2003 - 2005 Richard Barry.
+
+ 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 as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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
+ along with FreeRTOS; 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, 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.
+ ***************************************************************************
+*/
+
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+/*-----------------------------------------------------------
+ * 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 portCHAR
+#define portBASE_TYPE char
+
+#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 portBYTE_ALIGNMENT 1
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
+#define portYIELD() __asm( "swi" );
+/*-----------------------------------------------------------*/
+
+/* Critical section handling. */
+#define portENABLE_INTERRUPTS() __asm( "cli" )
+#define portDISABLE_INTERRUPTS() __asm( "sei" )
+
+/*
+ * Disable interrupts before incrementing the count of critical section nesting.
+ * The nesting count is maintained so we know when interrupts should be
+ * re-enabled. Once interrupts are disabled the nesting count can be accessed
+ * directly. Each task maintains its own nesting count.
+ */
+#define portENTER_CRITICAL() \
+{ \
+ extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
+ \
+ portDISABLE_INTERRUPTS(); \
+ uxCriticalNesting++; \
+}
+
+/*
+ * Interrupts are disabled so we can access the nesting count directly. If the
+ * nesting is found to be 0 (no nesting) then we are leaving the critical
+ * section and interrupts can be re-enabled.
+ */
+#define portEXIT_CRITICAL() \
+{ \
+ extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
+ \
+ uxCriticalNesting--; \
+ if( uxCriticalNesting == 0 ) \
+ { \
+ portENABLE_INTERRUPTS(); \
+ } \
+}
+/*-----------------------------------------------------------*/
+
+/* Task utilities. */
+
+/*
+ * These macros are very simple as the processor automatically saves and
+ * restores its registers as interrupts are entered and exited. In
+ * addition to the (automatically stacked) registers we also stack the
+ * critical nesting count. Each task maintains its own critical nesting
+ * count as it is legitimate for a task to yield from within a critical
+ * section. If the banked memory model is being used then the PPAGE
+ * register is also stored as part of the tasks context.
+ */
+
+#ifdef BANKED_MODEL
+ /*
+ * Load the stack pointer for the task, then pull the critical nesting
+ * count and PPAGE register from the stack. The remains of the
+ * context are restored by the RTI instruction.
+ */
+ #define portRESTORE_CONTEXT() \
+ { \
+ __asm( " \n\
+ .globl pxCurrentTCB ; void * \n\
+ .globl uxCriticalNesting ; char \n\
+ \n\
+ ldx pxCurrentTCB \n\
+ lds 0,x ; Stack \n\
+ \n\
+ movb 1,sp+,uxCriticalNesting \n\
+ movb 1,sp+,0x30 ; PPAGE \n\
+ " ); \
+ }
+
+ /*
+ * By the time this macro is called the processor has already stacked the
+ * registers. Simply stack the nesting count and PPAGE value, then save
+ * the task stack pointer.
+ */
+ #define portSAVE_CONTEXT() \
+ { \
+ __asm( " \n\
+ .globl pxCurrentTCB ; void * \n\
+ .globl uxCriticalNesting ; char \n\
+ \n\
+ movb 0x30, 1,-sp ; PPAGE \n\
+ movb uxCriticalNesting, 1,-sp \n\
+ \n\
+ ldx pxCurrentTCB \n\
+ sts 0,x ; Stack \n\
+ " ); \
+ }
+#else
+
+ /*
+ * These macros are as per the BANKED versions above, but without saving
+ * and restoring the PPAGE register.
+ */
+
+ #define portRESTORE_CONTEXT() \
+ { \
+ __asm( " \n\
+ .globl pxCurrentTCB ; void * \n\
+ .globl uxCriticalNesting ; char \n\
+ \n\
+ ldx pxCurrentTCB \n\
+ lds 0,x ; Stack \n\
+ \n\
+ movb 1,sp+,uxCriticalNesting \n\
+ " ); \
+ }
+
+ #define portSAVE_CONTEXT() \
+ { \
+ __asm( " \n\
+ .globl pxCurrentTCB ; void * \n\
+ .globl uxCriticalNesting ; char \n\
+ \n\
+ movb uxCriticalNesting, 1,-sp \n\
+ \n\
+ ldx pxCurrentTCB \n\
+ sts 0,x ; Stack \n\
+ " ); \
+ }
+#endif
+
+/*
+ * Utility macros to save/restore correct software registers for GCC. This is
+ * useful when GCC does not generate appropriate ISR head/tail code.
+ */
+#define portISR_HEAD() \
+{ \
+ __asm(" \n\
+ movw _.frame, 2,-sp \n\
+ movw _.tmp, 2,-sp \n\
+ movw _.z, 2,-sp \n\
+ movw _.xy, 2,-sp \n\
+ ;movw _.d2, 2,-sp \n\
+ ;movw _.d1, 2,-sp \n\
+ "); \
+}
+
+#define portISR_TAIL() \
+{ \
+ __asm(" \n\
+ movw 2,sp+, _.xy \n\
+ movw 2,sp+, _.z \n\
+ movw 2,sp+, _.tmp \n\
+ movw 2,sp+, _.frame \n\
+ ;movw 2,sp+, _.d1 \n\
+ ;movw 2,sp+, _.d2 \n\
+ rti \n\
+ "); \
+}
+
+/*
+ * Utility macro to call macros above in correct order in order to perform a
+ * task switch from within a standard ISR. This macro can only be used if
+ * the ISR does not use any local (stack) variables. If the ISR uses stack
+ * variables portYIELD() should be used in it's place.
+ */
+
+#define portTASK_SWITCH_FROM_ISR() \
+ portSAVE_CONTEXT(); \
+ vTaskSwitchContext(); \
+ portRESTORE_CONTEXT();
+
+
+/* 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 )
+
+
+#endif /* PORTMACRO_H */
+