/* Pointer to the TCB of the currently executing task. */\r
extern void *pxCurrentTCB;\r
\r
+/* Used to ensure nothing is processed during the startup sequence. */\r
+static portBASE_TYPE xPortRunning = pdFALSE;\r
+\r
/*-----------------------------------------------------------*/\r
\r
static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )\r
Sleep( portTICK_RATE_MS );\r
}\r
\r
+ configASSERT( xPortRunning );\r
+\r
WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
\r
/* The timer has expired, generate the simulated tick event. */\r
\r
/* The interrupt is now pending - notify the simulated interrupt \r
handler thread. */\r
- SetEvent( pvInterruptEvent );\r
+ if( ulCriticalNesting == 0 )\r
+ {\r
+ SetEvent( pvInterruptEvent );\r
+ }\r
\r
/* Give back the mutex so the simulated interrupt handler unblocks \r
and can access the interrupt handler variables. */\r
ulCriticalNesting = portNO_CRITICAL_NESTING;\r
\r
/* Bump up the priority of the thread that is going to run, in the\r
- hope that this will asist in getting the Windows thread scheduler to\r
+ hope that this will assist in getting the Windows thread scheduler to\r
behave as an embedded engineer might expect. */\r
ResumeThread( pxThreadState->pvThread );\r
\r
unsigned long ulSwitchRequired;\r
\r
/* Process the tick itself. */\r
+ configASSERT( xPortRunning );\r
ulSwitchRequired = ( unsigned long ) xTaskIncrementTick();\r
\r
return ulSwitchRequired;\r
pvObjectList[ 0 ] = pvInterruptEventMutex;\r
pvObjectList[ 1 ] = pvInterruptEvent;\r
\r
+ /* Create a pending tick to ensure the first task is started as soon as\r
+ this thread pends. */\r
+ ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );\r
+ SetEvent( pvInterruptEvent );\r
+\r
+ xPortRunning = pdTRUE;\r
+\r
for(;;)\r
{\r
WaitForMultipleObjects( sizeof( pvObjectList ) / sizeof( void * ), pvObjectList, TRUE, INFINITE );\r
\r
void vPortGenerateSimulatedInterrupt( unsigned long ulInterruptNumber )\r
{\r
+ configASSERT( xPortRunning );\r
+\r
if( ( ulInterruptNumber < portMAX_INTERRUPTS ) && ( pvInterruptEventMutex != NULL ) )\r
{\r
/* Yield interrupts are processed even when critical nesting is non-zero. */\r
\r
void vPortEnterCritical( void )\r
{\r
- if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )\r
+ if( xPortRunning == pdTRUE )\r
{\r
/* The interrupt event mutex is held for the entire critical section,\r
effectively disabling (simulated) interrupts. */\r
(simulated) disabled? */\r
if( ulPendingInterrupts != 0UL )\r
{\r
+ configASSERT( xPortRunning );\r
SetEvent( pvInterruptEvent );\r
\r
/* Mutex will be released now, so does not require releasing\r
}\r
}\r
\r
- if( lMutexNeedsReleasing == pdTRUE )\r
+ if( pvInterruptEventMutex != NULL )\r
{\r
- ReleaseMutex( pvInterruptEventMutex );\r
+ if( lMutexNeedsReleasing == pdTRUE )\r
+ {\r
+ configASSERT( xPortRunning );\r
+ ReleaseMutex( pvInterruptEventMutex );\r
+ }\r
}\r
}\r
/*-----------------------------------------------------------*/\r