Update PIC32 demo application to remove reliance on PLIB functions. Update the default low power implementation in all the Cortex-M port layers to add a small critical section.
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index 0c8f29c..570e6f9 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
@@ -363,19 +363,28 @@ kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; - /* If a context switch is pending then abandon the low power entry as - the context switch might have been pended by an external interrupt that - requires processing. */ - if( ( portNVIC_INT_CTRL_REG & portNVIC_PENDSVSET_BIT ) != 0 ) + /* Adjust the reload value to take into account that the current + time slice is already partially complete. */ + ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_irq(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); } else { - /* Adjust the reload value to take into account that the current - time slice is already partially complete. */ - ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); + /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to @@ -404,6 +413,10 @@ kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The tick interrupt has already executed, and the SysTick
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 147ebcb..592fc25 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
@@ -426,19 +426,28 @@ kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; - /* If a context switch is pending then abandon the low power entry as - the context switch might have been pended by an external interrupt that - requires processing. */ - if( ( portNVIC_INT_CTRL_REG & portNVIC_PENDSVSET_BIT ) != 0 ) + /* Adjust the reload value to take into account that the current + time slice is already partially complete. */ + ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_irq(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) { /* Restart SysTick. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); } else { - /* Adjust the reload value to take into account that the current - time slice is already partially complete. */ - ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) ); + /* Set the new reload value. */ portNVIC_SYSTICK_LOAD_REG = ulReloadValue; /* Clear the SysTick count flag and set the count value back to @@ -467,6 +476,10 @@ kernel with respect to calendar time. */ portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) { /* The tick interrupt has already executed, and the SysTick