From d85fd461d9a17811f8d0d8fa11fcebf7fa542ee4 Mon Sep 17 00:00:00 2001 From: Cobus van Eeden <35851496+cobusve@users.noreply.github.com> Date: Thu, 27 Aug 2020 10:12:51 -0700 Subject: [PATCH] Fix inaccurate ticks in windows port (#142) --- portable/MSVC-MingW/port.c | 40 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c index f5e26a98d..81b5f3466 100644 --- a/portable/MSVC-MingW/port.c +++ b/portable/MSVC-MingW/port.c @@ -22,7 +22,6 @@ * https://www.FreeRTOS.org * https://github.com/FreeRTOS * - * 1 tab == 4 spaces! */ /* Standard includes. */ @@ -140,6 +139,9 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) { TickType_t xMinimumWindowsBlockTime; TIMECAPS xTimeCaps; +TickType_t xWaitTimeBetweenTicks = portTICK_PERIOD_MS; +HANDLE hTimer = NULL; +LARGE_INTEGER liDueTime; /* Set the timer resolution to the maximum possible. */ if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR ) @@ -159,22 +161,32 @@ TIMECAPS xTimeCaps; /* Just to prevent compiler warnings. */ ( 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( ;; ) { /* 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 ); - } + variables. */ + WaitForSingleObject( hTimer, INFINITE ); configASSERT( xPortRunning );