New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FreeRTOS timer callbacks occasionally executed twice (IDFGH-6590) #8234
Comments
Additional info: the effect is also present with SPIRAM disabled (and 64K for cpuload_task to fit in internal RAM), and it's even more frequent when running in single core mode. Regards, |
The effect also affects periodic timers. Extended test project including test results: test-timer-dupecall-2.zip Detection method: there are 5 counting and 1 checkpoint timers, identified by their timer IDs. The counting timers are set to run every 1,2,3,4,5 ticks. The checkpoint timer is set to run every 120 ticks, it subtracts the expected counts and checks for remaining offsets. Due to shuffling of the internal timer execution list, the counters can have a small offset on one checkpoint which will be equalized on the next. These get logged as warnings. If an offset appears to be stable, an error log line is written. The checkpoint logs show the long term evolution of the offsets. Offsets should long term always return to zero if all timers are executed exactly as often as they should. If they execute more often than expected, offsets will accumulate to positive values, if less often to negative. The test run shows these stabilized checkpoints:
Conclusions:
Regards, |
(ref: espressif/esp-idf#8234) Note: this scheme allows for callback processing delays of up to 3 ticks, it will fail to detect duplicate callbacks for timers with shorter periods -- if necessary, use another scheme there.
Hi @dexterbg Thanks for the report and sharing a very simple sample application that exhibits the problem void app_task(void *userdata)
{
...
while (xTimerChangePeriod(timer, 1, portMAX_DELAY) != pdPASS); // [1]
vTimerSetTimerID(timer, (void *) tid); // [2]
while (xTimerStart(timer, portMAX_DELAY) != pdPASS); // [3]
...
} I wonder why you keep changing the timer period esp-idf/components/freertos/include/freertos/timers.h Lines 622 to 623 in 8153bfe
esp-idf/components/freertos/timers.c Lines 879 to 892 in 8153bfe
|
Hi David, I seem to never have noticed that Any idea on why the cyclic timers also seem to get an occasional extra callback? Note we have no conclusive evidence for this happening in our main application, only some occasional effects that may be caused by this -- or by something else. So there may be something wrong with my test design here. Thanks & regards, |
Att: xTimerChangePeriod() not only changes the period, it also starts a dormant (stopped) timer. So the timer was actually already running (and the callback could be executed) before the payload was assigned. Ref: espressif/esp-idf#8234 (comment)
Hi Michael, Sorry for the late reply, no idea about those extra callback of periodic timers. I think it might be tricky to (dis)prove the duplicated callbacks of a cyclic timer. I would perhaps try to match timer's callback occurrences with kernel ticks? |
@dexterbg Apologies for getting to this issues so late!
Perhaps you could try it out again on the latest |
@sudeep-mohanty Thanks for investigating this. I'll try v4.4 ASAP, but your quoted log's runtime was a magnitude too short for the effect to occur. On my test runs, the first stable offset never occurred before about an hour runtime, with sometimes some hours between two offset jumps. |
@dexterbg I redid the experiment for a (much) longer duration of about ~ 4 hrs and I still did not observe the timer callback being called more than once. Did you get a chance to test it at your end?
|
@dexterbg PS. please always use "git describe --tags" for IDF versions when report issues. |
I can confirm to also not be able to reproduce this with the current v4.4 release & toolchain.
I've been running the test using different build configurations on an ESP32/R1, so I'm pretty sure this has been resolved. So I guess this issue can be closed. Thanks everyone involved! |
Thanks for confirming @dexterbg! |
@sudeep-mohanty |
Sorry, I cannot tell if I actually did the periodic callback test on the 4.4 branch. My test logs archived only show the periodic test on So the fix for the periodic callbacks may have been in a much earlier idf commit, or may have been in the new toolchain as well. |
Environment
Problem Description
FreeRTOS single shot timer callbacks occasionally are called twice. This occurs especially with CPU/MEM load and Wifi network traffic, but it also has been seen with Wifi disabled running a PPP network via modem. The issue can be reproduced by building & launching the attached test projects and starting some flood pings to the module, see below for details.
Source project / reference:
Additional note: it's possible this isn't limited to single shot timers. I haven't tested periodic timers for this behaviour yet.
Expected Behavior
A single shot timer callback is never executed twice on timer expiry.
Actual Behavior
Single shot timer callbacks occasionally are executed twice on timer expiry.
Steps to reproduce
Code to reproduce this issue
See attached ZIP archive (contains two projects, one for idf 3.3 & one for 4.4):
Debug Logs
See attached ZIP archive, files "testrun.log".
Example excerpt:
Other items if possible
See attached ZIP archive for sdkconfig.
The text was updated successfully, but these errors were encountered: