summaryrefslogtreecommitdiff
path: root/Source/portable
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2008-10-23 11:03:25 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2008-10-23 11:03:25 +0000
commit5affb6f050403a8298534cd83e475c5df96d8a4b (patch)
tree93cdcc1c62c5b110943531f3517b6150a2d04935 /Source/portable
parentf6632b69b19b718af5112932ec86fe7fa3d63b3a (diff)
downloadfreertos-5affb6f050403a8298534cd83e475c5df96d8a4b.tar.gz
freertos-5affb6f050403a8298534cd83e475c5df96d8a4b.tar.bz2
freertos-5affb6f050403a8298534cd83e475c5df96d8a4b.tar.xz
First ARM7 port that uses the RVDS compiler.
git-svn-id: https://freertos.svn.sourceforge.net/svnroot/freertos/trunk@511 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'Source/portable')
-rw-r--r--Source/portable/RVDS/ARM7_LPC21xx/port.c310
-rw-r--r--Source/portable/RVDS/ARM7_LPC21xx/portASM.s132
-rw-r--r--Source/portable/RVDS/ARM7_LPC21xx/portmacro.h162
-rw-r--r--Source/portable/RVDS/ARM7_LPC21xx/portmacro.inc113
4 files changed, 717 insertions, 0 deletions
diff --git a/Source/portable/RVDS/ARM7_LPC21xx/port.c b/Source/portable/RVDS/ARM7_LPC21xx/port.c
new file mode 100644
index 00000000..cfaaf1f1
--- /dev/null
+++ b/Source/portable/RVDS/ARM7_LPC21xx/port.c
@@ -0,0 +1,310 @@
+/*
+ FreeRTOS.org V5.0.4 - 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.
+*/
+
+
+/* Standard includes. */
+#include <stdlib.h>
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Constants required to setup the initial 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 VIC for the tick ISR. */
+#define portTIMER_VIC_CHANNEL ( ( unsigned portLONG ) 0x0004 )
+#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned portLONG ) 0x0010 )
+#define portTIMER_VIC_ENABLE ( ( unsigned portLONG ) 0x0020 )
+
+/* Constants required to handle interrupts. */
+#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
+#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
+
+/*-----------------------------------------------------------*/
+
+/* The code generated by the Keil compiler does not maintain separate
+stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
+use the stack as per other ports. Instead a variable is used to keep
+track of the critical section nesting. This variable has to be stored
+as part of the task context and must be initialised to a non zero value. */
+
+#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
+volatile unsigned portLONG ulCriticalNesting = 9999UL;
+
+/*-----------------------------------------------------------*/
+
+/* Setup the timer to generate the tick interrupts. */
+static void prvSetupTimerInterrupt( void );
+
+/*
+ * The scheduler can only be started from ARM mode, so
+ * vPortStartFirstSTask() is defined in portISR.c.
+ */
+extern __asm void vPortStartFirstTask( void );
+
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
+{
+portSTACK_TYPE *pxOriginalTOS;
+
+ /* Setup the initial stack of the task. The stack is set exactly as
+ expected by the portRESTORE_CONTEXT() macro.
+
+ Remember where the top of the (simulated) stack is before we place
+ anything on it. */
+ pxOriginalTOS = pxTopOfStack;
+
+ /* 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--;
+ *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 KEIL_THUMB_INTERWORK
+ {
+ /* We want the task to start in thumb mode. */
+ *pxTopOfStack |= portTHUMB_MODE_BIT;
+ }
+ #endif
+
+ pxTopOfStack--;
+
+ /* The code generated by the Keil compiler does not maintain separate
+ stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
+ use the stack as per other ports. Instead a variable is used to keep
+ track of the critical section nesting. This variable has to be stored
+ as part of the task context and is initially set to zero. */
+ *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
+
+ return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xPortStartScheduler( void )
+{
+ /* Start the timer that generates the tick ISR. */
+ prvSetupTimerInterrupt();
+
+ /* Start the first task. This is done from portISR.c as ARM mode must be
+ used. */
+ 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 this is required - stop the tick ISR then
+ return back to main. */
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_PREEMPTION == 0
+
+ /*
+ * The cooperative scheduler requires a normal IRQ service routine to
+ * simply increment the system tick.
+ */
+ void vNonPreemptiveTick( void ) __irq;
+ void vNonPreemptiveTick( void ) __irq
+ {
+ /* Increment the tick count - this may make a delaying task ready
+ to run - but a context switch is not performed. */
+ vTaskIncrementTick();
+
+ T0IR = portTIMER_MATCH_ISR_BIT; /* Clear the timer event */
+ VICVectAddr = portCLEAR_VIC_INTERRUPT; /* Acknowledge the Interrupt */
+ }
+
+ #else
+
+ /*
+ **************************************************************************
+ * The preemptive scheduler ISR is written in assembler and can be found
+ * in the portASM.s file. This will only get used if portUSE_PREEMPTION
+ * is set to 1 in portmacro.h
+ **************************************************************************
+ */
+
+ void vPreemptiveTick( void );
+
+#endif
+/*-----------------------------------------------------------*/
+
+static void prvSetupTimerInterrupt( void )
+{
+unsigned portLONG ulCompareMatch;
+
+ /* A 1ms tick does not require the use of the timer prescale. This is
+ defaulted to zero but can be used if necessary. */
+ T0PR = portPRESCALE_VALUE;
+
+ /* Calculate the match value required for our wanted tick rate. */
+ ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
+
+ /* Protect against divide by zero. Using an if() statement still results
+ in a warning - hence the #if. */
+ #if portPRESCALE_VALUE != 0
+ {
+ ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
+ }
+ #endif
+
+ T0MR0 = ulCompareMatch;
+
+ /* Generate tick with timer 0 compare match. */
+ T0MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
+
+ /* Setup the VIC for the timer. */
+ VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
+ VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
+
+ /* The ISR installed depends on whether the preemptive or cooperative
+ scheduler is being used. */
+ #if configUSE_PREEMPTION == 1
+ {
+ VICVectAddr0 = ( unsigned portLONG ) vPreemptiveTick;
+ }
+ #else
+ {
+ VICVectAddr0 = ( unsigned portLONG ) vNonPreemptiveTick;
+ }
+ #endif
+
+ VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
+
+ /* Start the timer - interrupts are disabled when this function is called
+ so it is okay to do this here. */
+ T0TCR = portENABLE_TIMER;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEnterCritical( void )
+{
+ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
+ __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 interrupts as per portEXIT_CRITICAL(). */
+ __enable_irq();
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+
diff --git a/Source/portable/RVDS/ARM7_LPC21xx/portASM.s b/Source/portable/RVDS/ARM7_LPC21xx/portASM.s
new file mode 100644
index 00000000..57740324
--- /dev/null
+++ b/Source/portable/RVDS/ARM7_LPC21xx/portASM.s
@@ -0,0 +1,132 @@
+;/*
+; FreeRTOS.org V5.0.4 - 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.
+;*/
+
+ INCLUDE portmacro.inc
+
+ IMPORT vTaskSwitchContext
+ IMPORT vTaskIncrementTick
+
+ EXPORT vPortYieldProcessor
+ EXPORT vPortStartFirstTask
+ EXPORT vPreemptiveTick
+
+
+
+VICVECTADDR EQU 0xFFFFF030
+T0IR EQU 0xE0004000
+T0MATCHBIT EQU 0x00000001
+
+
+ ARM
+ AREA PORT_ASM, CODE, READONLY
+ PRESERVE8
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Starting the first task is done by just restoring the context
+; setup by pxPortInitialiseStack
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+vPortStartFirstTask
+ portRESTORE_CONTEXT
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Interrupt service routine for the SWI interrupt. The vector table is
+; configured in the startup.s file.
+;
+; vPortYieldProcessor() is used to manually force a context switch. The
+; SWI interrupt is generated by a call to taskYIELD() or portYIELD().
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+vPortYieldProcessor
+
+ ; Within an IRQ ISR the link register has an offset from the true return
+ ; address, but an SWI ISR does not. Add the offset manually so the same
+ ; ISR return code can be used in both cases.
+ ADD LR, LR, #4
+
+ ; Perform the context switch.
+ portSAVE_CONTEXT ; Save current task context
+ LDR R0, =vTaskSwitchContext ; Get the address of the context switch function
+ MOV LR, PC ; Store the return address
+ BX R0 ; Call the contedxt switch function
+ portRESTORE_CONTEXT ; restore the context of the selected task
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Interrupt service routine for preemptive scheduler tick timer
+; Only used if portUSE_PREEMPTION is set to 1 in portmacro.h
+;
+; Uses timer 0 of LPC21XX Family
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+vPreemptiveTick
+ portSAVE_CONTEXT ; Save the context of the current task.
+
+ LDR R0, =vTaskIncrementTick ; Increment the tick count.
+ MOV LR, PC ; This may make a delayed task ready
+ BX R0 ; to run.
+
+ LDR R0, =vTaskSwitchContext ; Find the highest priority task that
+ MOV LR, PC ; is ready to run.
+ BX R0
+
+ MOV R0, #T0MATCHBIT ; Clear the timer event
+ LDR R1, =T0IR
+ STR R0, [R1]
+
+ LDR R0, =VICVECTADDR ; Acknowledge the interrupt
+ STR R0,[R0]
+
+ portRESTORE_CONTEXT ; Restore the context of the highest
+ ; priority task that is ready to run.
+ END
+
diff --git a/Source/portable/RVDS/ARM7_LPC21xx/portmacro.h b/Source/portable/RVDS/ARM7_LPC21xx/portmacro.h
new file mode 100644
index 00000000..daa33065
--- /dev/null
+++ b/Source/portable/RVDS/ARM7_LPC21xx/portmacro.h
@@ -0,0 +1,162 @@
+/*
+ FreeRTOS.org V5.0.4 - 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
+
+#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 4
+/*-----------------------------------------------------------*/
+
+/* Task utilities. */
+
+/*-----------------------------------------------------------
+ * ISR entry and exit macros. These are only required if a task switch
+ * is required from an ISR.
+ *----------------------------------------------------------*/
+
+/* If a switch is required then we just need to call */
+/* vTaskSwitchContext() as the context has already been */
+/* saved. */
+
+#define portEXIT_SWITCHING_ISR(SwitchRequired) \
+{ \
+extern void vTaskSwitchContext(void); \
+ \
+ if(SwitchRequired) \
+ { \
+ vTaskSwitchContext(); \
+ } \
+} \
+
+#define portYIELD() __asm{ SVC 0 }
+
+
+/* Critical section management. */
+
+/*
+ ******************************************************************
+ * We don't need to worry about whether we're in ARM or
+ * THUMB mode with the Keil Real View compiler when enabling
+ * or disabling interrupts as the compiler's intrinsic functions
+ * take care of that for us.
+ *******************************************************************
+ */
+#define portDISABLE_INTERRUPTS() __disable_irq()
+#define portENABLE_INTERRUPTS() __enable_irq()
+
+
+/*-----------------------------------------------------------
+ * Critical section control
+ *
+ * The code generated by the Keil compiler does not maintain separate
+ * stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
+ * use the stack as per other ports. Instead a variable is used to keep
+ * track of the critical section nesting. This necessitates the use of a
+ * function in place of the macro.
+ *----------------------------------------------------------*/
+
+extern void vPortEnterCritical( void );
+extern void vPortExitCritical( void );
+
+#define portENTER_CRITICAL() vPortEnterCritical();
+#define portEXIT_CRITICAL() vPortExitCritical();
+/*-----------------------------------------------------------*/
+
+/* Compiler specifics. */
+#define inline
+#define register
+#define portNOP() __asm{ NOP }
+/*-----------------------------------------------------------*/
+
+/* 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 */
+
diff --git a/Source/portable/RVDS/ARM7_LPC21xx/portmacro.inc b/Source/portable/RVDS/ARM7_LPC21xx/portmacro.inc
new file mode 100644
index 00000000..36378e89
--- /dev/null
+++ b/Source/portable/RVDS/ARM7_LPC21xx/portmacro.inc
@@ -0,0 +1,113 @@
+;/*
+; FreeRTOS.org V5.0.4 - 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.
+;*/
+
+ IMPORT ulCriticalNesting ;
+ IMPORT pxCurrentTCB ;
+
+
+ MACRO
+ portRESTORE_CONTEXT
+
+
+ LDR R0, =pxCurrentTCB ; Set the LR to the task stack. The location was...
+ LDR R0, [R0] ; ... stored in pxCurrentTCB
+ LDR LR, [R0]
+
+ LDR R0, =ulCriticalNesting ; The critical nesting depth is the first item on...
+ LDMFD LR!, {R1} ; ...the stack. Load it into the ulCriticalNesting var.
+ STR R1, [R0] ;
+
+ LDMFD LR!, {R0} ; Get the SPSR from the stack.
+ MSR SPSR_cxsf, R0 ;
+
+ LDMFD LR, {R0-R14}^ ; Restore all system mode registers for the task.
+ NOP ;
+
+ LDR LR, [LR, #+60] ; Restore the return address
+
+ ; And return - correcting the offset in the LR to obtain ...
+ SUBS PC, LR, #4 ; ...the correct address.
+
+ MEND
+
+; /**********************************************************************/
+
+ MACRO
+ portSAVE_CONTEXT
+
+
+ STMDB SP!, {R0} ; Store R0 first as we need to use it.
+
+ STMDB SP,{SP}^ ; Set R0 to point to the task stack pointer.
+ NOP ;
+ SUB SP, SP, #4 ;
+ LDMIA SP!,{R0} ;
+
+ STMDB R0!, {LR} ; Push the return address onto the stack.
+ MOV LR, R0 ; Now we have saved LR we can use it instead of R0.
+ LDMIA SP!, {R0} ; Pop R0 so we can save it onto the system mode stack.
+
+ STMDB LR,{R0-LR}^ ; Push all the system mode registers onto the task stack.
+ NOP ;
+ SUB LR, LR, #60 ;
+
+ MRS R0, SPSR ; Push the SPSR onto the task stack.
+ STMDB LR!, {R0} ;
+
+ LDR R0, =ulCriticalNesting ;
+ LDR R0, [R0] ;
+ STMDB LR!, {R0} ;
+
+ LDR R0, =pxCurrentTCB ; Store the new top of stack for the task.
+ LDR R1, [R0] ;
+ STR LR, [R1] ;
+
+ MEND
+
+ END