From 6322b3a034f97d80ddf57699efd5a800569306ab Mon Sep 17 00:00:00 2001 From: richardbarry Date: Tue, 5 Apr 2011 09:45:42 +0000 Subject: [PATCH] Ensure that the configMAX_SYSCALL_INTERRUPT_PRIORITY setting works with all possible values. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1342 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/portable/MPLAB/PIC32MX/port.c | 8 +++- Source/portable/MPLAB/PIC32MX/port_asm.S | 9 +++-- Source/portable/MPLAB/PIC32MX/portmacro.h | 46 +++++++++++++---------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Source/portable/MPLAB/PIC32MX/port.c b/Source/portable/MPLAB/PIC32MX/port.c index ed860b2b7..cdff10a69 100644 --- a/Source/portable/MPLAB/PIC32MX/port.c +++ b/Source/portable/MPLAB/PIC32MX/port.c @@ -204,7 +204,13 @@ unsigned portBASE_TYPE uxSavedStatusRegister; asm volatile ( "di" ); uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01; - _CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); + /* This clears the IPL bits, then sets them to + configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called + from an interrupt that has a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY so, when used correctly, the action + can only result in the IPL being unchanged or raised, and therefore never + lowered. */ + _CP0_SET_STATUS( ( ( uxSavedStatusRegister & ( ~portALL_IPL_BITS ) ) ) | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ); return uxSavedStatusRegister; } diff --git a/Source/portable/MPLAB/PIC32MX/port_asm.S b/Source/portable/MPLAB/PIC32MX/port_asm.S index fd91d8df7..3ee756c59 100644 --- a/Source/portable/MPLAB/PIC32MX/port_asm.S +++ b/Source/portable/MPLAB/PIC32MX/port_asm.S @@ -195,11 +195,14 @@ vPortYieldISR: lw s7, (s7) sw s5, (s7) - /* Set the interrupt mask to the max priority that can use the API. */ + /* Set the interrupt mask to the max priority that can use the API. The + yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which + is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever + raise the IPL value and never lower it. */ di mfc0 s7, _CP0_STATUS - ori s7, s7, 1 - ori s6, s7, configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 + ins s7, $0, 10, 6 + ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1 /* This mtc0 re-enables interrupts, but only above configMAX_SYSCALL_INTERRUPT_PRIORITY. */ diff --git a/Source/portable/MPLAB/PIC32MX/portmacro.h b/Source/portable/MPLAB/PIC32MX/portmacro.h index 004cb9970..cdebe6cef 100644 --- a/Source/portable/MPLAB/PIC32MX/portmacro.h +++ b/Source/portable/MPLAB/PIC32MX/portmacro.h @@ -84,7 +84,7 @@ extern "C" { typedef unsigned portSHORT portTickType; #define portMAX_DELAY ( portTickType ) 0xffff #else - typedef unsigned portLONG portTickType; + typedef unsigned long portTickType; #define portMAX_DELAY ( portTickType ) 0xffffffff #endif /*-----------------------------------------------------------*/ @@ -96,28 +96,34 @@ extern "C" { /*-----------------------------------------------------------*/ /* Critical section management. */ -#define portIPL_SHIFT ( 10 ) -#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT ) +#define portIPL_SHIFT ( 10UL ) +#define portALL_IPL_BITS ( 0x3fUL << portIPL_SHIFT ) #define portSW0_BIT ( 0x01 << 8 ) -#define portDISABLE_INTERRUPTS() \ -{ \ -unsigned portLONG ulStatus; \ - \ - /* Mask interrupts at and below the kernel interrupt priority. */ \ - ulStatus = _CP0_GET_STATUS(); \ - ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ); \ - _CP0_SET_STATUS( ulStatus ); \ +/* This clears the IPL bits, then sets them to +configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called +from an interrupt, so therefore will not be called with an IPL setting +above configMAX_SYSCALL_INTERRUPT_PRIORITY. Therefore, when used correctly, the +instructions in this macro can only result in the IPL being raised, and +therefore never lowered. */ +#define portDISABLE_INTERRUPTS() \ +{ \ +unsigned long ulStatus; \ + \ + /* Mask interrupts at and below the kernel interrupt priority. */ \ + ulStatus = _CP0_GET_STATUS(); \ + ulStatus &= ~portALL_IPL_BITS; \ + _CP0_SET_STATUS( ( ulStatus | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); \ } -#define portENABLE_INTERRUPTS() \ -{ \ -unsigned portLONG ulStatus; \ - \ - /* Unmask all interrupts. */ \ - ulStatus = _CP0_GET_STATUS(); \ - ulStatus &= ~portALL_IPL_BITS; \ - _CP0_SET_STATUS( ulStatus ); \ +#define portENABLE_INTERRUPTS() \ +{ \ +unsigned long ulStatus; \ + \ + /* Unmask all interrupts. */ \ + ulStatus = _CP0_GET_STATUS(); \ + ulStatus &= ~portALL_IPL_BITS; \ + _CP0_SET_STATUS( ulStatus ); \ } @@ -138,7 +144,7 @@ extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE ); #define portYIELD() \ { \ -unsigned portLONG ulStatus; \ +unsigned long ulStatus; \ \ /* Trigger software interrupt. */ \ ulStatus = _CP0_GET_CAUSE(); \ -- 2.39.5