esp-idf icon indicating copy to clipboard operation
esp-idf copied to clipboard

GPIO interrupt latency (IDFGH-14898)

Open moggiozzi opened this issue 11 months ago • 4 comments

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:

  1. We use gpio_isr_register() API. gpio_install_isr_service() API get worse latency.
  2. On ESP-IDF 5.4 dsiabling "Component config -> Bluetooth -> Controller Options -> High level interrupt" did't get latency improves.
  3. 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

moggiozzi avatar Mar 20 '25 13:03 moggiozzi

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.

ginkgm avatar Mar 21 '25 05:03 ginkgm

ESP_INTR_FLAG_LEVEL3

  1. 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
  1. Component config -> Bluetooth -> Controller Options -> High level interrupt already disabled

moggiozzi avatar Mar 21 '25 08:03 moggiozzi

How about pin Bluetooth and GPIO interrupts to different cores?

songruo avatar Mar 31 '25 12:03 songruo

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).

moggiozzi avatar Apr 01 '25 09:04 moggiozzi