timer adding one millisecond to the expected time on wondows port

haditj66 wrote on Saturday, July 06, 2019:

Im getting unexpected timer delays where the measured time is always one millisecond longer then what is expected. For example when I have

#define configTICK_RATE_HZ						( 1000 )

	xTimer1 = xTimerCreate("clock1",				 
		1,		
		pdTRUE,			
		NULL,				 
		clockTimer1); 

xTimerReset(xTimer1, portMAX_DELAY);

I would expect the timer to have a 1 millisecond delay. instead I measure 2 milli when using std::chrono.
When I have configTICK_RATE_HZ ( 100 )
and rest the same, I would expect a 10 millisecond delay but instead I am measuring 11 milliseconds.

rtel wrote on Saturday, July 06, 2019:

Which port are you using? How is std:chrono implemented?

haditj66 wrote on Saturday, July 06, 2019:

FreeRTOS Kernel V10.2.0
it is the WIN32 port running on visual studio 2015

chrono is implemented as follows within the callback

  bool oddtimer = false;
static void clockTimer1(TimerHandle_t xTimerHandle)
{
    if (!oddtimer)
    {
        std::chrono::high_resolution_clock::time_point bt1 = std::chrono::high_resolution_clock::now();
        oddtimer = !oddtimer;
    }
else
    {
        std::chrono::high_resolution_clock::time_point bt2 = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(bt2 - bt1).count();
        oddtimer = !oddtimer;
    
        printf(duration);
        }
    }

rtel wrote on Sunday, July 07, 2019:

I’m afraid the Win32 port is not going to give you accurate timing as it
is at the mercy of the Windows scheduler as to when the FreeRTOS threads
run. This is documented in the code. You can also view
https://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html

Additionally I note your code is calling printf() - you might get away
with that if it is only called from one thread, or very infrequently,
but as a general rule calling Windows system calls from kernel threads
can cause big issues as it can cause Windows to block the threads
whereas the FreeRTOS kernel assumes only it will block threads (it knows
nothing about the Windows scheduler). In the TCP code, which does a lot
of logging, we get around this by having a Windows thread that is not
under the control of the kernel do the printing - with the kernel’s
threads using a circular RAM buffer to send the strings they want to
print to that single thread.