CODE
void wait_ms(unsigned long ms)
{
unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
while (_rdtsc() < t2);
}
/*-----------------------------------------------------------*/
static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;
/* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
{
xMinimumWindowsBlockTime = ( TickType_t ) xTimeCaps.wPeriodMin;
timeBeginPeriod( xTimeCaps.wPeriodMin );
/* Register an exit handler so the timeBeginPeriod() function can be
matched with a timeEndPeriod() when the application exits. */
SetConsoleCtrlHandler( prvEndProcess, TRUE );
}
else
{
xMinimumWindowsBlockTime = ( TickType_t ) 20;
}
/* Just to prevent compiler warnings. */
( void ) lpParameter;
//Sleep(1);
for( ;; )
{
/* Wait until the timer expires and we can access the simulated interrupt
variables. *NOTE* this is not a 'real time' way of generating tick
events as the next wake time should be relative to the previous wake
time, not the time that Sleep() is called. It is done this way to
prevent overruns in this very non real time simulated/emulated
environment. */
/*if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
{
Sleep( xMinimumWindowsBlockTime );
}
else
{
Sleep( portTICK_PERIOD_MS );
}*/
wait_ms(portTICK_PERIOD_MS);
configASSERT( xPortRunning );
WaitForSingleObject( pvInterruptEventMutex, INFINITE );
/* The timer has expired, generate the simulated tick event. */
ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );
/* The interrupt is now pending - notify the simulated interrupt
handler thread. */
if( ulCriticalNesting == 0 )
{
SetEvent( pvInterruptEvent );
}
/* Give back the mutex so the simulated interrupt handler unblocks
and can access the interrupt handler variables. */
ReleaseMutex( pvInterruptEventMutex );
}
#ifdef __GNUC__
/* Should never reach here - MingW complains if you leave this line out,
MSVC complains if you put it in. */
return 0;
#endif
}
{
unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
while (_rdtsc() < t2);
}
/*-----------------------------------------------------------*/
static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;
/* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
{
xMinimumWindowsBlockTime = ( TickType_t ) xTimeCaps.wPeriodMin;
timeBeginPeriod( xTimeCaps.wPeriodMin );
/* Register an exit handler so the timeBeginPeriod() function can be
matched with a timeEndPeriod() when the application exits. */
SetConsoleCtrlHandler( prvEndProcess, TRUE );
}
else
{
xMinimumWindowsBlockTime = ( TickType_t ) 20;
}
/* Just to prevent compiler warnings. */
( void ) lpParameter;
//Sleep(1);
for( ;; )
{
/* Wait until the timer expires and we can access the simulated interrupt
variables. *NOTE* this is not a 'real time' way of generating tick
events as the next wake time should be relative to the previous wake
time, not the time that Sleep() is called. It is done this way to
prevent overruns in this very non real time simulated/emulated
environment. */
/*if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
{
Sleep( xMinimumWindowsBlockTime );
}
else
{
Sleep( portTICK_PERIOD_MS );
}*/
wait_ms(portTICK_PERIOD_MS);
configASSERT( xPortRunning );
WaitForSingleObject( pvInterruptEventMutex, INFINITE );
/* The timer has expired, generate the simulated tick event. */
ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );
/* The interrupt is now pending - notify the simulated interrupt
handler thread. */
if( ulCriticalNesting == 0 )
{
SetEvent( pvInterruptEvent );
}
/* Give back the mutex so the simulated interrupt handler unblocks
and can access the interrupt handler variables. */
ReleaseMutex( pvInterruptEventMutex );
}
#ifdef __GNUC__
/* Should never reach here - MingW complains if you leave this line out,
MSVC complains if you put it in. */
return 0;
#endif
}
Программа зависает намертво. Причем если в wait_ms добавить Sleep, то начинает работать. Или хотя бы закомментированный Sleep перед for(;;) раскомментировать, то один раз выводится Task 1 is running. И тоже зависает. Как починить?