FreeRTOS timers may fire earlier than expected when configUSE_TICKLESS_IDLE == 1

Hi all,
I am using FreeRTOS v10.0.1 and I am experiencing some issues with FreeRTOS timers expiring earlier than expected when configUSE_TICKLESS_IDLE == 1.

The problems started occurring when I applied fix in vTaskStepTick() proposed in topic: “Assert in tasks.c: 2611 on xTickCount wrap around” in this forum.
as I was experiencing the same issue with assert on xTickCount wrap around.
Also, applying the second solution proposed in that topic (fix in generic FreeRTOS code) cause the same problem.

I assume that the best solution for me would be fixing the original problem described in this post: “Assert in tasks.c: 2611 on xTickCount wrap around” in a way that does not cause FreeRTOS timers to fire earlier than expected.

The test I performed was setting a single shot timer starting itself for 20ms.
The results was:

  • 19,5ms to 20,5ms for configUSE_TICKLESS_IDLE == 0
  • mostly 19,5ms to 20,5ms, but sometimes 16,5ms, 17,5ms, 18,5ms, 21,5ms, 22,5ms for configUSE_TICKLESS_IDLE == 1
  • mostly 19,5ms to 20,5ms, but sometimes 21,5ms or 22,5ms for configUSE_TICKLESS_IDLE == 1 and reverted fix in vTaskStepTick()

The conclusion is that tickless idle enabled have bigger jitter than disabled, however only in pair with the proposed fix, it causes timers to fire earlier than expected.

So is there any solution that fixes the original problem with assert on xTickCount wrap around that will not cause timers to expire too early?

What processor are you using?

I am using nrf52832 with Softdevice 113 v7.0.1 and SDKv16

Tickless idle is always going to cause some inaccuracies in the timing because you are stopping, reprogramming, and starting clocks - during which time time is still moving forward. I would not expect the amount of variation you are seeing though. There is some variable compensation for this in the default tickless idle implementation, but I’m not sure about Nordic’s version.

Can you rerun your experiments without Nordic’s version of tickless idle? To do this, you would (temporarily) remove Nordic’s version of vPortSetupTimerInterrupt() and vPortSuppressTicksAndSleep(). The official FreeRTOS versions (in port.c) will then take effect. That may help you isolate any bugs in the Nordic code.

Also, Nordic’s devzone forum has several posts about tickless idle and SOFTDEVICE_PRESENT which all relate to Nordic’s custom implementation of tickless idle. They might be helpful as well.

The implementations of vPortSuppressTickAndSleep() and vPortSetupTimerInterrupt() are located in freertos/portable/CMSIS/nrf52, but there are no implementation of those functions in freertos/portable/ARM/nrf52/port.c and when I remove those versions from portable/CMSIS/nrf52, I get “undefined reference to …”

Can you please describe more specifically what exactly should I do to use the official FreeRTOS version instead of Nordic’s version?

And about Nordic’s devzone I already created a post there and I am waiting for the response.

I didn’t realize Nordic had modified the official FreeRTOS port itself. In that case, you might be able to grab those two functions from port.c in the kernel repo for v10.0.1. (That link is for gcc, you may need to go to a sister directory for your compiler.)

When you grab those functions you may also need to grab #define symbols they use. Depending on how much customization Nordic did to their port, this idea might not pan out. In that case, I expect what you would have found is that the Nordic tickless idle has some issues that cause your symptoms. Getting the tickless implementation right can be tricky.

I tried to use those two functions from the given link, but unfortunately, my app crashes at the start.
So it looks like only nordic guys can help me.

Anyway, thanks for the quick response. I will let you know when I manage to solve the problem.