From 53b376b6b85a136fa92fcd17ff97256ec8f8d609 Mon Sep 17 00:00:00 2001
From: Richard Barry <ribarry@amazon.com>
Date: Thu, 23 Oct 2008 19:16:29 +0000
Subject: [PATCH] Remove the two separate ports, instead use two demo apps that
 use a conditional compilation to select the method of interrupt management to
 use.

---
 Demo/msp430_CrossWorks/FreeRTOSConfig.h     |  30 ++++++
 Demo/msp430_CrossWorks/RTOSDemo.hzp         |   3 +-
 Demo/msp430_CrossWorks/RTOSDemo.hzs         |  19 ++--
 Demo/msp430_CrossWorks/serial/serial.c      |  35 ++++---
 Demo/msp430_CrossWorks/serial/serialASM.asm | 101 ++++++++++++++++++++
 5 files changed, 159 insertions(+), 29 deletions(-)
 create mode 100644 Demo/msp430_CrossWorks/serial/serialASM.asm

diff --git a/Demo/msp430_CrossWorks/FreeRTOSConfig.h b/Demo/msp430_CrossWorks/FreeRTOSConfig.h
index bf9c7f5aeb..5b30cbc781 100644
--- a/Demo/msp430_CrossWorks/FreeRTOSConfig.h
+++ b/Demo/msp430_CrossWorks/FreeRTOSConfig.h
@@ -52,6 +52,36 @@
 
 #include <msp430x44x.h>
 
+/* 
+Two interrupt examples are provided - 
+
+ + Method 1 does everything in C code.
+ + Method 2 uses an assembly file wrapper.
+
+Code size:
+Method 1 uses assembly macros to save and restore the task context, whereas 
+method 2 uses functions. This means method 1 will be faster, but method 2 will 
+use less code space. 
+
+Simplicity:
+Method 1 is very simplistic, whereas method 2 is more elaborate. This 
+elaboration results in the code space saving, but also requires a slightly more 
+complex procedure to define interrupt service routines. 
+
+Interrupt efficiency:
+Method 1 uses the compiler generated function prologue and epilogue code to save 
+and restore the necessary registers within an interrupt service routine (other 
+than the RTOS tick ISR). Should a context switch be required from within the ISR 
+the entire processor context is saved. This can result in some registers being saved 
+twice - once by the compiler generated code, and then again by the FreeRTOS code.
+Method 2 saves and restores all the processor registers within each interrupt service 
+routine, whether or not a context switch actually occurs. This means no registers 
+ever get saved twice, but imposes an overhead on the occasions that no context switch 
+occurs. 
+*/
+
+#define configINTERRUPT_EXAMPLE_METHOD 1
+
 /*-----------------------------------------------------------
  * Application specific definitions.
  *
diff --git a/Demo/msp430_CrossWorks/RTOSDemo.hzp b/Demo/msp430_CrossWorks/RTOSDemo.hzp
index 94acc5011f..56bb5a73b0 100644
--- a/Demo/msp430_CrossWorks/RTOSDemo.hzp
+++ b/Demo/msp430_CrossWorks/RTOSDemo.hzp
@@ -26,9 +26,10 @@
       <file file_name="ParTest/ParTest.c" Name="ParTest.c" />
       <file file_name="serial/serial.c" Name="serial.c" />
       <file file_name="../Common/Minimal/integer.c" Name="integer.c" />
+      <file file_name="serial/serialASM.asm" Name="serialASM.asm" />
     </folder>
   </project>
   <configuration compiler_optimization_strategy="Minimize size" optimize_code_motion="No" optimize_block_locality="No" optimize_register_allocation="Locals Only" Name="Debug" />
   <configuration c_preprocessor_definitions="NDEBUG" build_debug_information="No" Name="Release" build_optimize_output="Yes" />
-  <configuration c_preprocessor_definitions="ROWLEY_MSP430" c_user_include_directories="$(ProjectDir);$(ProjectDir)/../common/include" linker_printf_width_precision_supported="No" Name="Common" c_system_include_directories="$(StudioDir)/include;$(ProjectDir)/../../source/include;$(ProjectDir)/../../source/portable/Rowley/msp430F449" />
+  <configuration compiler_optimization_strategy="Maximize speed" c_preprocessor_definitions="ROWLEY_MSP430" c_user_include_directories="$(ProjectDir);$(ProjectDir)/../common/include" linker_printf_width_precision_supported="No" Name="Common" c_system_include_directories="$(StudioDir)/include;$(ProjectDir)/../../source/include;$(ProjectDir)/../../source/portable/Rowley/msp430F449" />
 </solution>
diff --git a/Demo/msp430_CrossWorks/RTOSDemo.hzs b/Demo/msp430_CrossWorks/RTOSDemo.hzs
index c4dc21923c..bbeaeac8b4 100644
--- a/Demo/msp430_CrossWorks/RTOSDemo.hzs
+++ b/Demo/msp430_CrossWorks/RTOSDemo.hzs
@@ -1,5 +1,9 @@
 <!DOCTYPE CrossStudio_for_MSP430_Session_File>
 <session>
+ <Autos>
+  <Watches active="0" />
+ </Autos>
+ <Bookmarks/>
  <Breakpoints/>
  <ExecutionCountWindow/>
  <Memory1>
@@ -18,20 +22,18 @@
   <ProjectSessionItem path="RTOSDemo" name="unnamed" />
   <ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
   <ProjectSessionItem path="RTOSDemo;RTOSDemo;Demo Source" name="unnamed" />
-  <ProjectSessionItem path="RTOSDemo;RTOSDemo;Scheduler Source" name="unnamed" />
-  <ProjectSessionItem path="RTOSDemo;RTOSDemo;Startup Code" name="unnamed" />
  </Project>
  <Register1>
-  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" visibleGroups="CPU Registers" decimalDisplays="" binaryDisplays="" />
+  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" openGroups="CPU Registers" visibleGroups="CPU Registers" decimalDisplays="" binaryDisplays="" />
  </Register1>
  <Register2>
-  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
+  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" openGroups="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
  </Register2>
  <Register3>
-  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
+  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" openGroups="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
  </Register3>
  <Register4>
-  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
+  <RegisterWindow unsignedDisplays="" asciiDisplays="" octalDisplays="" openGroups="" visibleGroups="" decimalDisplays="" binaryDisplays="" />
  </Register4>
  <SourceNavigatorWindow/>
  <TraceWindow>
@@ -50,8 +52,7 @@
   <Watches active="0" />
  </Watch4>
  <Files>
-  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" x="0" debugPath="E:\Dev\FreeRTOS\Demo\msp430_CrossStudio\serial\serial.c" y="205" useHTMLEdit="0" path="E:\Dev\FreeRTOS\Demo\msp430_CrossStudio\serial\serial.c" left="0" selected="0" name="unnamed" top="186" />
-  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" x="0" debugPath="E:\Dev\FreeRTOS\Demo\msp430_CrossStudio\main.c" y="134" useHTMLEdit="0" path="E:\Dev\FreeRTOS\Demo\msp430_CrossStudio\main.c" left="0" selected="0" name="unnamed" top="131" />
+  <SessionOpenFile useTextEdit="1" useBinaryEdit="0" x="0" debugPath="c:\e\dev\freertos\workingcopy2\demo\msp430_crossworks\main.c" y="152" useHTMLEdit="0" path="c:\e\dev\freertos\workingcopy2\demo\msp430_crossworks\main.c" left="0" selected="1" name="unnamed" top="146" />
  </Files>
- <MSP430CrossStudioWindow activeProject="RTOSDemo" ignoreExceptions="" autoConnectTarget="/MSP430 Flash Emulation Tool (MSP-FET430PIF)" debugSearchFileMap="" fileDialogInitialDirectory="E:\Dev\FreeRTOS\Demo\Common\Minimal" fileDialogDefaultFilter="*" debugSearchPath="" buildConfiguration="Debug" />
+ <MSP430CrossStudioWindow activeProject="RTOSDemo" moduleClockControl="24791" autoConnectTarget="/TI MSP430 Flash Emulation Tool (MSP-FET430PIF)" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy2\Demo\msp430_CrossWorks\serial" fileDialogDefaultFilter="*" haltTimerA="false" autoConnectCapabilities="1407" haltTimerB="false" holdBasicTimer="false" generalClockControl="46" debugSearchPath="" buildConfiguration="Debug" />
 </session>
diff --git a/Demo/msp430_CrossWorks/serial/serial.c b/Demo/msp430_CrossWorks/serial/serial.c
index 175d591c0a..c22195b275 100644
--- a/Demo/msp430_CrossWorks/serial/serial.c
+++ b/Demo/msp430_CrossWorks/serial/serial.c
@@ -200,9 +200,7 @@ signed portBASE_TYPE xReturn;
 }
 /*-----------------------------------------------------------*/
 
-#ifdef MSP_ROWLEY_RB_PORT
-
-/* Serial interrupt service routines for the RB port. */
+#if configINTERRUPT_EXAMPLE_METHOD == 1
 
 	/*
 	 * UART RX interrupt service routine.
@@ -226,6 +224,7 @@ signed portBASE_TYPE xReturn;
 			taskYIELD();
 		}
 
+        /* Make sure any low power mode bits are clear before leaving the ISR. */
         __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
 	}
 	/*-----------------------------------------------------------*/
@@ -252,17 +251,16 @@ signed portBASE_TYPE xReturn;
 			sTHREEmpty = pdTRUE;
 		}
 
+        /* Make sure any low power mode bits are clear before leaving the ISR. */
         __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
 	}
+    /*-----------------------------------------------------------*/
 
-#endif
-/*-----------------------------------------------------------*/
+#elif configINTERRUPT_EXAMPLE_METHOD == 2
 
-#ifdef MSP_ROWLEY_MP_PORT
-
-/* Serial port interrupts for the alternative port code. */
-
-	void ISRCom1Rx( void )
+    /* This is a standard C function as an assembly file wrapper is used as an
+    interrupt entry point. */
+	void vRxISR( void )
 	{
 	signed portCHAR cChar;
 	portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
@@ -273,17 +271,16 @@ signed portBASE_TYPE xReturn;
 	
 		xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
 
-		if( xHigherPriorityTaskWoken )
-		{
-			/*If the post causes a task to wake force a context switch 
-			as the woken task may have a higher priority than the task we have 
-			interrupted. */
-			portEXIT_SWITCHING_ISR( pdTRUE );
-		}
+        /*If the post causes a task to wake force a context switch 
+        as the woken task may have a higher priority than the task we have 
+        interrupted. */
+        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 	}
 	/*-----------------------------------------------------------*/
 	
-	void ISRCom1Tx( void )
+    /* This is a standard C function as an assembly file wrapper is used as an
+    interrupt entry point. */
+	void vTxISR( void )
 	{
 	signed portCHAR cChar;
 	portBASE_TYPE xTaskWoken = pdFALSE;
@@ -303,5 +300,5 @@ signed portBASE_TYPE xReturn;
 		}
 	}
 
-#endif
+#endif /* configINTERRUPT_EXAMPLE_METHOD */
 /*-----------------------------------------------------------*/
diff --git a/Demo/msp430_CrossWorks/serial/serialASM.asm b/Demo/msp430_CrossWorks/serial/serialASM.asm
new file mode 100644
index 0000000000..85b6a0e347
--- /dev/null
+++ b/Demo/msp430_CrossWorks/serial/serialASM.asm
@@ -0,0 +1,101 @@
+/*
+	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 "FreeRTOSConfig.h"
+#include "portasm.h"
+
+/* These wrappers are only used when interrupt method 2 is being used.  See
+FreeRTOSConfig.h for an explanation. */
+#if configINTERRUPT_EXAMPLE_METHOD == 2
+
+.CODE
+
+
+
+
+
+/* Wrapper for the Rx UART interrupt. */
+_vUARTRx_Wrapper
+
+	portSAVE_CONTEXT
+	call #_vRxISR
+	portRESTORE_CONTEXT
+
+/*-----------------------------------------------------------*/
+
+/* Wrapper for the Tx UART interrupt. */
+_vUARTTx_Wrapper
+
+	portSAVE_CONTEXT
+	call #_vTxISR
+	portRESTORE_CONTEXT
+
+/*-----------------------------------------------------------*/
+
+
+      		
+
+	/* Place the UART ISRs in the correct vectors. */
+
+	.VECTORS
+
+	.KEEP
+
+	ORG		UART1RX_VECTOR
+	DW		_vUARTRx_Wrapper
+
+	ORG		UART1TX_VECTOR
+	DW		_vUARTTx_Wrapper		
+		
+
+#endif /* configINTERRUPT_EXAMPLE_METHOD */
+
+	END
+	
+