Known issues with vTaskDelay() on Win32?

alangillespie wrote on Friday, November 09, 2018:

I wondered if there are any known issues with vTaskDelay() on Win32.

I’ve been trying to use the function in a simple system containing a single task that calls this function in an infinite loop, and it causes permanent suspension of the scheduler via uxSchedulerSuspended in tasks.c, which is set non-zero in vTaskSuspendAll() and never changed thereafter.

The task function is simply for (;:wink: vTaskDelay(pdMS_TO_TICKS(1000));, which I had expected to wake up every second or so, but it never does.

I tried what is effectively the same thing using a repeating 1 second timer which notifies the task from its expiry callback, and everything works as expected.

Am I abusing vTaskDelay() here, or is there an issue?

Thanks,
–Alan Gillespie

rtel wrote on Friday, November 09, 2018:

The code you show should work fine. The Windows port is used
extensively during develop and test. Although note on Windows you will
not get accurate or consistent timing as it is not real-time.

Is there anything unusual about your system? Does your Windows machine
have more than one core (the simulator in newer versions of FreeRTOS
assume that to be the case). Have you modified the code in any way at
all, even if you think it is in a way that doesn’t matter? Are you
making any Windows system calls or trying to communicate with Windows
threads that were not created with xTaskCreate() or xTaskCreateStatic()?

alangillespie wrote on Monday, November 12, 2018:

Thanks for replying Richard. Like you, I’m hoping to use Windows as a development platform, so timing accuracy is not a problem. The version I mentioned above, using the repeating timer, is easily accurate enough for our purposes.

I am using FreeRTOS 10.1.1 straight out of the box, and built using Visual Studio 2017 with the latest update. It is not modified in any way, and the code is not doing anything apart from starting FreeRTOS with a single (trivial) task.

Is it worth me putting together a minimal solution and posting it here?

alangillespie wrote on Wednesday, November 14, 2018:

I can get the vTaskDelay() version to work by inserting printf() calls into some of the threads to adjust the timing. It can then run for varying lengths of time before eventually stopping.

It looks to me like there is a race condition there somewhere. I’ll keep looking into it and post what I manage to find, although it might take a while because I don’t get much time for this.

rtel wrote on Wednesday, November 14, 2018:

printf() is a Windows system call, all of which have the potential to
crash the execution because it can cause Windows to block a thread that
the FreeRTOS kernel assumes it has complete control over. Are you
making any other Windows system calls in your application?

rtel wrote on Wednesday, November 14, 2018:

I just tried the following in the head revision from SVN (should be the
same as the last release with respect to this test). I found ten
seconds worth of ‘simulated’ time was about 15 seconds of real time -
but that is expected and all else was fine:

volatile uint32_t ul = 0;

void vDummyTask( void *pvParameters )
{
     for( ;; )
     {
         vTaskDelay( 100 );
         ul++;
     }
}

alangillespie wrote on Thursday, November 15, 2018:

I’m well aware of what printf() does. Perhaps I should make it clear that I get exactly the same result if I use an empty for loop {for (int i = 0; i < xxxx; ++i) ;} to generate the delay. That means there are no Windows calls at all, other than those made by FreeRTOS itself.

My very first attempt, as I described in my first post, was exactly the same as your dummy task, but in my case vTaskDelay() never returns. Changing nothing, except inserting strategic delays, causes it to burst into life.

As I said above I haven’t had much time to look into this so I don’t yet know why. I’m not expecting you to fix something you can’t reproduce, but I would certainly appreciate any pointers you can give.