xEventGroupWaitBits premature timeout cause?

Running FreeRTOS Kernel V10.0.1 port for NXP’s RT1052:

I have a task set to wait on xEventGroupWaitBits and occasionally, I get a timeout triggered at way less than the time I was expecting.

In the below code - I occassionally see the first wait for as_event_group exit in maybe 1 or 2 seconds instead of 9.5 seconds (and event_bits = 0x000000), so I didn’t get any bits set.


  TickType_t timeout = 9500 / portTICK_PERIOD_MS;
  const EventBits_t mask = 0x03;
  BaseType_t clear_all = pdTRUE;
  BaseType_t wait_all = pdFALSE; 

  while(1){
    event_bits = xEventGroupWaitBits(trigger_group, trig_mask, clear_all, wait_all, portMAX_DELAY);
    //do some setup stuff from trigger

   sensor_scan(1);
    event_bits = xEventGroupWaitBits(as_event_group, mask, clear_all, wait_all, timeout);
    if ((event_bits & 0x01) != 0x01){
      sensor_cancel();
      xEventGroupClearBits(as_event_group, 0x03);
      continue;
    }

   sensor_scan(2);
    event_bits = xEventGroupWaitBits(as_event_group, mask, clear_all, wait_all, timeout);
    if ((event_bits & 0x01) != 0x01){
      sensor_cancel();
      xEventGroupClearBits(as_event_group, 0x03);
      continue;
    }


  }

This is the only task listening for as_event_group, and there is only 1 task that will trigger as_event_group.

The sys tick stuff is set up similar to how clock is set up in the NXP power mode switch demo, copied to github here: https://github.com/andrewrt/rt1052-power_mode_switch_ca/

It looks like you are using tickless idle, but not the implementation in the official FreeRTOS port. I suspect it has some bugs.

Can you disable tickless and see if the problem goes away?

1 Like

Since turning off tickless idle - I haven’t been able to reproduce.

The tickless idle implementation from that demo is the prescribed method given by NXP for low power), so I was hoping this wasn’t the problem…

When you say this isn’t the implementation in the official FreeRTOS port - are you talking about the app side implementation (including their GPT config, configPRE_SLEEP_PROCESSING, not having a custom version of vPortSetupTimerInterrupt, etc)?

Or something in the actual FreeRTOS source was changed?

When I said the tickless implementation didn’t look like the official implementation, I was talking about the app side. I saw a function in lpm.c called LPM_InitTicklessTimer( ) and some parameters related to custom tickless in FreeRTOSConfig.h, so I made an assumption without investigating further. So I was suspecting some kind of error on the app side of the tickless implementation.

However, I just now noticed you are using the “slow” SysTick frequency – 100kHz. It is possible that this configuration is exposing a weakness on the FreeRTOS side (not the app side). Can you re-enable tickless, delete the definition of configSYSTICK_CLOCK_HZ in FreeRTOSConfig.h, and try again? What I’m hoping for is SysTick to use the core clock not the 100kHz clock. (FreeRTOS will automatically configure the SysTick accordingly.)

1 Like

Hi @jefftenney,

I commented out configSYSTICK_CLOCK_HZ and haven’t been able to reproduce as well.
But the odd thing is - this timeout bug is somewhat recent (i only noticed it after I added some benign code AFTER the last xEventGroupWaitBits() - referring to the code snippet above. So if i comment out that code (Which is just a function call to check a number, and always returns NULL) the premature timeouts stop as well…

Anyhow - with your suggestion of sticking w/ the system clock - so far I’m not seeing the early timeouts yet.

I’ll keep testing and re-confirm as the problem doesn’t appear consistently.

With this code update, the tick time is much faster - so burns power more in that case. Can you clarify what this change does aside from letting freeRTOS use the sys clock? How could this affect the wait bits timeout issue? In both cases (custom freq vs sysclock) FreeRTOS has to calculate ticks -> ms, right?

Whether you define configSYSTICK_CLOCK_HZ or not, the tick rate will be the same. It’s set by configTICK_RATE_HZ. If you are seeing the tick rate change, something is wrong.

When you don’t define configSYSTICK_CLOCK_HZ, FreeRTOS configures the SysTick to run on the core clock (say for example 100MHz) and configures the target tick rate (say for example 1000Hz) by setting the reload register (to 100000-1 in this case).

But when you define configSYSTICK_CLOCK_HZ, FreeRTOS configures the SysTick to use the “other” clock (in your case, its 100kHz), and configures target tick rate by setting the reload register (to 100-1 in this case).

So either way, you should have the proper tick rate.

I believe there is a FreeRTOS issue for Cortex M when SysTick uses the “other” clock and the other clock is slow (like yours). It can accidentally fast-forward the tick count by the entire expected idle time if an interrupt happens at exactly the wrong time when the CPU is going to sleep (or has just barely gone to sleep, or the app side of the tickless implementation selects a sleep mode that stops the SysTick). So it wouldn’t be surprising at all if small, unrelated code changes cause the issue to appear and disappear.

The only thing you give up by using the core clock for SysTick instead of the 100kHz clock is that you reduce the amount of time that can be spent in one pass of tickless sleep. FreeRTOS will just execute multiple passes of tickless sleep as needed.

1 Like

got it, thanks @jefftenney!

Glad to help, and glad the workaround is working for you.

A proposed fix on the FreeRTOS side is in this PR. It fixes tickless idle for “slow” SysTick clock rates.

1 Like