]> git.sur5r.net Git - freertos/commitdiff
New port files for HCS12 using GCC.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 27 May 2006 13:58:02 +0000 (13:58 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 27 May 2006 13:58:02 +0000 (13:58 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@8 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/GCC/HCS12/port.c [new file with mode: 0644]
Source/portable/GCC/HCS12/portmacro.h [new file with mode: 0644]

diff --git a/Source/portable/GCC/HCS12/port.c b/Source/portable/GCC/HCS12/port.c
new file mode 100644 (file)
index 0000000..a4137cc
--- /dev/null
@@ -0,0 +1,242 @@
+/* \r
+       FreeRTOS V3.2.3 - Copyright (C) 2003 - 2005 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+/* GCC/HCS12 port by Jefferson L Smith, 2005 */\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Port includes */\r
+#include <sys/ports_def.h>\r
+\r
+/*-----------------------------------------------------------\r
+ * Implementation of functions defined in portable.h for the HCS12 port.\r
+ *----------------------------------------------------------*/\r
+\r
+\r
+/*\r
+ * Configure a timer to generate the RTOS tick at the frequency specified \r
+ * within FreeRTOSConfig.h.\r
+ */\r
+static void prvSetupTimerInterrupt( void );\r
+\r
+/* NOTE: Interrupt service routines must be in non-banked memory - as does the\r
+scheduler startup function. */\r
+#define ATTR_NEAR      __attribute__((near))\r
+\r
+/* Manual context switch function.  This is the SWI ISR. */\r
+// __attribute__((interrupt))\r
+void ATTR_NEAR vPortYield( void );\r
+\r
+/* Tick context switch function.  This is the timer ISR. */\r
+// __attribute__((interrupt))\r
+void ATTR_NEAR vPortTickInterrupt( void );\r
+\r
+/* Function in non-banked memory which actually switches to first task. */\r
+portBASE_TYPE ATTR_NEAR xStartSchedulerNear( void );\r
+\r
+/* Calls to portENTER_CRITICAL() can be nested.  When they are nested the \r
+critical section should not be left (i.e. interrupts should not be re-enabled)\r
+until the nesting depth reaches 0.  This variable simply tracks the nesting \r
+depth.  Each task maintains it's own critical nesting depth variable so \r
+uxCriticalNesting is saved and restored from the task stack during a context\r
+switch. */\r
+volatile unsigned portBASE_TYPE uxCriticalNesting = 0x80;  // un-initialized\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* \r
+ * See header file for description. \r
+ */\r
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+{\r
+\r
+\r
+       /* Setup the initial stack of the task.  The stack is set exactly as \r
+       expected by the portRESTORE_CONTEXT() macro.  In this case the stack as\r
+       expected by the HCS12 RTI instruction. */\r
+\r
+\r
+       /* The address of the task function is placed in the stack byte at a time. */\r
+       *pxTopOfStack   = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );\r
+\r
+       /* Next are all the registers that form part of the task context. */\r
+\r
+       /* Y register */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0xff;\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0xee;\r
+\r
+       /* X register */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0xdd;\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0xcc;\r
\r
+       /* A register contains parameter high byte. */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );\r
+\r
+       /* B register contains parameter low byte. */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );\r
+\r
+       /* CCR: Note that when the task starts interrupts will be enabled since\r
+       "I" bit of CCR is cleared */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0x80;              // keeps Stop disabled (MCU default)\r
+       \r
+       /* tmp softregs used by GCC. Values right now don't     matter. */\r
+       __asm("\n\\r
+               movw _.frame, 2,-%0                                                     \n\\r
+               movw _.tmp, 2,-%0                                                       \n\\r
+               movw _.z, 2,-%0                                                         \n\\r
+               movw _.xy, 2,-%0                                                        \n\\r
+               ;movw _.d2, 2,-%0                                                       \n\\r
+               ;movw _.d1, 2,-%0                                                       \n\\r
+       ": "=A"(pxTopOfStack) : "0"(pxTopOfStack) );\r
+\r
+       #ifdef BANKED_MODEL\r
+               /* The page of the task. */\r
+               *--pxTopOfStack = 0x30;      // can only directly start in PPAGE 0x30\r
+       #endif\r
+       \r
+       /* The critical nesting depth is initialised with 0 (meaning not in\r
+       a critical section). */\r
+       *--pxTopOfStack = ( portSTACK_TYPE ) 0x00;\r
+\r
+\r
+       return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+       /* It is unlikely that the HCS12 port will get stopped. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupTimerInterrupt( void )\r
+{\r
+       /* Enable hardware RTI timer */\r
+       /* Ignores configTICK_RATE_HZ */\r
+       RTICTL = 0x50;                  // 16 MHz xtal: 976.56 Hz, 1024mS \r
+       CRGINT |= 0x80;                 // RTIE\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xPortStartScheduler( void )\r
+{\r
+       /* xPortStartScheduler() does not start the scheduler directly because \r
+       the header file containing the xPortStartScheduler() prototype is part \r
+       of the common kernel code, and therefore cannot use the CODE_SEG pragma. \r
+       Instead it simply calls the locally defined xNearStartScheduler() - \r
+       which does use the CODE_SEG pragma. */\r
+\r
+       short register d;\r
+       __asm ("jmp  xStartSchedulerNear                ; will never return": "=d"(d));\r
+       return d;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xStartSchedulerNear( void )\r
+{\r
+       /* Configure the timer that will generate the RTOS tick.  Interrupts are\r
+       disabled when this function is called. */\r
+       prvSetupTimerInterrupt();\r
+\r
+       /* Restore the context of the first task. */\r
+       portRESTORE_CONTEXT();\r
+\r
+       portISR_TAIL();\r
+\r
+       /* Should not get here! */\r
+       return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Context switch functions.  These are interrupt service routines.\r
+ */\r
+\r
+/*\r
+ * Manual context switch forced by calling portYIELD().  This is the SWI\r
+ * handler.\r
+ */\r
+void vPortYield( void )\r
+{\r
+       portISR_HEAD();\r
+       /* NOTE: This is the trap routine (swi) although not defined as a trap.\r
+          It will fill the stack the same way as an ISR in order to mix preemtion\r
+          and cooperative yield. */\r
+\r
+       portSAVE_CONTEXT();\r
+       vTaskSwitchContext();\r
+       portRESTORE_CONTEXT();\r
+\r
+       portISR_TAIL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * RTOS tick interrupt service routine.  If the cooperative scheduler is \r
+ * being used then this simply increments the tick count.  If the \r
+ * preemptive scheduler is being used a context switch can occur.\r
+ */\r
+void vPortTickInterrupt( void )\r
+{\r
+       portISR_HEAD();\r
+\r
+       /* Clear tick timer flag */\r
+       CRGFLG = 0x80;\r
+\r
+       #if configUSE_PREEMPTION == 1\r
+       {\r
+               /* A context switch might happen so save the context. */\r
+               portSAVE_CONTEXT();\r
+\r
+               /* Increment the tick ... */\r
+               vTaskIncrementTick();\r
+\r
+               /* ... then see if the new tick value has necessitated a\r
+               context switch. */\r
+               vTaskSwitchContext();\r
+\r
+               /* Restore the context of a task - which may be a different task\r
+               to that interrupted. */\r
+               portRESTORE_CONTEXT();\r
+       }\r
+       #else\r
+       {\r
+               vTaskIncrementTick();\r
+       }\r
+       #endif\r
+\r
+       portISR_TAIL();\r
+}\r
+\r
diff --git a/Source/portable/GCC/HCS12/portmacro.h b/Source/portable/GCC/HCS12/portmacro.h
new file mode 100644 (file)
index 0000000..98131cf
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+       FreeRTOS V3.2.3 - Copyright (C) 2003 - 2005 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+\r
+#ifndef PORTMACRO_H\r
+#define PORTMACRO_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Port specific definitions.  \r
+ *\r
+ * The settings in this file configure FreeRTOS correctly for the\r
+ * given hardware and compiler.\r
+ *\r
+ * These settings should not be altered.\r
+ *-----------------------------------------------------------\r
+ */\r
+\r
+/* Type definitions. */\r
+#define portCHAR               char\r
+#define portFLOAT              float\r
+#define portDOUBLE             double\r
+#define portLONG               long\r
+#define portSHORT              short\r
+#define portSTACK_TYPE unsigned portCHAR\r
+#define portBASE_TYPE  char\r
+\r
+#if( configUSE_16_BIT_TICKS == 1 )\r
+       typedef unsigned portSHORT portTickType;\r
+       #define portMAX_DELAY ( portTickType ) 0xffff\r
+#else\r
+       typedef unsigned portLONG portTickType;\r
+       #define portMAX_DELAY ( portTickType ) 0xffffffff\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Hardware specifics. */\r
+#define portBYTE_ALIGNMENT                     1\r
+#define portSTACK_GROWTH                       ( -1 )\r
+#define portTICK_RATE_MS                       ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
+#define portYIELD()                                    __asm( "swi" );\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Critical section handling. */\r
+#define portENABLE_INTERRUPTS()                                __asm( "cli" )  \r
+#define portDISABLE_INTERRUPTS()                       __asm( "sei" )\r
+\r
+/*\r
+ * Disable interrupts before incrementing the count of critical section nesting.\r
+ * The nesting count is maintained so we know when interrupts should be\r
+ * re-enabled.  Once interrupts are disabled the nesting count can be accessed\r
+ * directly.  Each task maintains its own nesting count.\r
+ */\r
+#define portENTER_CRITICAL()                                                                   \\r
+{                                                                                                                              \\r
+       extern volatile unsigned portBASE_TYPE uxCriticalNesting;       \\r
+                                                                                                                               \\r
+       portDISABLE_INTERRUPTS();                                                                       \\r
+       uxCriticalNesting++;                                                                            \\r
+}\r
+\r
+/*\r
+ * Interrupts are disabled so we can access the nesting count directly.  If the\r
+ * nesting is found to be 0 (no nesting) then we are leaving the critical \r
+ * section and interrupts can be re-enabled.\r
+ */\r
+#define  portEXIT_CRITICAL()                                                                   \\r
+{                                                                                                                              \\r
+       extern volatile unsigned portBASE_TYPE uxCriticalNesting;       \\r
+                                                                                                                               \\r
+       uxCriticalNesting--;                                                                            \\r
+       if( uxCriticalNesting == 0 )                                                            \\r
+       {                                                                                                                       \\r
+               portENABLE_INTERRUPTS();                                                                \\r
+       }                                                                                                                       \\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Task utilities. */\r
+\r
+/* \r
+ * These macros are very simple as the processor automatically saves and \r
+ * restores its registers as interrupts are entered and exited.  In\r
+ * addition to the (automatically stacked) registers we also stack the \r
+ * critical nesting count.  Each task maintains its own critical nesting\r
+ * count as it is legitimate for a task to yield from within a critical\r
+ * section.  If the banked memory model is being used then the PPAGE\r
+ * register is also stored as part of the tasks context.\r
+ */\r
+\r
+#ifdef BANKED_MODEL\r
+       /* \r
+        * Load the stack pointer for the task, then pull the critical nesting\r
+        * count and PPAGE register from the stack.  The remains of the \r
+        * context are restored by the RTI instruction.\r
+        */\r
+       #define portRESTORE_CONTEXT()                                                   \\r
+       {                                                                               \\r
+               __asm( "                                                                \n\\r
+               .globl pxCurrentTCB                     ; void *                        \n\\r
+               .globl uxCriticalNesting                ; char                          \n\\r
+                                                                                       \n\\r
+               ldx  pxCurrentTCB                                                       \n\\r
+               lds  0,x                                ; Stack                         \n\\r
+                                                                                       \n\\r
+               movb 1,sp+,uxCriticalNesting                                            \n\\r
+               movb 1,sp+,0x30                         ; PPAGE                         \n\\r
+               " );                                                                    \\r
+       }\r
+\r
+       /* \r
+        * By the time this macro is called the processor has already stacked the\r
+        * registers.  Simply stack the nesting count and PPAGE value, then save \r
+        * the task stack pointer.\r
+        */\r
+       #define portSAVE_CONTEXT()                                                      \\r
+       {                                                                               \\r
+               __asm( "                                                                \n\\r
+               .globl pxCurrentTCB                     ; void *                        \n\\r
+               .globl uxCriticalNesting                ; char                          \n\\r
+                                                                                       \n\\r
+               movb 0x30, 1,-sp                        ; PPAGE                         \n\\r
+               movb uxCriticalNesting, 1,-sp                                           \n\\r
+                                                                                       \n\\r
+               ldx  pxCurrentTCB                                                       \n\\r
+               sts  0,x                                ; Stack                         \n\\r
+               " );                                                                    \\r
+       }\r
+#else\r
+\r
+       /* \r
+        * These macros are as per the BANKED versions above, but without saving\r
+        * and restoring the PPAGE register.\r
+        */\r
+\r
+       #define portRESTORE_CONTEXT()                                                   \\r
+       {                                                                               \\r
+               __asm( "                                                                \n\\r
+               .globl pxCurrentTCB                     ; void *                        \n\\r
+               .globl uxCriticalNesting                ; char                          \n\\r
+                                                                                       \n\\r
+               ldx  pxCurrentTCB                                                       \n\\r
+               lds  0,x                                ; Stack                         \n\\r
+                                                                                       \n\\r
+               movb 1,sp+,uxCriticalNesting                                            \n\\r
+               " );                                                                    \\r
+       }\r
+\r
+       #define portSAVE_CONTEXT()                                                      \\r
+       {                                                                               \\r
+               __asm( "                                                                \n\\r
+               .globl pxCurrentTCB                     ; void *                        \n\\r
+               .globl uxCriticalNesting                ; char                          \n\\r
+                                                                                       \n\\r
+               movb uxCriticalNesting, 1,-sp                                           \n\\r
+                                                                                       \n\\r
+               ldx  pxCurrentTCB                                                       \n\\r
+               sts  0,x                                ; Stack                         \n\\r
+               " );                                                                    \\r
+       }\r
+#endif\r
+\r
+/*\r
+ * Utility macros to save/restore correct software registers for GCC. This is\r
+ * useful when GCC does not generate appropriate ISR head/tail code.\r
+ */\r
+#define portISR_HEAD()                                                                 \\r
+{                                                                                      \\r
+               __asm("                                                                 \n\\r
+               movw _.frame, 2,-sp                                                     \n\\r
+               movw _.tmp, 2,-sp                                                       \n\\r
+               movw _.z, 2,-sp                                                         \n\\r
+               movw _.xy, 2,-sp                                                        \n\\r
+               ;movw _.d2, 2,-sp                                                       \n\\r
+               ;movw _.d1, 2,-sp                                                       \n\\r
+               ");                                                                     \\r
+}\r
+\r
+#define portISR_TAIL()                                                                 \\r
+{                                                                                      \\r
+               __asm("                                                                 \n\\r
+               movw 2,sp+, _.xy                                                        \n\\r
+               movw 2,sp+, _.z                                                         \n\\r
+               movw 2,sp+, _.tmp                                                       \n\\r
+               movw 2,sp+, _.frame                                                     \n\\r
+               ;movw 2,sp+, _.d1                                                       \n\\r
+               ;movw 2,sp+, _.d2                                                       \n\\r
+               rti                                                                     \n\\r
+               ");                                                                     \\r
+}\r
+\r
+/*\r
+ * Utility macro to call macros above in correct order in order to perform a\r
+ * task switch from within a standard ISR.  This macro can only be used if\r
+ * the ISR does not use any local (stack) variables.  If the ISR uses stack\r
+ * variables portYIELD() should be used in it's place.\r
+ */\r
+\r
+#define portTASK_SWITCH_FROM_ISR()                                                             \\r
+       portSAVE_CONTEXT();                                                                                     \\r
+       vTaskSwitchContext();                                                                           \\r
+       portRESTORE_CONTEXT();\r
+\r
+\r
+/* Task function macros as described on the FreeRTOS.org WEB site. */\r
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+\r
+\r
+#endif /* PORTMACRO_H */\r
+\r