GPIO interrupt latency (IDFGH-14898)
Answers checklist.
- [x] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- [x] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- [x] I have searched the issue tracker for a similar issue and not found a similar issue.
IDF version.
v5.4
Espressif SoC revision.
ESP-WROOM-32 board
Operating System used.
Windows
How did you build your project?
Command line with Make
If you are using Windows, please specify command line type.
CMD
Development Kit.
ESP-WROOM-32 | Custom Board
Power Supply used.
USB
What is the expected behavior?
GPIO interrupt latency < 100us
What is the actual behavior?
GPIO interrupt latency > 1000us (skip some interrupts handling)
Steps to reproduce.
We use ESP-IDF 4.2 in our project for several years. MCP3912 ADC DataReady pin connected to GPIO34. In GPIO interrupt we start spi dma reading every 500us (we patched spi_master.c for starting spi dma operation from interrupt).
When trying migrate to ESP-IDF 5.4, we encountered with problem: GPIO interrupt latency significantly increased when using Bluetooth at the same time. If the typical period between interrupts in project builded with ESP-IDF 4.2: min = 478, max = 499 Then when building project on 5.4 we get interrupt gaps: min = 318, max = 1180
I create test project for reproduce problem on ESP-WROOM-32 board https://github.com/moggiozzi/esp32gpioint ADC DataReady interrupts emulated with PWM module. Сonnect D32(GPIO32) to D34(GPIO34) pin on ESP-WROOM-32 board. Interrupt handler call period with ESP-IDF 4.2: min = 478, max = 500 Interrupt handler call period with ESP-IDF 5.4: min = 332, max = 1226
Some notes:
- We use gpio_isr_register() API. gpio_install_isr_service() API get worse latency.
- On ESP-IDF 5.4 dsiabling "Component config -> Bluetooth -> Controller Options -> High level interrupt" did't get latency improves.
- There is an assumption that the performance broke already in 4.4, because I once tried to migrate, but refused due to performance isues. (I'm not sure about the gues).
How increase GPIO interrupt priority or decrease Bluetooth interrupt priority or any steps to fix interrupt latency problem?
Debug Logs.
https://raw.githubusercontent.com/moggiozzi/esp32gpioint/refs/heads/main/log42.txt
https://raw.githubusercontent.com/moggiozzi/esp32gpioint/refs/heads/main/log54.txt
Diagnostic report archive.
No response
More Information.
No response
Please try this one: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/intr_alloc.html#c.ESP_INTR_FLAG_LEVEL3
when calling https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#_CPPv417gpio_isr_registerPFvPvEPviP17gpio_isr_handle_t
But as you can see, BT may use higher level (LEVEL4 in some cases), so maybe Component config -> Bluetooth -> Controller Options -> High level interrupt still need to be disabled.
ESP_INTR_FLAG_LEVEL3
- Using the ESP_INTR_FLAG_LEVEL3 flag does not help (add changes to test project)
#ifdef USE_GPIO_ISR_SERVICE
ret |= gpio_install_isr_service(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL3);
ret |= gpio_isr_handler_add(INT_GPIO_PIN, gpio_isr_handler, NULL);
#else
ret |= gpio_intr_enable(INT_GPIO_PIN);
ret |= gpio_set_intr_type(INT_GPIO_PIN, GPIO_INTR_POSEDGE);
ret |= gpio_isr_register(gpio_isr_handler, NULL, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL3, NULL);
#endif
-
Component config -> Bluetooth -> Controller Options -> High level interruptalready disabled
How about pin Bluetooth and GPIO interrupts to different cores?
How about pin Bluetooth and GPIO interrupts to different cores?
I think this is already done, since the project defaults settings is
Component config - Bluetooth - Bluedroid Options - The cpu core which Bluedroid run (Core 0 (PRO CPU))
And the user code executed on Core 1 (APP CPU).