diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index 28668de14..c2ebf24c3 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -257,6 +257,10 @@ hold explicit before calling the code. */ #define portMEMORY_BARRIER() #endif +#ifndef portSOFTWARE_BARRIER + #define portSOFTWARE_BARRIER() +#endif + /* The timers module relies on xTaskGetSchedulerState(). */ #if configUSE_TIMERS == 1 diff --git a/FreeRTOS/Source/portable/MSVC-MingW/port.c b/FreeRTOS/Source/portable/MSVC-MingW/port.c index 396633123..3c685b925 100644 --- a/FreeRTOS/Source/portable/MSVC-MingW/port.c +++ b/FreeRTOS/Source/portable/MSVC-MingW/port.c @@ -75,7 +75,7 @@ static uint32_t prvProcessTickInterrupt( void ); * attempt to obtain pvInterruptEventMutex if a critical section is used inside * an interrupt handler itself. */ -static volatile BaseType_t xInsideInterrupt = pdFALSE; +volatile BaseType_t xInsideInterrupt = pdFALSE; /* * Called when the process exits to let Windows know the high timer resolution @@ -394,7 +394,7 @@ CONTEXT xContext; xInsideInterrupt = pdFALSE; WaitForMultipleObjects( sizeof( pvObjectList ) / sizeof( void * ), pvObjectList, TRUE, INFINITE ); - /* /* Cannot be in a critical section to get here. Tasks that exist a + /* Cannot be in a critical section to get here. Tasks that exist a critical section will block on a yield mutex to wait for an interrupt to process if an interrupt was set pending while the task was inside the critical section. xInsideInterrupt prevents interrupts that contain diff --git a/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h b/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h index 5f5412810..51b96f2fc 100644 --- a/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h +++ b/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h @@ -74,6 +74,11 @@ typedef unsigned long UBaseType_t; #define portYIELD() vPortGenerateSimulatedInterrupt( portINTERRUPT_YIELD ) + +extern volatile BaseType_t xInsideInterrupt; +#define portSOFTWARE_BARRIER() while( xInsideInterrupt != pdFALSE ) + + /* Simulated interrupts return pdFALSE if no context switch should be performed, or a non-zero number if a context switch should be performed. */ #define portYIELD_FROM_ISR( x ) ( void ) x diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c index 5129bf981..20044337e 100644 --- a/FreeRTOS/Source/tasks.c +++ b/FreeRTOS/Source/tasks.c @@ -2113,7 +2113,17 @@ void vTaskSuspendAll( void ) BaseType_t. Please read Richard Barry's reply in the following link to a post in the FreeRTOS support forum before reporting this as a bug! - http://goo.gl/wu4acr */ + + /* portSOFRWARE_BARRIER() is only implemented for emulated/simulated ports that + do not otherwise exhibit real time behaviour. */ + portSOFTWARE_BARRIER(); + + /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment + is used to allow calls to vTaskSuspendAll() to nest. */ ++uxSchedulerSuspended; + + /* Enforces ordering for ports and optimised compilers that may otherwise place + the above increment elsewhere. */ portMEMORY_BARRIER(); } /*----------------------------------------------------------*/