From 026e98eab8d5358fa76ce6ec69462e0a2e52b922 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 18 May 2008 17:28:30 +0000 Subject: [PATCH] Update to use the kernel critical nesting. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@356 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/portable/MPLAB/PIC32MX/ISR_Support.h | 12 ----- Source/portable/MPLAB/PIC32MX/port.c | 58 ++++----------------- Source/portable/MPLAB/PIC32MX/port_asm.S | 30 ++--------- Source/portable/MPLAB/PIC32MX/portmacro.h | 46 +++++++++++----- 4 files changed, 50 insertions(+), 96 deletions(-) diff --git a/Source/portable/MPLAB/PIC32MX/ISR_Support.h b/Source/portable/MPLAB/PIC32MX/ISR_Support.h index 757b1ba4e..433c7a620 100644 --- a/Source/portable/MPLAB/PIC32MX/ISR_Support.h +++ b/Source/portable/MPLAB/PIC32MX/ISR_Support.h @@ -131,11 +131,6 @@ mflo s6 sw s6, 8(s5) - /* Each task maintains its own nesting count. */ - la s6, uxCriticalNesting - lw s6, (s6) - sw s6, 4(s5) - /* Update the task stack pointer value if nesting is zero. */ la s6, uxInterruptNesting lw s6, (s6) @@ -199,13 +194,6 @@ addiu k1, k1, -1 sw k1, 0(k0) - /* Restore the critical nesting count. */ - la k0, uxCriticalNesting - lw k1, 4(s5) - sw k1, (k0) - - /* If the critical nesting is not zero then set status as if within - a critical section. */ lw k0, portSTATUS_STACK_LOCATION(s5) lw k1, portEPC_STACK_LOCATION(s5) diff --git a/Source/portable/MPLAB/PIC32MX/port.c b/Source/portable/MPLAB/PIC32MX/port.c index 8ab29fc68..e170709b5 100644 --- a/Source/portable/MPLAB/PIC32MX/port.c +++ b/Source/portable/MPLAB/PIC32MX/port.c @@ -62,24 +62,15 @@ #define portIE_BIT ( 0x00000001 ) #define portEXL_BIT ( 0x00000002 ) #define portSW0_ENABLE ( 0x00000100 ) -#define portIPL_SHIFT ( 10 ) -#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT ) /* The EXL bit is set to ensure interrupts do not occur while the context of the first task is being restored. */ #define portINITIAL_SR ( portIE_BIT | portEXL_BIT | portSW0_ENABLE ) -/* Records the nesting depth of calls to portENTER_CRITICAL(). */ -unsigned portBASE_TYPE uxCriticalNesting = 0x55555555; - /* Records the interrupt nesting depth. This starts at one as it will be decremented to 0 when the first task starts. */ volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01; -/* Used to store the original interrupt mask when the mask level is temporarily -raised during an ISR. */ -volatile unsigned portBASE_TYPE uxSavedStatusRegister = 0; - /* Stores the task stack pointer when a switch is made to use the system stack. */ unsigned portBASE_TYPE uxSavedTaskStackPointer = 0; @@ -126,7 +117,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE *pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */ pxTopOfStack -= 14; - *pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level */ + *pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level - no longer used. */ pxTopOfStack--; return pxTopOfStack; @@ -154,39 +145,6 @@ void vPortEndScheduler(void) } /*-----------------------------------------------------------*/ -void vPortEnterCritical(void) -{ -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 ); - - /* Once interrupts are disabled we can access the nesting count directly. */ - uxCriticalNesting++; -} -/*-----------------------------------------------------------*/ - -void vPortExitCritical(void) -{ -unsigned portLONG ulStatus; - - /* If we are in a critical section then we can access the nesting count - directly. */ - uxCriticalNesting--; - - /* Has the nesting unwound? */ - if( uxCriticalNesting == 0 ) - { - /* Unmask all interrupts. */ - ulStatus = _CP0_GET_STATUS(); - ulStatus &= ~portALL_IPL_BITS; - _CP0_SET_STATUS( ulStatus ); - } -} -/*-----------------------------------------------------------*/ - portBASE_TYPE xPortStartScheduler( void ) { extern void vPortStartFirstTask( void ); @@ -224,9 +182,11 @@ unsigned portLONG ulStatus; void vPortIncrementTick( void ) { - vPortSetInterruptMaskFromISR(); +unsigned portBASE_TYPE uxSavedStatus; + + uxSavedStatus = uxPortSetInterruptMaskFromISR(); vTaskIncrementTick(); - vPortClearInterruptMaskFromISR(); + vPortClearInterruptMaskFromISR( uxSavedStatus ); /* If we are using the preemptive scheduler then we might want to select a different task to execute. */ @@ -239,15 +199,19 @@ void vPortIncrementTick( void ) } /*-----------------------------------------------------------*/ -void vPortSetInterruptMaskFromISR( void ) +unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void ) { +unsigned portBASE_TYPE uxSavedStatusRegister; + asm volatile ( "di" ); uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01; _CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); + + return uxSavedStatusRegister; } /*-----------------------------------------------------------*/ -void vPortClearInterruptMaskFromISR( void ) +void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusRegister ) { _CP0_SET_STATUS( uxSavedStatusRegister ); } diff --git a/Source/portable/MPLAB/PIC32MX/port_asm.S b/Source/portable/MPLAB/PIC32MX/port_asm.S index a1b26f8f8..0a02935d5 100644 --- a/Source/portable/MPLAB/PIC32MX/port_asm.S +++ b/Source/portable/MPLAB/PIC32MX/port_asm.S @@ -57,7 +57,6 @@ .set noreorder .extern pxCurrentTCB - .extern uxCriticalNesting .extern vTaskSwitchContext .extern vPortIncrementTick .extern xISRStackTop @@ -189,11 +188,6 @@ vPortYieldISR: mflo s7 sw s7, 8(s5) - /* Each task maintains its own nesting count. */ - la s7, uxCriticalNesting - lw s7, (s7) - sw s7, 4(s5) - /* Save the stack pointer to the task. */ la s7, pxCurrentTCB lw s7, (s7) @@ -276,33 +270,19 @@ vPortYieldISR: /* Switch back to use the real stack pointer. */ add sp, zero, s5 - /* Restore the critical nesting depth. */ - la s5, uxCriticalNesting - lw k0, 4(sp) - sw k0, (s5) + /* Restore the real s5 value. */ + lw s5, 40(sp) /* If the critical nesting is not zero and a yield is not pended then set status as if within a critical section. */ - lw s5, portSTATUS_STACK_LOCATION(sp) - beq k0, zero, .+28 - nop - mfc0 k1, _CP0_CAUSE - andi k1, k1, 256 - bne k1, zero, .+12 - nop - or s5, s5, (configMAX_SYSCALL_INTERRUPT_PRIORITY<<10) - + lw k1, portSTATUS_STACK_LOCATION(sp) lw k0, portEPC_STACK_LOCATION(sp) - mtc0 s5, _CP0_STATUS - ehb - - /* Restore the real s5 value. */ - lw s5, 40(sp) - /* Remove stack frame. */ addiu sp, sp, portCONTEXT_SIZE + mtc0 k1, _CP0_STATUS + ehb mtc0 k0, _CP0_EPC eret nop diff --git a/Source/portable/MPLAB/PIC32MX/portmacro.h b/Source/portable/MPLAB/PIC32MX/portmacro.h index 1c22d5104..cb5911b3f 100644 --- a/Source/portable/MPLAB/PIC32MX/portmacro.h +++ b/Source/portable/MPLAB/PIC32MX/portmacro.h @@ -92,18 +92,40 @@ extern "C" { /*-----------------------------------------------------------*/ /* Critical section management. */ -#define portDISABLE_INTERRUPTS() INTDisableInterrupts() -#define portENABLE_INTERRUPTS() INTEnableInterrupts() - -extern void vPortEnterCritical( void ); -extern void vPortExitCritical( void ); -#define portENTER_CRITICAL() vPortEnterCritical() -#define portEXIT_CRITICAL() vPortExitCritical() - -extern void vPortSetInterruptMaskFromISR(); -extern void vPortClearInterruptMaskFromISR(); -#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMaskFromISR() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR() vPortClearInterruptMaskFromISR() +#define portIPL_SHIFT ( 10 ) +#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT ) + +#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 ); \ +} + +#define portENABLE_INTERRUPTS() \ +{ \ +unsigned portLONG ulStatus; \ + \ + /* Unmask all interrupts. */ \ + ulStatus = _CP0_GET_STATUS(); \ + ulStatus &= ~portALL_IPL_BITS; \ + _CP0_SET_STATUS( ulStatus ); \ +} + + +extern void vTaskEnterCritical( void ); +extern void vTaskExitCritical( void ); +#define portCRITICAL_NESTING_IN_TCB 1 +#define portENTER_CRITICAL() vTaskEnterCritical() +#define portEXIT_CRITICAL() vTaskExitCritical() + +extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR(); +extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE ); +#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) vPortClearInterruptMaskFromISR( uxSavedStatusRegister ) /*-----------------------------------------------------------*/ -- 2.39.5