]> git.sur5r.net Git - freertos/commitdiff
Ensure that the configMAX_SYSCALL_INTERRUPT_PRIORITY setting works with all possible...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 5 Apr 2011 09:45:42 +0000 (09:45 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 5 Apr 2011 09:45:42 +0000 (09:45 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1342 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/MPLAB/PIC32MX/port.c
Source/portable/MPLAB/PIC32MX/port_asm.S
Source/portable/MPLAB/PIC32MX/portmacro.h

index ed860b2b7d01973092e482cd79f4a1f6fb87363d..cdff10a697370c4a410e417190d0df8e7fc4cf1a 100644 (file)
@@ -204,7 +204,13 @@ unsigned portBASE_TYPE uxSavedStatusRegister;
 \r
        asm volatile ( "di" );\r
        uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;\r
 \r
        asm volatile ( "di" );\r
        uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;\r
-       _CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) );\r
+       /* This clears the IPL bits, then sets them to \r
+       configMAX_SYSCALL_INTERRUPT_PRIORITY.  This function should not be called\r
+       from an interrupt that has a priority above \r
+       configMAX_SYSCALL_INTERRUPT_PRIORITY so, when used correctly, the action\r
+       can only result in the IPL being unchanged or raised, and therefore never\r
+       lowered. */\r
+       _CP0_SET_STATUS( ( ( uxSavedStatusRegister & ( ~portALL_IPL_BITS ) ) ) | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) );\r
 \r
        return uxSavedStatusRegister;\r
 }\r
 \r
        return uxSavedStatusRegister;\r
 }\r
index fd91d8df7ad3a0e016da06268cf9cc50f2c3ce5c..3ee756c59842367f62196e32b8459917d51bd884 100644 (file)
@@ -195,11 +195,14 @@ vPortYieldISR:
        lw                      s7, (s7)\r
        sw                      s5, (s7)\r
 \r
        lw                      s7, (s7)\r
        sw                      s5, (s7)\r
 \r
-       /* Set the interrupt mask to the max priority that can use the API. */\r
+       /* Set the interrupt mask to the max priority that can use the API.  The\r
+       yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which\r
+       is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever\r
+       raise the IPL value and never lower it. */\r
        di\r
        mfc0            s7, _CP0_STATUS\r
        di\r
        mfc0            s7, _CP0_STATUS\r
-       ori                     s7, s7, 1\r
-       ori                     s6, s7, configMAX_SYSCALL_INTERRUPT_PRIORITY << 10\r
+       ins             s7, $0, 10, 6\r
+       ori                     s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1\r
 \r
        /* This mtc0 re-enables interrupts, but only above \r
        configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
 \r
        /* This mtc0 re-enables interrupts, but only above \r
        configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
index 004cb9970eb80bb16a81917f96fb92ec2feec77e..cdebe6cefea572a29a7adc5eb6e7c773974fd66f 100644 (file)
@@ -84,7 +84,7 @@ extern "C" {
        typedef unsigned portSHORT portTickType;\r
        #define portMAX_DELAY ( portTickType ) 0xffff\r
 #else\r
        typedef unsigned portSHORT portTickType;\r
        #define portMAX_DELAY ( portTickType ) 0xffff\r
 #else\r
-       typedef unsigned portLONG portTickType;\r
+       typedef unsigned long portTickType;\r
        #define portMAX_DELAY ( portTickType ) 0xffffffff\r
 #endif\r
 /*-----------------------------------------------------------*/\r
        #define portMAX_DELAY ( portTickType ) 0xffffffff\r
 #endif\r
 /*-----------------------------------------------------------*/\r
@@ -96,28 +96,34 @@ extern "C" {
 /*-----------------------------------------------------------*/\r
 \r
 /* Critical section management. */\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Critical section management. */\r
-#define portIPL_SHIFT                          ( 10 )\r
-#define portALL_IPL_BITS                       ( 0x3f << portIPL_SHIFT )\r
+#define portIPL_SHIFT                          ( 10UL )\r
+#define portALL_IPL_BITS                       ( 0x3fUL << portIPL_SHIFT )\r
 #define portSW0_BIT                                    ( 0x01 << 8 )\r
 \r
 #define portSW0_BIT                                    ( 0x01 << 8 )\r
 \r
-#define portDISABLE_INTERRUPTS()                                                                                       \\r
-{                                                                                                                                                      \\r
-unsigned portLONG ulStatus;                                                                                                    \\r
-                                                                                                                                                       \\r
-       /* Mask interrupts at and below the kernel interrupt priority. */               \\r
-       ulStatus = _CP0_GET_STATUS();                                                                                   \\r
-       ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT );  \\r
-       _CP0_SET_STATUS( ulStatus );                                                                                    \\r
+/* This clears the IPL bits, then sets them to \r
+configMAX_SYSCALL_INTERRUPT_PRIORITY.  This function should not be called\r
+from an interrupt, so therefore will not be called with an IPL setting\r
+above configMAX_SYSCALL_INTERRUPT_PRIORITY.  Therefore, when used correctly, the \r
+instructions in this macro can only result in the IPL being raised, and \r
+therefore never lowered. */\r
+#define portDISABLE_INTERRUPTS()                                                                               \\r
+{                                                                                                                                              \\r
+unsigned long ulStatus;                                                                                                        \\r
+                                                                                                                                               \\r
+       /* Mask interrupts at and below the kernel interrupt priority. */       \\r
+       ulStatus = _CP0_GET_STATUS();                                                                           \\r
+       ulStatus &= ~portALL_IPL_BITS;                                                                          \\r
+       _CP0_SET_STATUS( ( ulStatus | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); \\r
 }\r
 \r
 }\r
 \r
-#define portENABLE_INTERRUPTS()                                                                                                \\r
-{                                                                                                                                                      \\r
-unsigned portLONG ulStatus;                                                                                                    \\r
-                                                                                                                                                       \\r
-       /* Unmask all interrupts. */                                                                                    \\r
-       ulStatus = _CP0_GET_STATUS();                                                                                   \\r
-       ulStatus &= ~portALL_IPL_BITS;                                                                                  \\r
-       _CP0_SET_STATUS( ulStatus );                                                                                    \\r
+#define portENABLE_INTERRUPTS()                                                                                        \\r
+{                                                                                                                                              \\r
+unsigned long ulStatus;                                                                                                        \\r
+                                                                                                                                               \\r
+       /* Unmask all interrupts. */                                                                            \\r
+       ulStatus = _CP0_GET_STATUS();                                                                           \\r
+       ulStatus &= ~portALL_IPL_BITS;                                                                          \\r
+       _CP0_SET_STATUS( ulStatus );                                                                            \\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -138,7 +144,7 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
 \r
 #define portYIELD()                                                            \\r
 {                                                                                              \\r
 \r
 #define portYIELD()                                                            \\r
 {                                                                                              \\r
-unsigned portLONG ulStatus;                                            \\r
+unsigned long ulStatus;                                                        \\r
                                                                                                \\r
        /* Trigger software interrupt. */                       \\r
        ulStatus = _CP0_GET_CAUSE();                            \\r
                                                                                                \\r
        /* Trigger software interrupt. */                       \\r
        ulStatus = _CP0_GET_CAUSE();                            \\r