Fix inaccurate ticks in windows port (#142)

This commit is contained in:
Cobus van Eeden 2020-08-27 10:12:51 -07:00 committed by GitHub
parent 805b15a022
commit d85fd461d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -22,7 +22,6 @@
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
@ -140,6 +139,9 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{ {
TickType_t xMinimumWindowsBlockTime; TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps; TIMECAPS xTimeCaps;
TickType_t xWaitTimeBetweenTicks = portTICK_PERIOD_MS;
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
/* Set the timer resolution to the maximum possible. */ /* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR ) if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
@ -159,22 +161,32 @@ TIMECAPS xTimeCaps;
/* Just to prevent compiler warnings. */ /* Just to prevent compiler warnings. */
( void ) lpParameter; ( void ) lpParameter;
/* Tick time for the timer is adjusted with the maximum available
resolution. */
if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
{
xWaitTimeBetweenTicks = xMinimumWindowsBlockTime;
}
/* Convert the tick time in milliseconds to nanoseconds resolution
for the Waitable Timer. */
liDueTime.u.LowPart = xWaitTimeBetweenTicks * 1000 * 1000;
liDueTime.u.HighPart = 0;
/* Create a synchronization Waitable Timer.*/
hTimer = CreateWaitableTimer( NULL, FALSE, NULL );
configASSERT( hTimer != NULL );
/* Set the Waitable Timer. The timer is set to run periodically at every
xWaitTimeBetweenTicks milliseconds. */
configASSERT( SetWaitableTimer( hTimer, &liDueTime, xWaitTimeBetweenTicks, NULL, NULL, 0 ) );
for( ;; ) for( ;; )
{ {
/* Wait until the timer expires and we can access the simulated interrupt /* Wait until the timer expires and we can access the simulated interrupt
variables. *NOTE* this is not a 'real time' way of generating tick variables. */
events as the next wake time should be relative to the previous wake WaitForSingleObject( hTimer, INFINITE );
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 );
}
configASSERT( xPortRunning ); configASSERT( xPortRunning );