Page 1 of 1

External Interrupt Delay

Posted: Wed May 03, 2023 2:53 pm
by taoglas
Hello. A problem occurred while executing external interrupts. The time between an interrupt handler call and a task function call varies from 20 microseconds to 5 milliseconds. I tried to change the priority and interrupt flags, I did not notice the difference. I can not understand what this delay depends on. I measured the delay like this:

Code: Select all

static void IRAM_ATTR gpio_interrupt_handler(void *args)
{
    int pinNumber = (int)args;
    start = esp_timer_get_time();
    xQueueSendFromISR(interputQueue, &pinNumber, NULL);
}

void isr_task(void *params)
{
	int pinNumber;
	while(1)
	{
        	if (xQueueReceive(interputQueue, &pinNumber, portMAX_DELAY))
        	{
			stop = esp_timer_get_time();
			printf("interrupt delay %llu us\n", (stop - start));
        	}
	}
}

void app_main(void)
{
...
    gpio_pad_select_gpio(35);
    gpio_set_direction(35, GPIO_MODE_INPUT);
    gpio_set_intr_type(35, GPIO_INTR_POSEDGE);
    interputQueue = xQueueCreate(10, sizeof(int));
    xTaskCreate(isr_task, "isr_task", 2048, NULL, 20, NULL);	//configMAX_PRIORITIES = 25
    gpio_install_isr_service(ESP_INTR_FLAG_LEVEL3);
	gpio_isr_handler_add(35, gpio_interrupt_handler, (void *)35);
...
}
Output
interrupt delay 4715 us
interrupt delay 2185 us
interrupt delay 4916 us
interrupt delay 15 us
interrupt delay 1237 us
interrupt delay 2562 us
interrupt delay 2592 us
interrupt delay 3882 us
interrupt delay 204 us
interrupt delay 1758 us
interrupt delay 1557 us
interrupt delay 2053 us
interrupt delay 4593 us
interrupt delay 2849 us
interrupt delay 4201 us
interrupt delay 522 us
interrupt delay 3770 us
interrupt delay 1813 us
interrupt delay 3167 us
interrupt delay 4091 us
interrupt delay 1657 us
interrupt delay 4457 us
interrupt delay 779 us
interrupt delay 2133 us
interrupt delay 750 us
interrupt delay 2752 us
interrupt delay 3423 us

I would like a delay no more than a millisecond. I will be glad to any advice. Thank you.

Re: External Interrupt Delay

Posted: Thu May 04, 2023 3:50 am
by ESP_Sprite
So you're not counting the interrupt delay; you're counting the delay before your task gets scheduled. This depends on a bunch of things: mainly other interrupts scheduled and other tasks running. Is there anything else that your CPU is doing (WiFi, BT, writing to flash, ...)? Also, what chip is this on?

Re: External Interrupt Delay

Posted: Thu May 04, 2023 9:05 am
by taoglas
Thanks, I did it differently. If you create a task in an interrupt handler, everything works much faster:

Code: Select all

static void IRAM_ATTR gpio_interrupt_handler(void *args)
{
    int pinNumber = (int)args;
    start = esp_timer_get_time();
    xTaskCreate(&get_hf_data, "get_hf_data", 2048, NULL, 5, NULL);
}

void get_hf_data(void)
{
	stop = esp_timer_get_time();
	printf("interrupt delay %llu us\n", (stop - start));
	hf_get_data_wg(&hf_handle);
	vTaskDelete(NULL);
}

Latency 56 microseconds.

Re: External Interrupt Delay

Posted: Thu May 04, 2023 7:27 pm
by MicroController
You should make use of the pxHigherPriorityTaskWoken parameter of xQueueSendFromISR, and portYIELD_FROM_ISR(), as per the example at https://www.freertos.org/a00119.html

Re: External Interrupt Delay

Posted: Fri May 05, 2023 1:48 am
by ESP_Sprite
+1 on what MicroController said; doing something expensive and dangerous like creating a task from an ISR is unlikely to ever be a good idea.