]> git.sur5r.net Git - freertos/commitdiff
Changed the way the ARM7/9 GCC ports enter interrupts that can cause a context switch.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 28 Oct 2007 13:55:35 +0000 (13:55 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 28 Oct 2007 13:55:35 +0000 (13:55 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@113 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

24 files changed:
Demo/ARM7_AT91FR40008_GCC/serial/serial.c
Demo/ARM7_AT91FR40008_GCC/serial/serialISR.c
Demo/ARM7_LPC2106_GCC/FreeRTOSConfig.h
Demo/ARM7_LPC2106_GCC/main.c
Demo/ARM7_LPC2106_GCC/serial/serial.c
Demo/ARM7_LPC2106_GCC/serial/serialISR.c
Demo/ARM7_LPC2138_Rowley/main.c
Demo/ARM7_LPC2138_Rowley/mainISR.c
Demo/ARM7_LPC2368_Eclipse/RTOSDemo/webserver/EMAC_ISR.c
Demo/ARM7_LPC2368_Eclipse/RTOSDemo/webserver/uIP_Task.c
Demo/ARM7_LPC2368_Rowley/webserver/EMAC_ISR.c
Demo/ARM7_LPC2368_Rowley/webserver/uIP_Task.c
Demo/WizNET_DEMO_GCC_ARM7/TCP.c
Demo/WizNET_DEMO_GCC_ARM7/TCPISR.c
Demo/WizNET_DEMO_GCC_ARM7/i2c.c
Demo/WizNET_DEMO_GCC_ARM7/i2cISR.c
Demo/lwIP_Demo_Rowley_ARM7/EMAC/SAM7_EMAC.c
Demo/lwIP_Demo_Rowley_ARM7/EMAC/SAM7_EMAC_ISR.c
Demo/lwIP_Demo_Rowley_ARM7/USB/USB-CDC.c
Demo/lwIP_Demo_Rowley_ARM7/USB/USBIsr.c
Source/portable/GCC/ARM7_AT91FR40008/portmacro.h
Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h
Source/portable/GCC/ARM7_LPC2000/portmacro.h
Source/portable/GCC/ARM7_LPC23xx/portmacro.h

index 49ab7fabffae5f6d4b4fe4641788aa3ec4cc66d7..34603757a414fa04a5ed16628644cdbc2dd01013 100644 (file)
@@ -87,7 +87,7 @@ xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned
 unsigned portLONG ulSpeed;\r
 unsigned portLONG ulCD;\r
 xComPortHandle xReturn = serHANDLE;\r
-extern void ( vUART_ISR )( void );\r
+extern void ( vUART_ISR_Wrapper )( void );\r
 \r
        /* The queues are used in the serial ISR routine, so are created from\r
        serialISR.c (which is always compiled to ARM mode. */\r
@@ -139,7 +139,7 @@ extern void ( vUART_ISR )( void );
                        /* Setup the interrupt for USART0.\r
 \r
                        Store interrupt handler function address in USART0 vector register... */\r
-                       AT91C_BASE_AIC->AIC_SVR[ portUSART0_AIC_CHANNEL ] = (unsigned long)vUART_ISR;\r
+                       AT91C_BASE_AIC->AIC_SVR[ portUSART0_AIC_CHANNEL ] = (unsigned long)vUART_ISR_Wrapper;\r
                        \r
                        /* USART0 interrupt level-sensitive, priority 1... */\r
                        AT91C_BASE_AIC->AIC_SMR[ portUSART0_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 1;\r
index a8b3ad57737f0c33ceaa047b61d08b75c4882e23..34d45f2ebb8b3a143025ee556a924b63cbb3f787 100644 (file)
@@ -74,7 +74,11 @@ static xQueueHandle xCharsForTx;
 \r
 /* UART0 interrupt service routine.  This can cause a context switch so MUST\r
 be declared "naked". */\r
-void vUART_ISR( void ) __attribute__ ((naked));\r
+void vUART_ISR_Wrapper( void ) __attribute__ ((naked));\r
+\r
+/* The ISR function that actually performs the work.  This must be separate \r
+from the wrapper to ensure the correct stack frame is set up. */\r
+void vUART_ISR_Handler( void );\r
 \r
 /*-----------------------------------------------------------*/\r
 void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx )\r
@@ -90,21 +94,26 @@ void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vUART_ISR( void )\r
+void vUART_ISR_Wrapper( void )\r
 {\r
-       /* This ISR can cause a context switch, so the first statement must be a\r
-       call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any\r
-       variable declarations. */\r
-       portENTER_SWITCHING_ISR();\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
 \r
-       /* Now we can declare the local variables.   These must be static. */\r
-       static signed portCHAR cChar;\r
-       static portBASE_TYPE xTaskWokenByTx, xTaskWokenByRx;\r
-       static unsigned portLONG ulStatus;\r
+       /* Call the handler.  This must be a separate function to ensure the \r
+       stack frame is correctly set up. */\r
+       vUART_ISR_Handler();\r
 \r
-       /* These variables are static so need initialising manually here. */\r
-       xTaskWokenByTx = pdFALSE;\r
-       xTaskWokenByRx = pdFALSE;\r
+       /* Restore the context of whichever task will run next. */\r
+       portRESTORE_CONTEXT();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vUART_ISR_Handler( void )\r
+{\r
+/* Now we can declare the local variables.   These must be static. */\r
+signed portCHAR cChar;\r
+portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;\r
+unsigned portLONG ulStatus;\r
 \r
        /* What caused the interrupt? */\r
        ulStatus = AT91C_BASE_US0->US_CSR & AT91C_BASE_US0->US_IMR;\r
@@ -140,9 +149,14 @@ void vUART_ISR( void )
        /* Acknowledge the interrupt at AIC level... */\r
        AT91C_BASE_AIC->AIC_EOICR = serCLEAR_AIC_INTERRUPT;\r
 \r
-       /* Exit the ISR.  If a task was woken by either a character being received\r
-       or transmitted then a context switch will occur. */\r
-       portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );\r
+       /* If an event caused a task to unblock then we call "Yield from ISR" to\r
+       ensure that the unblocked task is the task that executes when the interrupt\r
+       completes if the unblocked task has a priority higher than the interrupted\r
+       task. */\r
+       if( xTaskWokenByTx || xTaskWokenByRx )\r
+       {\r
+               portYIELD_FROM_ISR();\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index ffb291e88fd0c63f713c96a6a8f0f9a1c21af327..ed948898d3e17a6b231f72de48fcc96f1953e09a 100644 (file)
@@ -56,7 +56,7 @@
 #define configTICK_RATE_HZ                     ( ( portTickType ) 1000 )\r
 #define configMAX_PRIORITIES           ( ( unsigned portBASE_TYPE ) 5 )\r
 #define configMINIMAL_STACK_SIZE       ( ( unsigned portSHORT ) 128 )\r
-#define configTOTAL_HEAP_SIZE          ( ( size_t ) ( 23 * 1024 ) )\r
+#define configTOTAL_HEAP_SIZE          ( ( size_t ) ( 24 * 1024 ) )\r
 #define configMAX_TASK_NAME_LEN                ( 16 )\r
 #define configUSE_TRACE_FACILITY       0\r
 #define configUSE_16_BIT_TICKS         0\r
index f5bc1dd3c4d045bef7188b72442cac43b95fb092..2e3bf2b903cec878675e8693b050853c5695594f 100644 (file)
 /* Priorities for the demo application tasks. */\r
 #define mainLED_TASK_PRIORITY          ( tskIDLE_PRIORITY + 3 )\r
 #define mainCOM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
-#define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 2 )\r
+#define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 0 )\r
 #define mainCHECK_TASK_PRIORITY                ( tskIDLE_PRIORITY + 4 )\r
-#define mainSEM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
+#define mainSEM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 0 )\r
 #define mainBLOCK_Q_PRIORITY           ( tskIDLE_PRIORITY + 2 )\r
 \r
 /* The rate at which the on board LED will toggle when there is/is not an \r
@@ -247,6 +247,7 @@ xTaskHandle xCreatedTask;
                parameter. */\r
                ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;\r
                xCreatedTask = mainNO_TASK;\r
+\r
                if( xTaskCreate( vMemCheckTask, ( signed portCHAR * ) "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )\r
                {\r
                        /* Could not create the task - we have probably run out of heap. */\r
index bbb5b207adc158f4decd180a761360caad8515ca..694d8a89000169c5289f1935ce476771970a5306 100644 (file)
@@ -118,7 +118,7 @@ xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned
 {\r
 unsigned portLONG ulDivisor, ulWantedClock;\r
 xComPortHandle xReturn = serHANDLE;\r
-extern void ( vUART_ISR )( void );\r
+extern void ( vUART_ISR_Wrapper )( void );\r
 \r
        /* The queues are used in the serial ISR routine, so are created from\r
        serialISR.c (which is always compiled to ARM mode. */\r
@@ -153,7 +153,7 @@ extern void ( vUART_ISR )( void );
                        /* Setup the VIC for the UART. */\r
                        VICIntSelect &= ~( serUART0_VIC_CHANNEL_BIT );\r
                        VICIntEnable |= serUART0_VIC_CHANNEL_BIT;\r
-                       VICVectAddr1 = ( portLONG ) vUART_ISR;\r
+                       VICVectAddr1 = ( portLONG ) vUART_ISR_Wrapper;\r
                        VICVectCntl1 = serUART0_VIC_CHANNEL | serUART0_VIC_ENABLE;\r
 \r
                        /* Enable UART0 interrupts. */\r
index 34d542f7cc594a3c004702c7121ed143aa8399fd..4aaae98563115557ff38b11b9fab6b96a6442847 100644 (file)
@@ -80,9 +80,11 @@ static volatile portLONG lTHREEmpty;
  */\r
 void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx, portLONG volatile **pplTHREEmptyFlag );\r
 \r
-/* UART0 interrupt service routine.  This can cause a context switch so MUST\r
-be declared "naked". */\r
-void vUART_ISR( void ) __attribute__ ((naked));\r
+/* UART0 interrupt service routine entry point. */\r
+void vUART_ISR_Wrapper( void ) __attribute__ ((naked));\r
+\r
+/* UART0 interrupt service routine handler. */\r
+void vUART_ISR_Handler( void );\r
 \r
 /*-----------------------------------------------------------*/\r
 void vSerialISRCreateQueues(   unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, \r
@@ -103,20 +105,24 @@ void vSerialISRCreateQueues(      unsigned portBASE_TYPE uxQueueLength, xQueueHandle
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vUART_ISR( void )\r
+void vUART_ISR_Wrapper( void )\r
 {\r
-       /* This ISR can cause a context switch, so the first statement must be a\r
-       call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any\r
-       variable declarations. */\r
-       portENTER_SWITCHING_ISR();\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* Call the handler.  This must be a separate function from the wrapper\r
+       to ensure the correct stack frame is set up. */\r
+       vUART_ISR_Handler();\r
 \r
-       /* Now we can declare the local variables.   These must be static. */\r
-       static signed portCHAR cChar;\r
-       static portBASE_TYPE xTaskWokenByTx, xTaskWokenByRx;\r
+       /* Restore the context of whichever task is going to run next. */\r
+       portRESTORE_CONTEXT();\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       /* As these variables are static they must be initialised manually here. */\r
-       xTaskWokenByTx = pdFALSE;\r
-       xTaskWokenByRx = pdFALSE;\r
+void vUART_ISR_Handler( void )\r
+{\r
+signed portCHAR cChar;\r
+portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;\r
 \r
        /* What caused the interrupt? */\r
        switch( UART0_IIR & serINTERRUPT_SOURCE_MASK )\r
@@ -154,14 +160,15 @@ void vUART_ISR( void )
                                                                break;\r
        }\r
 \r
+       if( xTaskWokenByTx || xTaskWokenByRx )\r
+       {\r
+               portYIELD_FROM_ISR();\r
+       }\r
+\r
        /* Clear the ISR in the VIC. */\r
        VICVectAddr = serCLEAR_VIC_INTERRUPT;\r
-\r
-       /* Exit the ISR.  If a task was woken by either a character being received\r
-       or transmitted then a context switch will occur. */\r
-       portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );\r
 }\r
-/*-----------------------------------------------------------*/\r
+\r
 \r
 \r
 \r
index 1e6e33944aaddb6b746f5e5faa208a4d93c4e34a..ab1e2ecd1ee9b2219f4e3e6c5b7ce3e2bb0a7dbb 100644 (file)
@@ -96,6 +96,8 @@
 #define mainLED_DELAY                                          ( ( portTickType ) 500 / portTICK_RATE_MS )\r
 #define mainCHECK_DELAY                                                ( ( portTickType ) 5000 / portTICK_RATE_MS )\r
 #define mainLIST_BUFFER_SIZE                           2048\r
+#define mainNO_DELAY                                           ( 0 )\r
+#define mainSHORT_DELAY                                                ( 150 / portTICK_RATE_MS )\r
 \r
 /* Task priorities. */\r
 #define mainLED_TASK_PRIORITY                          ( tskIDLE_PRIORITY + 2 )\r
@@ -178,7 +180,7 @@ int main( void )
        /* Start the scheduler. */\r
        vTaskStartScheduler();\r
 \r
-       /* The scheduler should now running, so we will only ever reach here if we\r
+       /* The scheduler should now be running, so we will only ever reach here if we\r
        ran out of heap space. */\r
 \r
        return 0;\r
@@ -290,7 +292,7 @@ static void vButtonHandlerTask( void *pvParameters )
 static portCHAR cListBuffer[ mainLIST_BUFFER_SIZE ];\r
 const portCHAR *pcList = &( cListBuffer[ 0 ] );\r
 const portCHAR * const pcHeader = "\nTask          State  Priority  Stack      #\n************************************************";\r
-extern void (vButtonISR) ( void );\r
+extern void (vButtonISRWrapper) ( void );\r
 \r
        /* Configure the interrupt. */\r
        portENTER_CRITICAL();   \r
@@ -303,15 +305,19 @@ extern void (vButtonISR) ( void );
                /* Setup the VIC for EINT 1. */\r
                VICIntSelect &= ~mainEINT_1_VIC_CHANNEL_BIT;\r
                VICIntEnable |= mainEINT_1_VIC_CHANNEL_BIT;\r
-               VICVectAddr1 = ( portLONG ) vButtonISR;\r
+               VICVectAddr1 = ( portLONG ) vButtonISRWrapper;\r
                VICVectCntl1 = mainEINT_1_ENABLE_BIT | mainEINT_1_CHANNEL;\r
        }\r
        portEXIT_CRITICAL();\r
 \r
        for( ;; )\r
        {\r
+               /* For debouncing, wait a while then clear the semaphore. */\r
+               vTaskDelay( mainSHORT_DELAY );\r
+               xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );\r
+\r
                /* Wait for an interrupt. */\r
-               while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );\r
+               xSemaphoreTake( xButtonSemaphore, portMAX_DELAY );\r
 \r
                /* Send the column headers to the print task for display. */\r
                xQueueSend( xPrintQueue, &pcHeader, portMAX_DELAY );\r
index ae93705624bc8e7bbc62aa46e6e7262010c77144..7890a9638aa6835dfb840974d6edc534adebf28e 100644 (file)
 \r
 /*\r
  * Interrupt routine that simply wakes vButtonHandlerTask on each interrupt \r
- * generated by a push of the built in button.\r
+ * generated by a push of the built in button.  The wrapper takes care of\r
+ * the ISR entry.  This then calls the actual handler function to perform\r
+ * the work.  This work should not be done in the wrapper itself unless\r
+ * you are absolutely sure that no stack space is used.\r
  */\r
-void vButtonISR( void ) __attribute__ ((naked));\r
+void vButtonISRWrapper( void ) __attribute__ ((naked));\r
+void vButtonHandler( void );\r
+\r
+void vButtonHandler( void )\r
+{\r
 extern xSemaphoreHandle xButtonSemaphore;\r
 \r
-void vButtonISR( void )\r
+       if( xSemaphoreGiveFromISR( xButtonSemaphore, pdFALSE ) )\r
+       {\r
+               /* We have woken a task.  Calling "yield from ISR" here will ensure\r
+               the interrupt returns to the woken task if it has a priority higher\r
+               than the interrupted task. */\r
+               portYIELD_FROM_ISR();\r
+       }\r
+\r
+    EXTINT = isrCLEAR_EINT_1;\r
+    VICVectAddr = 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vButtonISRWrapper( void )\r
 {\r
-       portENTER_SWITCHING_ISR();\r
-               xSemaphoreGiveFromISR( xButtonSemaphore, pdFALSE );\r
-        EXTINT = isrCLEAR_EINT_1;\r
-        VICVectAddr = 0;\r
-       portEXIT_SWITCHING_ISR( pdTRUE );\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* Call the handler to do the work.  This must be a separate function to\r
+       the wrapper to ensure the correct stack frame is set up. */\r
+       vButtonHandler();\r
+\r
+       /* Restore the context of whichever task is going to run once the interrupt\r
+       completes. */\r
+       portRESTORE_CONTEXT();\r
 }\r
 \r
 \r
index 495fea5006233b5a9d37a3efe431ad1ad412e401..b78837d132edb9a82d3b59f5d5a853a2f649a3f3 100644 (file)
@@ -2,17 +2,18 @@
 #include "Semphr.h"\r
 #include "Task.h"\r
 \r
-void vEMAC_ISR( void ) __attribute__((naked));\r
+/* The interrupt entry point. */\r
+void vEMAC_ISR_Wrapper( void ) __attribute__((naked));\r
 \r
-extern xSemaphoreHandle xEMACSemaphore;\r
+/* The handler that does the actual work. */\r
+void vEMAC_ISR_Handler( void );\r
 \r
-void vEMAC_ISR( void )\r
-{\r
-    portENTER_SWITCHING_ISR();\r
+extern xSemaphoreHandle xEMACSemaphore;\r
 \r
-    static portBASE_TYPE xSwitchRequired;\r
 \r
-       xSwitchRequired = pdFALSE;\r
+void vEMAC_ISR_Handler( void )\r
+{\r
+portBASE_TYPE xSwitchRequired = pdFALSE;\r
 \r
     /* Clear the interrupt. */\r
     MAC_INTCLEAR = 0xffff;\r
@@ -21,11 +22,22 @@ void vEMAC_ISR( void )
     /* Ensure the uIP task is not blocked as data has arrived. */\r
     if( xSemaphoreGiveFromISR( xEMACSemaphore, pdFALSE ) )\r
     {\r
-        xSwitchRequired = pdTRUE;\r
+       /* Giving the semaphore woke a task. */\r
+        portYIELD_FROM_ISR();\r
     }\r
-\r
-    /* Switch to the uIP task. */\r
-    portEXIT_SWITCHING_ISR( xSwitchRequired );\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
+void vEMAC_ISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+    portSAVE_CONTEXT();\r
+    \r
+    /* Call the handler.  This must be a separate function unless you can\r
+    guarantee that no stack will be used. */\r
+    vEMAC_ISR_Handler();\r
+    \r
+    /* Restore the context of whichever task is going to run next. */\r
+    portRESTORE_CONTEXT();\r
+}\r
 \r
index 1520d152409d0d1fc349bf2b7647db9d7de50878..77e1ec2787eceb8ab5afbf01e616c7983c04546a 100644 (file)
@@ -62,7 +62,7 @@
 #define uipIP_ADDR0            172\r
 #define uipIP_ADDR1            25\r
 #define uipIP_ADDR2            218\r
-#define uipIP_ADDR3            10      \r
+#define uipIP_ADDR3            16      \r
 \r
 /* How long to wait before attempting to connect the MAC again. */\r
 #define uipINIT_WAIT    100\r
@@ -115,7 +115,7 @@ void vuIP_Task( void *pvParameters )
 portBASE_TYPE i;\r
 uip_ipaddr_t xIPAddr;\r
 struct timer periodic_timer, arp_timer;\r
-extern void ( vEMAC_ISR )( void );\r
+extern void ( vEMAC_ISR_Wrapper )( void );\r
 \r
        /* Create the semaphore used by the ISR to wake this task. */\r
        vSemaphoreCreateBinary( xEMACSemaphore );\r
@@ -138,7 +138,7 @@ extern void ( vEMAC_ISR )( void );
        {\r
                MAC_INTENABLE = INT_RX_DONE;\r
         VICIntEnable |= 0x00200000;\r
-        VICVectAddr21 = ( portLONG ) vEMAC_ISR;\r
+        VICVectAddr21 = ( portLONG ) vEMAC_ISR_Wrapper;\r
                prvSetMACAddress();\r
        }\r
        portEXIT_CRITICAL();\r
index 9df1ffe269a96a19a704e9bc005bbf18b16a5590..1796ce7570c1cb9ea40868e7820cf12275545e23 100644 (file)
@@ -2,21 +2,17 @@
 #include "Semphr.h"\r
 #include "Task.h"\r
 \r
-void vEMAC_ISR( void ) __attribute__((naked));\r
+/* The interrupt entry point. */\r
+void vEMAC_ISR_Wrapper( void ) __attribute__((naked));\r
+\r
+/* The function that actually performs the interrupt processing.  This must be \r
+separate to the wrapper to ensure the correct stack frame is set up. */\r
+void vEMAC_ISR_Handler( void );\r
 \r
 extern xSemaphoreHandle xEMACSemaphore;\r
 \r
-void vEMAC_ISR( void )\r
+void vEMAC_ISR_Handler( void )\r
 {\r
-    portENTER_SWITCHING_ISR();\r
-\r
-\r
-       /* Variable must be static. */\r
-    static portBASE_TYPE xSwitchRequired;\r
-\r
-       /* As the variable is static it must be manually initialised here. */\r
-       xSwitchRequired = pdFALSE;\r
-\r
     /* Clear the interrupt. */\r
     IntClear = 0xffff;\r
     VICVectAddr = 0;\r
@@ -24,11 +20,27 @@ void vEMAC_ISR( void )
     /* Ensure the uIP task is not blocked as data has arrived. */\r
     if( xSemaphoreGiveFromISR( xEMACSemaphore, pdFALSE ) )\r
     {\r
-        xSwitchRequired = pdTRUE;\r
+               /* If the uIP task was unblocked then calling "Yield from ISR" here\r
+               will ensure the interrupt returns directly to the uIP task, if it\r
+               is the highest priority read task. */\r
+        portYIELD_FROM_ISR();\r
     }\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-    /* Switch to the uIP task. */\r
-    portEXIT_SWITCHING_ISR( xSwitchRequired );\r
+void vEMAC_ISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* Call the handler function.  This must be separate from the wrapper\r
+       function to ensure the correct stack frame is set up. */\r
+       vEMAC_ISR_Handler();\r
+\r
+       /* Restore the context of whichever task is going to run next. */\r
+       portRESTORE_CONTEXT();\r
 }\r
 \r
 \r
+\r
+\r
index 304004f022c4c0eef868f3ad1a8a811c5b0786de..1c16824e9c15a558a715f61d36f846bb9e0189f4 100644 (file)
@@ -115,7 +115,7 @@ void vuIP_Task( void *pvParameters )
 portBASE_TYPE i;\r
 uip_ipaddr_t xIPAddr;\r
 struct timer periodic_timer, arp_timer;\r
-extern void ( vEMAC_ISR )( void );\r
+extern void ( vEMAC_ISR_Wrapper )( void );\r
 \r
        /* Create the semaphore used by the ISR to wake this task. */\r
        vSemaphoreCreateBinary( xEMACSemaphore );\r
@@ -138,7 +138,7 @@ extern void ( vEMAC_ISR )( void );
        {\r
         IntEnable = INT_RX_DONE;\r
         VICIntEnable |= 0x00200000;\r
-        VICVectAddr21 = ( portLONG ) vEMAC_ISR;\r
+        VICVectAddr21 = ( portLONG ) vEMAC_ISR_Wrapper;\r
                prvSetMACAddress();\r
        }\r
        portEXIT_CRITICAL();\r
index c1639b0799413d5e0ca33e00ac1e1a7a0871e372..71262a07e6e38571d0c6f240cc51ff55c8e776c9 100644 (file)
@@ -300,10 +300,10 @@ void vTCPHardReset( void )
        /* Install the ISR into the VIC - but don't enable it yet! */\r
        portENTER_CRITICAL();\r
        {\r
-               extern void ( vEINT0_ISR )( void );\r
+               extern void ( vEINT0_ISR_Wrapper )( void );\r
 \r
                VICIntSelect &= ~( tcpEINT0_VIC_CHANNEL_BIT );\r
-               VICVectAddr3 = ( portLONG ) vEINT0_ISR;\r
+               VICVectAddr3 = ( portLONG ) vEINT0_ISR_Wrapper;\r
 \r
                VICVectCntl3 = tcpEINT0_VIC_CHANNEL | tcpEINT0_VIC_ENABLE;\r
        }\r
index 5b1d3bff633cefb27cff98efb93bf9241b1957a6..94261378ece9da1fa03c7cadfeb03ba844f11970 100644 (file)
 #define tcpEINT0_VIC_CHANNEL_BIT       ( ( unsigned portLONG ) 0x4000 )\r
 \r
 /* EINT0 interrupt handler.  This processes interrupts from the WIZnet device. */\r
-void vEINT0_ISR( void ) __attribute__((naked));\r
+void vEINT0_ISR_Wrapper( void ) __attribute__((naked));\r
+\r
+/* The handler that goes with the EINT0 wrapper. */\r
+void vEINT0_ISR_Handler( void );\r
 \r
 /* Variable is required for its address, but does not otherwise get used. */\r
 static portLONG lDummyVariable;\r
@@ -53,21 +56,16 @@ static portLONG lDummyVariable;
  * the TCP task.  This wakes the task so the interrupt can be processed.  The\r
  * source of the interrupt has to be ascertained by the TCP task as this \r
  * requires an I2C transaction which cannot be performed from this ISR.\r
+ * Note this code predates the introduction of semaphores, a semaphore should\r
+ * be used in place of the empty queue message.\r
  */\r
-void vEINT0_ISR( void )\r
+void vEINT0_ISR_Handler( void )\r
 {\r
-       portENTER_SWITCHING_ISR();\r
-\r
-       extern xQueueHandle xTCPISRQueue;\r
-\r
-       /* Must be declared static. */\r
-       static portBASE_TYPE xTaskWoken;\r
-\r
-       /* As the variable is static it must be manually initialised. */\r
-       xTaskWoken = pdFALSE;\r
+extern xQueueHandle xTCPISRQueue;\r
+portBASE_TYPE xTaskWoken = pdFALSE;\r
 \r
        /* Just wake the TCP task so it knows an ISR has occurred. */\r
-       xQueueSendFromISR( xTCPISRQueue, ( void * ) &lDummyVariable, xTaskWoken );      \r
+       xTaskWoken = xQueueSendFromISR( xTCPISRQueue, ( void * ) &lDummyVariable, xTaskWoken ); \r
 \r
        /* We cannot carry on processing interrupts until the TCP task has \r
        processed this one - so for now interrupts are disabled.  The TCP task will\r
@@ -77,10 +75,24 @@ void vEINT0_ISR( void )
        /* Clear the interrupt bit. */  \r
        VICVectAddr = tcpCLEAR_VIC_INTERRUPT;\r
 \r
-       /* Switch to the TCP task immediately so the cause of the interrupt can\r
-       be ascertained.  It is the responsibility of the TCP task to clear the\r
-       interrupts. */\r
-       portEXIT_SWITCHING_ISR( ( xTaskWoken ) );\r
+       if( xTaskWoken )\r
+       {\r
+               portYIELD_FROM_ISR();\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEINT0_ISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* The handler must be a separate function from the wrapper to\r
+       ensure the correct stack frame is set up. */\r
+       vEINT0_ISR_Handler();\r
+\r
+       /* Restore the context of whichever task is going to run next. */\r
+       portRESTORE_CONTEXT();\r
 }\r
 \r
 \r
index 19cd69da011074a547be3e3a38e1493628238eda..7b9bbfcd22c0ec75ffb3c23dfc653e967aba228f 100644 (file)
@@ -182,7 +182,7 @@ signed portBASE_TYPE xReturn;
 \r
 void i2cInit( void )\r
 {\r
-extern void ( vI2C_ISR )( void );\r
+extern void ( vI2C_ISR_Wrapper )( void );\r
 \r
        /* Create the queue used to send messages to the ISR. */\r
        vI2CISRCreateQueues( i2cQUEUE_LENGTH, &xMessagesForTx, &pulBusFree );\r
@@ -203,7 +203,7 @@ extern void ( vI2C_ISR )( void );
                /* Setup the VIC for the i2c interrupt. */\r
                VICIntSelect &= ~( i2cI2C_VIC_CHANNEL_BIT );\r
                VICIntEnable |= i2cI2C_VIC_CHANNEL_BIT;\r
-               VICVectAddr2 = ( portLONG ) vI2C_ISR;\r
+               VICVectAddr2 = ( portLONG ) vI2C_ISR_Wrapper;\r
 \r
                VICVectCntl2 = i2cI2C_VIC_CHANNEL | i2cI2C_VIC_ENABLE;\r
        }\r
index cfb4e9aadcc863e18d44f631bc481d1d10b772b8..22d6df619c859722c02e6d77624dd136c476e6da 100644 (file)
@@ -119,21 +119,36 @@ void vI2CISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *px
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vI2C_ISR( void ) __attribute__ (( naked ));\r
-void vI2C_ISR( void )\r
-{\r
-       portENTER_SWITCHING_ISR();\r
+/* The ISR entry point. */\r
+void vI2C_ISR_Wrapper( void ) __attribute__ (( naked ));\r
 \r
-       /* Variables must be static. */\r
+/* The ISR function to perform the actual work.  This must be a separate\r
+function from the wrapper to ensure the correct stack frame is set up. */\r
+void vI2C_ISR_Handler( void );\r
 \r
-       /* Holds the current transmission state. */                                                     \r
-       static I2C_STATE eCurrentState = eSentStart;\r
-       static portLONG lMessageIndex = -i2cBUFFER_ADDRESS_BYTES; /* There are two address bytes to send prior to the data. */\r
-       static portBASE_TYPE xTaskWokenByTx;\r
-       static portLONG lBytesLeft;\r
+/*-----------------------------------------------------------*/\r
 \r
-       xTaskWokenByTx = pdFALSE;\r
+void vI2C_ISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
 \r
+       /* Call the handler to perform the actual work.  This must be a\r
+       separate function to ensure the correct stack frame is set up. */\r
+       vI2C_ISR_Handler();\r
+\r
+       /* Restore the context of whichever task is going to run next. */\r
+       portRESTORE_CONTEXT();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vI2C_ISR_Handler( void )\r
+{\r
+/* Holds the current transmission state. */                                                    \r
+static I2C_STATE eCurrentState = eSentStart;\r
+static portLONG lMessageIndex = -i2cBUFFER_ADDRESS_BYTES; /* There are two address bytes to send prior to the data. */\r
+portBASE_TYPE xTaskWokenByTx = pdFALSE;\r
+portLONG lBytesLeft;\r
 \r
        /* The action taken for this interrupt depends on our current state. */\r
        switch( eCurrentState )\r
@@ -342,7 +357,10 @@ void vI2C_ISR( void )
        I2C_I2CONCLR = i2cSI_BIT;\r
        VICVectAddr = i2cCLEAR_VIC_INTERRUPT;\r
 \r
-       portEXIT_SWITCHING_ISR( ( xTaskWokenByTx ) );\r
+       if( xTaskWokenByTx )\r
+       {\r
+               portYIELD_FROM_ISR();\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index f5477f74c687923dc61c290f7c2340f8af1f1599..8e7665845f106ac1260e99a01b573f378b466613 100644 (file)
@@ -163,9 +163,9 @@ const unsigned char ucIPAddress[ 4 ]  = { emacIPADDR0, emacIPADDR1, emacIPADDR2,
 /* See the header file for descriptions of public functions. */\r
 \r
 /*\r
- * Prototype for the EMAC interrupt function - called by the asm wrapper.\r
+ * Prototype for the EMAC interrupt function.\r
  */\r
-void vEMACISR( void ) __attribute__ ((naked));\r
+void vEMACISR_Wrapper( void ) __attribute__ ((naked));\r
 \r
 /*\r
  * Initialise both the Tx and Rx descriptors used by the EMAC.\r
@@ -666,7 +666,7 @@ static void prvSetupEMACInterrupt( void )
                        AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;\r
 \r
                        /* Enable the interrupts in the AIC. */\r
-                       AT91F_AIC_ConfigureIt( AT91C_ID_EMAC, emacINTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vEMACISR );\r
+                       AT91F_AIC_ConfigureIt( AT91C_ID_EMAC, emacINTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vEMACISR_Wrapper );\r
             AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_EMAC;\r
                }\r
                portEXIT_CRITICAL();\r
index 32d982fe31cfa6e9abf68f20f80a0dfed3873b53..a8a717843debad05d4b370bf2c4e976d55dca8a7 100644 (file)
        ***************************************************************************\r
 */\r
 \r
-/* \r
-Changes from V3.2.4\r
-\r
-       + Also read the EMAC_RSR register in the EMAC ISR as a work around the \r
-         the EMAC bug that can reset the RX bit in EMAC_ISR register before the\r
-         bit has been read.\r
-\r
-Changes from V4.0.1\r
-\r
-       + Only check the interrupt status register to see if an EMAC Tx interrupt\r
-         has occurred.  Previously the TSR register was also inspected.\r
-*/\r
 \r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
@@ -58,26 +46,22 @@ Changes from V4.0.1
 task. */\r
 static xSemaphoreHandle xSemaphore = NULL;\r
 \r
-void vEMACISR( void ) __attribute__((naked));\r
+/* The interrupt entry point is naked so we can control the context saving. */\r
+void vEMACISR_Wrapper( void ) __attribute__((naked));\r
+\r
+/* The interrupt handler function must be separate from the entry function\r
+to ensure the correct stack frame is set up. */\r
+void vEMACISR_Handler( void );\r
 \r
 /*-----------------------------------------------------------*/\r
 /*\r
  * The EMAC ISR.  Handles both Tx and Rx complete interrupts.\r
  */\r
-void vEMACISR( void )\r
+void vEMACISR_Handler( void )\r
 {\r
-       /* This ISR can cause a context switch, so the first statement must be a\r
-       call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any\r
-       variable declarations. */\r
-       portENTER_SWITCHING_ISR();\r
-\r
-       /* Variable definitions can be made now.   These must be static. */\r
-       static volatile unsigned portLONG ulIntStatus, ulEventStatus;\r
-       static portBASE_TYPE xSwitchRequired;\r
-    extern void vClearEMACTxBuffer( void );\r
-\r
-       /* As the variable is static it must be initialised manually here. */\r
-       xSwitchRequired = pdFALSE;\r
+volatile unsigned portLONG ulIntStatus, ulEventStatus;\r
+portBASE_TYPE xSwitchRequired = pdFALSE;\r
+extern void vClearEMACTxBuffer( void );\r
 \r
        /* Find the cause of the interrupt. */\r
        ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;\r
@@ -103,8 +87,27 @@ void vEMACISR( void )
        AT91C_BASE_AIC->AIC_EOICR = 0;\r
 \r
        /* If a task was woken by either a frame being received then we may need to \r
-       switch to another task. */\r
-       portEXIT_SWITCHING_ISR( xSwitchRequired );\r
+       switch to another task.  If the unblocked task was of higher priority then\r
+       the interrupted task it will then execute immediately that the ISR\r
+       completes. */\r
+       if( xSwitchRequired )\r
+       {\r
+               portYIELD_FROM_ISR();\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void  vEMACISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* Call the handler to do the work.  This must be a separate\r
+       function to ensure the stack frame is set up correctly. */\r
+       vEMACISR_Handler();\r
+\r
+       /* Restore the context of whichever task will execute next. */\r
+       portRESTORE_CONTEXT();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index 92a7f3cce4154f30f67b0f160f15d6fdce65a793..47a9939f5439d3334968012d61767165996948c7 100644 (file)
@@ -699,7 +699,7 @@ static void vDetachUSBInterface( void)
 \r
 static void vInitUSBInterface( void )\r
 {\r
-extern void ( vUSB_ISR )( void );\r
+extern void ( vUSB_ISR_Wrapper )( void );\r
 \r
        /* Create the queue used to communicate between the USB ISR and task. */\r
        xUSBInterruptQueue = xQueueCreate( usbQUEUE_LENGTH + 1, sizeof( xISRStatus * ) );\r
@@ -759,7 +759,7 @@ extern void ( vUSB_ISR )( void );
 \r
        /* Enable the USB interrupts - other interrupts get enabled as the \r
        enumeration process progresses. */\r
-       AT91F_AIC_ConfigureIt( AT91C_ID_UDP, usbINTERRUPT_PRIORITY, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vUSB_ISR );\r
+       AT91F_AIC_ConfigureIt( AT91C_ID_UDP, usbINTERRUPT_PRIORITY, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vUSB_ISR_Wrapper );\r
        AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_UDP;\r
 \r
 \r
index db1f9cf91c5f9f2028dc8327751976d9150b3a35..85f233f307b2dd6dff41a0d5776d0b07161c443f 100644 (file)
@@ -59,27 +59,20 @@ extern xQueueHandle xUSBInterruptQueue;
 /*-----------------------------------------------------------*/\r
 \r
 /* The ISR can cause a context switch so is declared naked. */\r
-void vUSB_ISR( void ) __attribute__ ((naked));\r
+void vUSB_ISR_Wrapper( void ) __attribute__ ((naked));\r
 \r
+/* The function that actually performs the ISR work.  This must be separate\r
+from the wrapper function to ensure the correct stack frame gets set up. */\r
+void vUSB_ISR_Handler( void );\r
 /*-----------------------------------------------------------*/\r
 \r
-\r
-void vUSB_ISR( void )\r
+void vUSB_ISR_Handler( void )\r
 {\r
-       /* This ISR can cause a context switch.  Therefore a call to the \r
-       portENTER_SWITCHING_ISR() macro is made.  This must come BEFORE any \r
-       stack variable declarations. */\r
-       portENTER_SWITCHING_ISR();\r
-\r
-       /* Now variables can be declared.  These must be static. */\r
-       static portCHAR cTaskWokenByPost; \r
-       static volatile unsigned portLONG ulNextMessage = 0;\r
-       static xISRStatus *pxMessage;\r
-       static unsigned portLONG ulRxBytes;\r
-       static unsigned portCHAR ucFifoIndex;\r
-\r
-       /* As the variables are static they must be initialised manually here. */\r
-       cTaskWokenByPost = pdFALSE; \r
+portCHAR cTaskWokenByPost = pdFALSE;\r
+static volatile unsigned portLONG ulNextMessage = 0;\r
+xISRStatus *pxMessage;\r
+unsigned portLONG ulRxBytes;\r
+unsigned portCHAR ucFifoIndex;\r
 \r
     /* Use the next message from the array. */\r
        pxMessage = &( xISRMessages[ ( ulNextMessage & usbQUEUE_LENGTH ) ] );\r
@@ -158,6 +151,27 @@ void vUSB_ISR( void )
        AT91C_BASE_AIC->AIC_EOICR = 0;\r
 \r
        /* Do a task switch if needed */\r
-       portEXIT_SWITCHING_ISR( cTaskWokenByPost )\r
+       if( cTaskWokenByPost )\r
+       {\r
+               /* This call will ensure that the unblocked task will be executed\r
+               immediately upon completion of the ISR if it has a priority higher\r
+               than the interrupted task. */\r
+               portYIELD_FROM_ISR();\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vUSB_ISR_Wrapper( void )\r
+{\r
+       /* Save the context of the interrupted task. */\r
+       portSAVE_CONTEXT();\r
+\r
+       /* Call the handler to do the work.  This must be a separate\r
+       function to ensure the stack frame is set up correctly. */\r
+       vUSB_ISR_Handler();\r
+\r
+       /* Restore the context of whichever task will execute next. */\r
+       portRESTORE_CONTEXT();\r
 }\r
 \r
+\r
index 2458050a3068a11a9cef9fa37962ea587f30b4bb..60baa50ead1dc3ee78877ef85fc00f99ff72581f 100644 (file)
 \r
        Changes from V4.5.0\r
 \r
-       + The macro portENTER_SWITCHING_ISR() no longer attempts to use the frame\r
-         pointer.  Variables declared within ISRs must now be declared static.\r
+       + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros\r
+         and replaced them with portYIELD_FROM_ISR() macro.  Application code \r
+         should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()\r
+         macros as per the V4.5.1 demo code.\r
 */\r
 \r
 #ifndef PORTMACRO_H\r
@@ -89,8 +91,8 @@
 #define portSTACK_GROWTH                       ( -1 )\r
 #define portTICK_RATE_MS                       ( ( portTickType ) 1000 / configTICK_RATE_HZ )          \r
 #define portBYTE_ALIGNMENT                     4\r
-#define portYIELD()                                    asm volatile ( "SWI" )\r
-#define portNOP()                                      asm volatile ( "NOP" );\r
+#define portYIELD()                                    asm volatile ( "SWI" )\r
+#define portNOP()                                      asm volatile ( "NOP" )\r
 \r
 /*\r
  * These define the timer to use for generating the tick interrupt.\r
@@ -194,29 +196,7 @@ extern volatile unsigned portLONG ulCriticalNesting;                                       \
        ( void ) pxCurrentTCB;                                                                                          \\r
 }\r
 \r
-/*-----------------------------------------------------------\r
- * ISR entry and exit macros.  These are only required if a task switch\r
- * is required from the ISR.\r
- *----------------------------------------------------------*/\r
-\r
-#define portENTER_SWITCHING_ISR()                                                                              \\r
-       /* Save the context of the interrupted task. */                                         \\r
-       portSAVE_CONTEXT();                                                                                                     \\r
-       {\r
-\r
-#define portEXIT_SWITCHING_ISR( SwitchRequired )                                               \\r
-               /* If a switch is required then we just need to call */                 \\r
-               /* vTaskSwitchContext() as the context has already been */              \\r
-               /* saved. */                                                                                                    \\r
-               if( SwitchRequired )                                                                                    \\r
-               {                                                                                                                               \\r
-                       vTaskSwitchContext();                                                                           \\r
-               }                                                                                                                               \\r
-       }                                                                                                                                       \\r
-       /* Restore the context of which ever task is now the highest */         \\r
-       /* priority that is ready to run. */                                                            \\r
-       portRESTORE_CONTEXT();\r
-/*-----------------------------------------------------------*/        \r
+#define portYIELD_FROM_ISR() vTaskSwitchContext()\r
 \r
 /* Critical section handling. */\r
 \r
index 9ec48a238241b0c111349b0e0d8bf73438376d11..d5d2ece776ac4bd5e110e4ea5891f1ecb866ac17 100644 (file)
        + The assembler statements are now included in a single asm block rather\r
          than each line having its own asm block.\r
 \r
-       + The macro portENTER_SWITCHING_ISR() no longer attempts to use the frame\r
-         pointer.  Variables declared within ISRs must now be declared static.\r
+       Changes from V4.5.0\r
+\r
+       + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros\r
+         and replaced them with portYIELD_FROM_ISR() macro.  Application code \r
+         should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()\r
+         macros as per the V4.5.1 demo code.\r
 */\r
 \r
 #ifndef PORTMACRO_H\r
@@ -184,31 +188,8 @@ extern volatile unsigned portLONG ulCriticalNesting;                                       \
 }\r
 \r
 \r
-/*-----------------------------------------------------------\r
- * ISR entry and exit macros.  These are only required if a task switch\r
- * is required from the ISR.\r
- *----------------------------------------------------------*/\r
-\r
-\r
-#define portENTER_SWITCHING_ISR()                                                                              \\r
-       /* Save the context of the interrupted task. */                                         \\r
-       portSAVE_CONTEXT();                                                                                                     \\r
-       {\r
-\r
-#define portEXIT_SWITCHING_ISR( SwitchRequired )                                               \\r
-               /* If a switch is required then we just need to call */                 \\r
-               /* vTaskSwitchContext() as the context has already been */              \\r
-               /* saved. */                                                                                                    \\r
-               if( SwitchRequired )                                                                                    \\r
-               {                                                                                                                               \\r
-                       vTaskSwitchContext();                                                                           \\r
-               }                                                                                                                               \\r
-       }                                                                                                                                       \\r
-       /* Restore the context of which ever task is now the highest */         \\r
-       /* priority that is ready to run. */                                                            \\r
-       portRESTORE_CONTEXT();\r
-\r
-#define portYIELD()                                    asm volatile ( "SWI" ); \r
+#define portYIELD_FROM_ISR()           vTaskSwitchContext()\r
+#define portYIELD()                                    asm volatile ( "SWI" )\r
 /*-----------------------------------------------------------*/\r
 \r
 \r
index 9ec48a238241b0c111349b0e0d8bf73438376d11..d5d2ece776ac4bd5e110e4ea5891f1ecb866ac17 100644 (file)
        + The assembler statements are now included in a single asm block rather\r
          than each line having its own asm block.\r
 \r
-       + The macro portENTER_SWITCHING_ISR() no longer attempts to use the frame\r
-         pointer.  Variables declared within ISRs must now be declared static.\r
+       Changes from V4.5.0\r
+\r
+       + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros\r
+         and replaced them with portYIELD_FROM_ISR() macro.  Application code \r
+         should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()\r
+         macros as per the V4.5.1 demo code.\r
 */\r
 \r
 #ifndef PORTMACRO_H\r
@@ -184,31 +188,8 @@ extern volatile unsigned portLONG ulCriticalNesting;                                       \
 }\r
 \r
 \r
-/*-----------------------------------------------------------\r
- * ISR entry and exit macros.  These are only required if a task switch\r
- * is required from the ISR.\r
- *----------------------------------------------------------*/\r
-\r
-\r
-#define portENTER_SWITCHING_ISR()                                                                              \\r
-       /* Save the context of the interrupted task. */                                         \\r
-       portSAVE_CONTEXT();                                                                                                     \\r
-       {\r
-\r
-#define portEXIT_SWITCHING_ISR( SwitchRequired )                                               \\r
-               /* If a switch is required then we just need to call */                 \\r
-               /* vTaskSwitchContext() as the context has already been */              \\r
-               /* saved. */                                                                                                    \\r
-               if( SwitchRequired )                                                                                    \\r
-               {                                                                                                                               \\r
-                       vTaskSwitchContext();                                                                           \\r
-               }                                                                                                                               \\r
-       }                                                                                                                                       \\r
-       /* Restore the context of which ever task is now the highest */         \\r
-       /* priority that is ready to run. */                                                            \\r
-       portRESTORE_CONTEXT();\r
-\r
-#define portYIELD()                                    asm volatile ( "SWI" ); \r
+#define portYIELD_FROM_ISR()           vTaskSwitchContext()\r
+#define portYIELD()                                    asm volatile ( "SWI" )\r
 /*-----------------------------------------------------------*/\r
 \r
 \r
index d6d3f4de5d91a22fd1dc3c41b72dbb200231d9f1..c74b3d017da9b12418030187e5fbba66ae006a3a 100644 (file)
        + The assembler statements are now included in a single asm block rather\r
          than each line having its own asm block.\r
 \r
-       + The macro portENTER_SWITCHING_ISR() no longer attempts to use the frame\r
-         pointer.  Variables declared within ISRs must now be declared static.\r
+       Changes from V4.5.0\r
+\r
+       + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros\r
+         and replaced them with portYIELD_FROM_ISR() macro.  Application code \r
+         should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()\r
+         macros as per the V4.5.1 demo code.\r
 */\r
 \r
 #ifndef PORTMACRO_H\r
@@ -181,31 +185,8 @@ extern volatile unsigned portLONG ulCriticalNesting;                                       \
 }\r
 \r
 \r
-/*-----------------------------------------------------------\r
- * ISR entry and exit macros.  These are only required if a task switch\r
- * is required from the ISR.\r
- *----------------------------------------------------------*/\r
-\r
-\r
-#define portENTER_SWITCHING_ISR()                                                                              \\r
-       /* Save the context of the interrupted task. */                                         \\r
-       portSAVE_CONTEXT();                                                                                                     \\r
-       {\r
-\r
-#define portEXIT_SWITCHING_ISR( SwitchRequired )                                               \\r
-               /* If a switch is required then we just need to call */                 \\r
-               /* vTaskSwitchContext() as the context has already been */              \\r
-               /* saved. */                                                                                                    \\r
-               if( SwitchRequired )                                                                                    \\r
-               {                                                                                                                               \\r
-                       vTaskSwitchContext();                                                                           \\r
-               }                                                                                                                               \\r
-       }                                                                                                                                       \\r
-       /* Restore the context of which ever task is now the highest */         \\r
-       /* priority that is ready to run. */                                                            \\r
-       portRESTORE_CONTEXT();\r
-\r
-#define portYIELD()                                    asm volatile ( "SWI" ); \r
+#define portYIELD_FROM_ISR()           vTaskSwitchContext()\r
+#define portYIELD()                                    asm volatile ( "SWI" )\r
 /*-----------------------------------------------------------*/\r
 \r
 \r