From ce68e3d3a153deed0c09ac50286d3ce3c74e02b5 Mon Sep 17 00:00:00 2001 From: RichardBarry Date: Fri, 30 Jan 2009 10:47:35 +0000 Subject: [PATCH] New 78K0R first pass files added. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@653 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/portable/IAR/78K0R/port.c | 253 ++++++++++++++++++++++++ Source/portable/IAR/78K0R/portmacro.h | 165 ++++++++++++++++ Source/portable/IAR/78K0R/portmacro.s26 | 230 +++++++++++++++++++++ 3 files changed, 648 insertions(+) create mode 100644 Source/portable/IAR/78K0R/port.c create mode 100644 Source/portable/IAR/78K0R/portmacro.h create mode 100644 Source/portable/IAR/78K0R/portmacro.s26 diff --git a/Source/portable/IAR/78K0R/port.c b/Source/portable/IAR/78K0R/port.c new file mode 100644 index 000000000..c6de3cd03 --- /dev/null +++ b/Source/portable/IAR/78K0R/port.c @@ -0,0 +1,253 @@ +/* + FreeRTOS.org V5.1.1 - Copyright (C) 2003-2009 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. +*/ + +/* Standard includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#define portINITIAL_CRITICAL_NESTING (( unsigned portSHORT ) 10) + +/* default Initialization of the PSW for the task: + * 1100011000000000 + * ||||||||-------------- Fill byte + * |||||||--------------- Cary Flag cleared + * |||||----------------- In-service priority Flags set to low level + * ||||------------------ Register bank Select 0 Flag cleared + * |||------------------- Auxiliary Cary Flag cleared + * ||-------------------- Register bank Select 1 Flag cleared + * |--------------------- Zero Flag set + * ---------------------- Global Interrupt Flag set + */ +#define portPSW (( portSTACK_TYPE ) 0xC600) + +/* We require the address of the pxCurrentTCB variable, but don't want to know +any details of its type. */ +typedef void tskTCB; +extern volatile tskTCB * volatile pxCurrentTCB; + +/* Most ports implement critical sections by placing the interrupt flags on + * the stack before disabling interrupts. Exiting the critical section is then + * simply a case of popping the flags from the stack. As 78K0 IAR does not use + * a frame pointer this cannot be done as modifying the stack will clobber all + * the stack variables. Instead each task maintains a count of the critical + * section nesting depth. Each time a critical section is entered the count is + * incremented. Each time a critical section is left the count is decremented - + * with interrupts only being re-enabled if the count is zero. + * + * usCriticalNesting will get set to zero when the scheduler starts, but must + * not be initialised to zero as this will cause problems during the startup + * sequence. + */ +volatile unsigned portSHORT usCriticalNesting = portINITIAL_CRITICAL_NESTING; +/*-----------------------------------------------------------*/ + +__interrupt void MD_INTTM05( void ); + +/* + * Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but + * could have alternatively used the watchdog timer or timer 1. + */ +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * Initialise the stack of a task to look exactly as if a call to + * portSAVE_CONTEXT had been called. + * + * See the header file portable.h. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ +unsigned portLONG *pxLocal; + +/* + * The 78K0R/Kx3 automatically pushes the PSW then PC onto the stack before + * executing an ISR. We want the stack to look just as if this has happened + * so place a pointer to the start of the task on the stack first - followed + * by the flags we want the task to use when it starts up. + */ +#if configMEMORY_MODE == 1 + pxTopOfStack--; + pxLocal = (unsigned portLONG*) pxTopOfStack; + *pxLocal = (unsigned portLONG) pvParameters; + pxTopOfStack--; + + /* dummy are on the stack cause there normaly the return adress of the funtion + * is written. Can be a dummy cause the function will never end but only be + * yielded an reentered + */ + *pxTopOfStack = ( portSTACK_TYPE ) 0xcdcd; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xcdcd; + pxTopOfStack--; + pxTopOfStack--; + + /* task function start address */ + pxLocal = (unsigned portLONG*) pxTopOfStack; + *pxLocal = (unsigned portLONG) pxCode; + pxTopOfStack--; + + /* write initial value of the PSW */ + *pxTopOfStack = portPSW; + pxTopOfStack--; + + /* Next general purpose register AX */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x1111; + pxTopOfStack--; + +#else + + pxTopOfStack--; + + /* task function start address */ + pxLocal = (unsigned portLONG*) pxTopOfStack; + *pxLocal = (unsigned portLONG) pxCode; + pxTopOfStack--; + + /* write initial value of the PSW */ + *pxTopOfStack = portPSW; + pxTopOfStack--; + + /* Next general purpose registers AX with the task function parameter start address */ + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; + pxTopOfStack--; + +#endif + + *pxTopOfStack = ( portSTACK_TYPE ) 0x2222; + pxTopOfStack--; + + /* save the CS and ES register */ + *pxTopOfStack = ( portSTACK_TYPE ) 0x0F00; + pxTopOfStack--; + + /* Next the remaining general purpose registers DE and BC */ + *pxTopOfStack = ( portSTACK_TYPE ) 0xDEDE; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xBCBC; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING; + + /* + * Return a pointer to the top of the stack we have generated so this can + * be stored in the task control block for the task. + */ + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Setup the hardware to generate the tick. Interrupts are disabled when + this function is called. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + vPortStart(); + + /* Should not get here as the tasks are now running! */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the 78K0R/Kx3 port will get stopped. If required simply + disable the tick interrupt here. */ +} +/*-----------------------------------------------------------*/ + +/* + * Hardware initialisation to generate the RTOS tick. This uses Channel 5 of + * the Timer Array Unit (TAU). Any other Channel could also be used. + */ +static void prvSetupTimerInterrupt( void ) +{ + /* First the Timer Array Unit has to be enabled */ + TAU0EN = 1; + + /* To configure the Timer Array Unit all Channels have to been stopped */ + TT0 = 0xff; + + /* Interrupt of Timer Array Unit Channel 5 disabled to set Interrupt Priority */ + TMMK05 = 1; + + /* Clear Timer Array Unit Channel 5 Interrupt Flag */ + TMIF05 = 0; + + /* Set Timer Array Unit Channel 5 Interrupt Priority */ + TMPR005 = 0; + TMPR105 = 0; + + /* Set Timer Array Unit Channel 5 Mode as Interval Timer */ + TMR05 = 0x0000; + + /* Set the compare match value according to the tick rate we want. */ + TDR05 = (portTickType) (configCPU_CLOCK_HZ / configTICK_RATE_HZ); + + /* Set Timer Array Unit Channel 5 Output Mode */ + TOM0 &= ~0x0020; + + /* Set Timer Array Unit Channel 5 Output Level */ + TOL0 &= ~0x0020; + + /* Set Timer Array Unit Channel 5 Output Enable */ + TOE0 &= ~0x0020; + + /* Interrupt of Timer Array Unit Channel 5 enabled */ + TMMK05 = 0; + + /* Set Timer Array Unit Channel 5 Start*/ + TS0 |= 0x0020; +} +/*-----------------------------------------------------------*/ + diff --git a/Source/portable/IAR/78K0R/portmacro.h b/Source/portable/IAR/78K0R/portmacro.h new file mode 100644 index 000000000..a311b4aa6 --- /dev/null +++ b/Source/portable/IAR/78K0R/portmacro.h @@ -0,0 +1,165 @@ +/* + FreeRTOS.org V5.1.1 - Copyright (C) 2003-2009 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 + +#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 int +#define portBASE_TYPE int + +#if (configUSE_16_BIT_TICKS==1) + typedef unsigned int portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned long portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Interrupt control macros. */ +#define portDISABLE_INTERRUPTS() __asm ( "DI" ) +#define portENABLE_INTERRUPTS() __asm ( "EI" ) +/*-----------------------------------------------------------*/ + +/* Critical section control macros. */ +#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned portSHORT ) 0 ) + +#define portENTER_CRITICAL() \ +{ \ +extern volatile unsigned portSHORT usCriticalNesting; \ + \ + portDISABLE_INTERRUPTS(); \ + \ + /* Now interrupts are disabled ulCriticalNesting can be accessed */ \ + /* directly. Increment ulCriticalNesting to keep a count of how many */ \ + /* times portENTER_CRITICAL() has been called. */ \ + usCriticalNesting++; \ +} + +#define portEXIT_CRITICAL() \ +{ \ +extern volatile unsigned portSHORT usCriticalNesting; \ + \ + if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ + { \ + /* Decrement the nesting count as we are leaving a critical section. */ \ + usCriticalNesting--; \ + \ + /* If the nesting level has reached zero then interrupts should be */ \ + /* re-enabled. */ \ + if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ + { \ + portENABLE_INTERRUPTS(); \ + } \ + } \ +} +/*-----------------------------------------------------------*/ + +/* Task utilities. */ +extern void vPortYield( void ); +extern void vPortStart( void ); +extern void portSAVE_CONTEXT( void ); +extern void portRESTORE_CONTEXT( void ); +#define portYIELD() vPortYield() +#define portNOP() __asm ( "NOP" ) +/*-----------------------------------------------------------*/ + +/* Hardwware specifics. */ +#define portBYTE_ALIGNMENT 2 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +/*-----------------------------------------------------------*/ + +/* 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 ) + + +static __interrupt void P0_isr (void); + +/* --------------------------------------------------------------------------*/ +/* Option-bytes and security ID */ +/* --------------------------------------------------------------------------*/ +#define OPT_BYTES_SIZE 4 +#define SECU_ID_SIZE 10 +#define WATCHDOG_DISABLED 0x00 +#define LVI_ENABLED 0xFE +#define LVI_DISABLED 0xFF +#define RESERVED_FF 0xFF +#define OCD_DISABLED 0x04 +#define OCD_ENABLED 0x81 +#define OCD_ENABLED_ERASE 0x80 + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/Source/portable/IAR/78K0R/portmacro.s26 b/Source/portable/IAR/78K0R/portmacro.s26 new file mode 100644 index 000000000..eaf88998d --- /dev/null +++ b/Source/portable/IAR/78K0R/portmacro.s26 @@ -0,0 +1,230 @@ +; 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. +; +; *************************************************************************** +; 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. +; *************************************************************************** +; +;------------------------------------------------------------------------------ +; Note: Select the correct include files for the device used by the application. +#include "FreeRTOSConfig.h" +;------------------------------------------------------------------------------ + +#if __CORE__ != __78K0R__ + #error "This file is only for 78K0R Devices" +#endif + +#define CS 0xFFFFC +#define ES 0xFFFFD + +; Functions implemented in this file +;------------------------------------------------------------------------------ + + PUBLIC vPortYield + PUBLIC vPortStart + +; Functions used by scheduler +;------------------------------------------------------------------------------ + EXTERN vTaskSwitchContext + EXTERN vTaskIncrementTick + +; Variables used by scheduler +;------------------------------------------------------------------------------ + EXTERN pxCurrentTCB + EXTERN usCriticalNesting + + +; Tick ISR Prototype +;------------------------------------------------------------------------------ + EXTERN ?CL78K0R_V2_L00 + + PUBWEAK `??MD_INTTM05??INTVEC 68` + PUBLIC MD_INTTM05 + +MD_INTTM05 SYMBOL "MD_INTTM05" +`??MD_INTTM05??INTVEC 68` SYMBOL "??INTVEC 68", MD_INTTM05 + + +;------------------------------------------------------------------------------ +; portSAVE_CONTEXT MACRO +; Saves the context of the remaining general purpose registers, CS and ES +; (only in far memory mode) registers +; the usCriticalNesting Value and the Stack Pointer +; of the active Task onto the task stack +;------------------------------------------------------------------------------ +portSAVE_CONTEXT MACRO + + PUSH HL +#if configMEMORY_MODE == 1 + MOV A, CS ; save CS register + XCH A, X + MOV A, ES ; save ES register + PUSH AX +#else + MOV A, CS ; save CS register + PUSH AX +#endif + PUSH DE ; save the remaining general purpose registers + PUSH BC + MOVW AX, usCriticalNesting ; save the usCriticalNesting value + PUSH AX + MOVW AX, pxCurrentTCB ; save the Stack pointer + MOVW HL, AX + MOVW AX, SP + MOVW [HL], AX + ENDM +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; portRESTORE_CONTEXT MACRO +; Restores the context of the Stack Pointer, usCriticalNesting +; value, general purpose registers and the CS and ES (only in far memory mode) +; of the selected task from the task stack +;------------------------------------------------------------------------------ + +portRESTORE_CONTEXT MACRO + MOVW AX, pxCurrentTCB ; restore the Stack pointer + MOVW HL, AX + MOVW AX, [HL] + MOVW SP, AX + POP AX ; restore usCriticalNesting value + MOVW usCriticalNesting, AX + POP BC ; restore the necessary general purpose registers + POP DE +#if configMEMORY_MODE == 1 + POP AX ; restore the ES register + MOV ES, A + XCH A, X ; restore the CS register + MOV CS, A +#else + POP AX + MOV CS, A ; restore CS register +#endif + POP HL ; restore general purpose register HL + ENDM +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; Port Yield function to check for a Task switch in the cooperative mode +; +; Input: NONE +; +; Call: CALL vPortYield +; +; Output: NONE +; +;------------------------------------------------------------------------------ + RSEG CODE:CODE +vPortYield: + PUSH PSW ; save Task PSW (Program Status Word) + DI ; global disable interrupt + PUSH AX + portSAVE_CONTEXT ; Save the context of the current task. + CALL vTaskSwitchContext ; Call the scheduler. + portRESTORE_CONTEXT ; Restore the context of whichever task the ... + POP AX + EI ; (re-)enable global interrupts + POP PSW ; restore active task PSW + RET ; ... scheduler decided should run. + + +;------------------------------------------------------------------------------ +; Restore the context of the first task that is going to run. +; +; Input: NONE +; +; Call: CALL vPortStart +; +; Output: NONE +; +;------------------------------------------------------------------------------ + RSEG CODE:CODE +vPortStart: + portRESTORE_CONTEXT ; Restore the context of whichever task the ... + POP AX + EI ; enable global interrupts + POP PSW ; restore active task PSW + ret ; ... scheduler decided should run. + +;------------------------------------------------------------------------------ +; Perform the necessary steps of the Tick Count Increment and Task Switch +; depending on the chosen kernel configuration +; +; Input: NONE +; +; Call: ISR +; +; Output: NONE +; +;------------------------------------------------------------------------------ +#if configUSE_PREEMPTION == 1 + +MD_INTTM05: + PUSH AX ; create temporary dummy area on stack + PUSH AX ; save AX Register to stack + MOVW AX, [SP+6] ; get PSW + MOVW [SP+2], AX ; write PSW into dummy area on the stack + + portSAVE_CONTEXT ; Save the context of the current task. + call vTaskIncrementTick ; Call the timer tick function. + call vTaskSwitchContext ; Call the scheduler. + portRESTORE_CONTEXT ; Restore the context of whichever task the ... + ; ... scheduler decided should run. + + MOVW AX, [SP+2] ; get PSW from stack + MOVW [SP+6], AX ; write PSW to expected location for reti + POP AX ; restore AX + MOVW [SP+0], AX ; rewrite dummy stack area to expected value + POP AX + RETI +#else + +MD_INTTM05: + PUSH AX ; save necessary general purpose register... + PUSH HL ; ...used by the ISR + MOVW AX, CS ; save CS register + PUSH AX + CALL vTaskIncrementTick ; Call the timer tick function. + POP AX + MOVW CS, AX ; restore CS register + POP HL ; restore used general purpose registers + POP AX + RETI +#endif + + REQUIRE ?CL78K0R_V2_L00 + COMMON INTVEC:CODE:ROOT(1) ; set ISR location to the Interrupt vector table + ORG 68 +`??MD_INTTM05??INTVEC 68`: + DW MD_INTTM05 + ; set value for the usCriticalNesting + RSEG NEAR_ID:CONST:SORT:NOROOT(1) +`?`: + DW 10 + +;#endif + + END \ No newline at end of file -- 2.39.5