-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
[BUG][PATCH]Delay in esp_timer task callback prevents dispatch of ESP_TIMER_ISR callbacks (IDFGH-10379) #11636
Comments
Hi @acf-bwl!
Yes, I confirm that your fix is able to fix a ceratin scenario. I will applay your changes with some addoptions. |
great, thanks :) |
Answers checklist.
IDF version.
master
Operating System used.
Windows
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
CMD
Development Kit.
Lolin D32, in-house board
Power Supply used.
USB
What is the expected behavior?
I would expect that callbacks dispatched as ESP_TIMER_ISR would run asynchronously to those dispatched as ESP_TIMER_TASK, so that even if a long delay were to occur in a callback in the timer task, the callbacks run in the ISR would continue to run unimpeded during this delay. Indeed, in esp_timer code, the esp_timer_impl abstraction layer appears to provide two separate alarms: one for the time task and one for the isr. One would expect that even when the timer task is busy, the separate ISR alarm would continue unaffected.
What is the actual behavior?
Introducing a one second delay into a callback in the timer task causes all ISR callbacks to stop being serviced until the aforementioned timer task callback returns. This means no ISR-dispatched esp_timer s are serviced for around a second. This seems like it somewhat defeats the purpose of the ESP_TIMER_ISR dispatch method.
Steps to reproduce.
Please build and run the attached code on ESP32: esp_timer_issue.zip
. A copy of the main file is provided below for convenience. Note that the CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD option must be enabled.
Note that following a print of "task callback", which prints with a period of 2 seconds, "isr callback" stops printing for some time prior to resuming its regular printing with a period of 200ms.
Debug Logs.
More Information.
This occurs because the LAC timer has only one compare register to use for both the timer task dispatch alarm and the ISR dispatch alarm. Both methods use the
function to set their timers, with alarm_id distinguishing between the two. The timestamps of both alarms are stored, and esp_timer_impl_set_alarm_id compares them and places the lesser of the two in the actual hardware timer compare register.
During the interrupt, however, the hardware timer compare register is never updated. The next update to the compare register comes after the next callback is finished running, whether in the ISR or in the timer task. This means that the timer compare register will continue to hold an outdated compare value, rather than the compare value for the upcoming ISR alarm, until the callback in the timer task is complete and the time task once again calls esp_timer_impl_set_alarm_id(). This scenario only occurs if this timer expiry was dispatched to the timer task and the next is destined to be dispatched to be run in the ISR, or perhaps theoretically the opposite.
This appears to affect the LAC esp_timer backend; I have not checked whether any of the others are affected. I have a patch for this bug for both esp-idf master and release/v4.4 which I will attach to this bug report as pull requests.
The text was updated successfully, but these errors were encountered: