/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
FreeRTOS is free software; you can redistribute it and/or modify it under\r
the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+ Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
\r
***************************************************************************\r
>>! NOTE: The modification to the GPL is included to allow you to !<<\r
#define portMAX_INTERRUPTS ( ( uint32_t ) sizeof( uint32_t ) * 8UL ) /* The number of bits in an uint32_t. */\r
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )\r
\r
+/* The priorities at which the various components of the simulation execute.\r
+Priorities are higher when a soak test is performed to lessen the effect of\r
+Windows interfering with the timing. */\r
+#define portSOAK_TEST\r
+#ifndef portSOAK_TEST\r
+ #define portSIMULATED_INTERRUPTS_THREAD_PRIORITY THREAD_PRIORITY_NORMAL\r
+ #define portSIMULATED_TIMER_THREAD_PRIORITY THREAD_PRIORITY_BELOW_NORMAL\r
+ #define portTASK_THREAD_PRIORITY THREAD_PRIORITY_IDLE\r
+#else\r
+ #define portSIMULATED_INTERRUPTS_THREAD_PRIORITY THREAD_PRIORITY_TIME_CRITICAL\r
+ #define portSIMULATED_TIMER_THREAD_PRIORITY THREAD_PRIORITY_HIGHEST\r
+ #define portTASK_THREAD_PRIORITY THREAD_PRIORITY_ABOVE_NORMAL\r
+#endif\r
/*\r
* Created as a high priority thread, this function uses a timer to simulate\r
* a tick interrupt being generated on an embedded target. In this Windows\r
configASSERT( pxThreadState->pvThread );\r
SetThreadAffinityMask( pxThreadState->pvThread, 0x01 );\r
SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );\r
- SetThreadPriority( pxThreadState->pvThread, THREAD_PRIORITY_IDLE );\r
+ SetThreadPriority( pxThreadState->pvThread, portTASK_THREAD_PRIORITY );\r
\r
return ( StackType_t * ) pxThreadState;\r
}\r
\r
if( lSuccess == pdPASS )\r
{\r
- if( SetThreadPriority( pvHandle, THREAD_PRIORITY_NORMAL ) == 0 )\r
+ if( SetThreadPriority( pvHandle, portSIMULATED_INTERRUPTS_THREAD_PRIORITY ) == 0 )\r
{\r
lSuccess = pdFAIL;\r
}\r
pvHandle = CreateThread( NULL, 0, prvSimulatedPeripheralTimer, NULL, CREATE_SUSPENDED, NULL );\r
if( pvHandle != NULL )\r
{\r
- SetThreadPriority( pvHandle, THREAD_PRIORITY_BELOW_NORMAL );\r
+ SetThreadPriority( pvHandle, portSIMULATED_TIMER_THREAD_PRIORITY );\r
SetThreadPriorityBoost( pvHandle, TRUE );\r
SetThreadAffinityMask( pvHandle, 0x01 );\r
ResumeThread( pvHandle );\r
uint32_t ulSwitchRequired, i;\r
xThreadState *pxThreadState;\r
void *pvObjectList[ 2 ];\r
+CONTEXT xContext;\r
\r
/* Going to block on the mutex that ensured exclusive access to the simulated\r
interrupt objects, and the event that signals that a simulated interrupt\r
pxThreadState = ( xThreadState *) *( ( size_t * ) pvOldCurrentTCB );\r
SuspendThread( pxThreadState->pvThread );\r
\r
+ /* Ensure the thread is actually suspended by performing a\r
+ synchronous operation that can only complete when the thread is\r
+ actually suspended. The below code asks for dummy register\r
+ data. */\r
+ xContext.ContextFlags = CONTEXT_INTEGER;\r
+ ( void ) GetThreadContext( pxThreadState->pvThread, &xContext );\r
+\r
/* Obtain the state of the task now selected to enter the\r
Running state. */\r
pxThreadState = ( xThreadState * ) ( *( size_t *) pxCurrentTCB );\r
does not run and swap it out before it is closed. If that were to happen\r
the thread would never run again and effectively be a thread handle and\r
memory leak. */\r
- SetThreadPriority( pvThread, THREAD_PRIORITY_ABOVE_NORMAL );\r
+ SetThreadPriority( pvThread, THREAD_PRIORITY_HIGHEST );\r
\r
/* This function will not return, therefore a yield is set as pending to\r
ensure a context switch occurs away from this thread on the next tick. */\r
\r
if( ( ulInterruptNumber < portMAX_INTERRUPTS ) && ( pvInterruptEventMutex != NULL ) )\r
{\r
- /* Yield interrupts are processed even when critical nesting is non-zero. */\r
+ /* Yield interrupts are processed even when critical nesting is\r
+ non-zero. */\r
WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
ulPendingInterrupts |= ( 1 << ulInterruptNumber );\r
\r
- /* The simulated interrupt is now held pending, but don't actually process it\r
- yet if this call is within a critical section. It is possible for this to\r
- be in a critical section as calls to wait for mutexes are accumulative. */\r
+ /* The simulated interrupt is now held pending, but don't actually\r
+ process it yet if this call is within a critical section. It is\r
+ possible for this to be in a critical section as calls to wait for\r
+ mutexes are accumulative. */\r
if( ulCriticalNesting == 0 )\r
{\r
SetEvent( pvInterruptEvent );\r