skip external interrupts with gpio_install_isr_service() but not with gpio_isr_register()

moggiozzi
Posts: 2
Joined: Thu Feb 06, 2020 11:57 am

skip external interrupts with gpio_install_isr_service() but not with gpio_isr_register()

Postby moggiozzi » Sat Oct 30, 2021 12:00 pm

Hi guys!
I try handle external interrupt every 500 us (2000 Hz).

Code: Select all

#define USE_GPIO_ISR_SERVICE // sometime skip interrupts when use interrupt service

IRAM_ATTR static void gpio_isr_handler(void* arg)
{
#ifndef USE_GPIO_ISR_SERVICE
	uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG);   //read status to get interrupt status for GPIO0-31
	uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
	SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status);    //Clear intr for gpio0-gpio31
	SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
#endif
	//myCode
	BaseType_t mustYield = pdFALSE;
	vTaskNotifyGiveFromISR(my_task_handle, &mustYield);
	if (mustYield)
		portYIELD_FROM_ISR();
}

void init(void) {
	esp_err_t ret = ESP_OK;
	gpio_config_t io_conf;
	//interrupt of rising edge
	io_conf.intr_type = GPIO_INTR_NEGEDGE;
	io_conf.pin_bit_mask = ((uint64_t)1 << ADC_PIN_nDR);
	io_conf.mode = GPIO_MODE_INPUT;
	io_conf.pull_down_en = 0;
	io_conf.pull_up_en = 0;
	ret |= gpio_config(&io_conf);

	xTaskCreate(dsp_task, "my_task", 4096, NULL, MY_TASK_PRIO, &my_task_handle);

#ifdef USE_GPIO_ISR_SERVICE
	ret |= gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
	gpio_isr_handler_add(ADC_PIN_nDR, gpio_isr_handler, (void*)ADC_PIN_nDR);
#else
	gpio_intr_enable(ADC_PIN_nDR);
	gpio_set_intr_type(ADC_PIN_nDR, GPIO_INTR_NEGEDGE);
	gpio_isr_register(gpio_isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL);
#endif
}
Sometime ouccur interrupt skips when using gpio_install_isr_service(). IMORTANT: without hi loaded my_task wake up with vTaskNotifyGiveFromISR() interrupt skips not occur.
ERR.png
ERR.png (85.62 KiB) Viewed 2233 times

When use alternate API gpio_isr_register() interrupt skips not occur.
OK.png
OK.png (56.92 KiB) Viewed 2233 times

Why ESP32 not properly handle external interrupts with gpio_install_isr_service()?

ESP_SRJ
Posts: 3
Joined: Sat Oct 09, 2021 8:19 am

Re: skip external interrupts with gpio_install_isr_service() but not with gpio_isr_register()

Postby ESP_SRJ » Mon Nov 01, 2021 11:41 am

I believe you have encountered a race condition which causes interrupt being lost. Here is the Github PR link that has raised this issue: https://github.com/espressif/esp-idf/pull/6853. We do have an internal fix for this issue. Once it has be reviewed, it will be merged to master, and the PR will be closed. If you are urgent, you could try the fix in the PR.

dmitrij999
Posts: 71
Joined: Sat Mar 02, 2019 8:06 pm

Re: skip external interrupts with gpio_install_isr_service() but not with gpio_isr_register()

Postby dmitrij999 » Thu Oct 27, 2022 7:35 pm

I've just run into the trouble like that, but I see that ESP32 sometimes skips pulses ~100 us, but with CPU frequency raising from 160 MHz to 240 MHz it comes to skip them rarer.
But I see that ESP32 doesn't skip pulses in 1-2 ms even on 160 MHz, but I generated pulses with the FreeRTOS task on the apart pin.
ESP-IDF v4.4.1 used.
Is it OK?

Who is online

Users browsing this forum: Google [Bot] and 81 guests