-
Notifications
You must be signed in to change notification settings - Fork 7.3k
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
Periodic esp_timer variation with BLE (IDFGH-9053) #10457
Comments
Looks like I might have figured this one out (✊🪵). There's a "general purpose" gptimer under peripherals and the esp_timer under system. Both are called high resolution timers. The documentation for esp_timer is a bit more streamlined and made it sound like it was suitable, but that does not seem to be the case. I swapped out some code to replace the esp_timer with the gptimer and now the events are firing as expected, with minimal variation, even with BLE enabled. It might be good to clarify or crosslink these two pages in the documentation. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_timer.html |
Hi @spanky411 ! |
I tried setting that to 3 (when using esp_timer), but it didn't resolve the timer irregularities when BLE was running. |
@spanky411 Using GPtimer helped your case, probably for some reasons: gptimer ISR is configured to share with any CPUs, or gptimer ISR is allocated on the 1 core. Maybe as another solution move the BT task to another core (see menuconfig). |
@spanky411 Could you try to enable
Thanks. |
@KonstantinKondrashov thank you for the insight. My vTaskList() dump showed esp_timer on core0 at priority 22, while btcontroller was higher at 23, so that falls inline with your statements. |
@spanky411 const esp_timer_create_args_t timer_args = {
.callback = &isr_callback_func,
.dispatch_method = ESP_TIMER_ISR,
}; And you see that the If your case is above then I can provide a feature for esp_timer that solve it (but only for timers with ESP_TIMER_ISR). EDIT: |
Here is the esp_timer_dump(). I had to revert some code, but I'm 99% sure this is the same esp_timer as before (I updated to idf5.0 in the middle of all of this and switched to gptimer).
The dump appears to impact the timing. The one above is printed "only" when there is a delay from the previous execution (I've got some timestamps to check that. see currTSx below) I think this makes it the most "fair" reading of the timing. Also, this is printed from the SensorTask following the unblocking of the semaphore... see below. Here is the callback (to your other question, I set it up to use
The sensortask running on It could be an interaction between the ble and sd card causing the delays. I only notice disappear it when I disable BLE (the plot above is derived from the logged timestamps from the sensortask, so tracking this variation over time would be difficult without that logging). It can take minutes for the timing delays to become noticeable, and even then, "on average" its fine and even when there are delays, they're interspersed with "well behaved" timings. |
Hi @spanky411! There is a solution to make esp_timer unsusceptible to such cases. This patch makes esp_timer callable from any core. (It is not the final version, I want to get confirmation that it helps for your case). |
These new settings allow you to balance the load on cores. Closes: espressif/esp-idf#10457
These new settings allow you to balance the load on cores. Closes: espressif/esp-idf#10457
I need 4 separate one-shot timers, with callbacks. timing 100us to 10ms each. confused by GPTimer vs High-Resolution (ESP-Timer) |
Answers checklist.
General issue report
With BLE (bluedroid) enabled, I'm seeing some uneven execution of the hardware timer. I'm trying to achieve 100Hz sample rate on a sensor and have setup an esp_timer to fire every 10000us (10ms). This works perfectly with BLE disabled, but when BLE is advertising, I get some periodic irregularities in the timing. This is a plot of the difference in esp_timer_get_time() between adjacent timer executions. You can see something is causing a periodic delay on the timer execution:
The subsequent timer event fires early to balance it out, making it look like a Rorschach test. On average its firing at 100Hz, but this variation is too significant for my application.
The same behavior is present on idf 4.4 and 5.0. I don't think this is a bug exactly, but I'm having a rough time finding the source of this periodic delay, or a way to work around it. Its a pretty big delay for a high-resolution hardware timer. Is it possible to restrict the variation in timer events (I thought the minimum esp_timer resolution is 50us, which is way below the +/-1ms I'm seeing)?
Here's the same plot with BLE off (which shows it executing pretty close to 10ms with minimal variation). Same code as above, just not starting BLE:
Some more background:
Here's a vTaskList() dump. I'm using core1 to do this timer, and have pushed basically everything else to core0:
I'm using the timer to unblock the high priority SensorTask. I am reading esp_timer_get_time() in the timer ISR and then unblocking the task via xSemaphoreGiveFromISR and then portYIELD_FROM_ISR() (I've also tried esp_timer_isr_dispatch_need_yield() with the same results). Its about 13-14us from the ISR to the unblocked task. That is not the source of the delay in the above plot. The timer ISR itself is what appears to be delayed.
The text was updated successfully, but these errors were encountered: