Page 1 of 1

[Question]: Maximum interrupt rate on GPIO

Posted: Sun Jul 23, 2017 4:21 pm
by kolban
What is the maximum interrupt rate we can support on a GPIO input pin?

Tests and back story:

I am playing with an OV7670 camera module. This has an input clock frequency of 4MHz. For each byte of pixel data, it transitions a clock signal from low to high.

Image

My thinking was that I would setup an interrupt handler such that each time the clock signal transitioned, I would read the 8 bits of parallel GPIO data. To test this theory, I performed a simpler test. I setup an interrupt handler that merely incremented a 32bit value to validate that my handler was being called.

My API logic was loosely as follows:

Code: Select all

gpio_install_isr_service(0); // Install the ISR service.
gpio_isr_handler_add(pixelClockPin, myHandler, NULL);
gpio_intr_enable(pixelClockPin);
Immediately following this interrupt setup, I then loop/sleep displaying the counter:

Code: Select all

while(1) {
   vTaskDelay(1000/portTICK_PERIOD_MS);
   ESP_LOGD(tag, "Value of counter: %d", pclkCounter);
}
The interrupt handler logic looked like:

Code: Select all

static void IRAM_ATTR myHandler(void* arg) {
   pclkCounter++;
}
When I build and flash the application, it runs but "resets" before the first log of the counter print with the reset message:
ets Jun 8 2016 00:22:57
rst:0x8 (TG1WDT_SYS_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
My immediate guess is that an interrupt rate of 4MHz is too fast ... and the FreeRTOS environment is being starved. However, that doesn't *feel* right. With the thinking that the clock speed of an ESP32 is 240MHz, there should be enough capacity to execute a large number of instructions between interrupts at this rate.

Does anyone have any thoughts on this puzzle?

Neil

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Sun Jul 23, 2017 6:02 pm
by ESP_igrr
A simple test would be to measure how much time a single interrupt takes to complete. For example:

1. Have a busy loop in a task. On each iteration, get CCOUNT value — CPU cycle counter. If the difference with the previous iteration of the counter is > N cycles, log the difference to console. Choose N larger than the loop cycle duration but smaller than interrupt duration.
2. Enable some one-off interrupt, such as GPIO interrupt. Measure its duration using the task set up in pt. 1.

You will likely get a result that an interrupt takes ~2 microseconds to execute.

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Sun Jul 23, 2017 7:29 pm
by WiFive
I know you are just experimenting but no harm to add this reference here for others
ESP32 I2S supports a camera slave mode for high-speed data transfer from external camera modules.
https://github.com/igrr/esp32-cam-demo

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Sun Jul 23, 2017 8:54 pm
by kolban
Thank you Mr ESP_Igrr ... I haven't run the test yet but added it to my list of things to try. Let us assume that it does take 2µS to execute the most trivial interrupt handler (using the ESP-IDF framework as described in previous post), then that would appear to say that we are able to process 500,000 interrupts/second. And that would be the VERY maximum ... allowing almost nothing for the rest of a single core.

500,000 * 2µS = 1 second of CPU time.

My attempt to interrupt at 4MHz rate would require an interrupt to be handled in 250nS or less ... which appears to be a factor of eight times more than the max we can afford ... and hence would more than explain the symptoms being seen.

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Mon Feb 19, 2018 2:55 am
by jgustavoam
Hi Mr Kolban , I did this Test with 8 MHz (and 20MHz) . I do'nt know if it can be conclusive. I'm still learning ESP-IDF.
So I used Arduino IDE. My question is that the interrupt mode does not change anything - the same waveform in some modes (I do not know why).I'll do more tests.

GPIO_2 = clock 8 MHz (and 20MHz)
GPIO_4 = interrupt pin connected to GPIO_2
GPIO_5 = Pulse generated by external interrupt

Oscilloscope IMAGE ( 8 MHz):
https://www.flickr.com/photos/jgustavoa ... 409004158/

Oscilloscope IMAGE ( 20 MHz) !
https://www.flickr.com/photos/jgustavoa ... 409004158/

Code: Select all

// TEST OF EXTERNAL INTERRUPTS 
// ESP32 DEVKIT - ARDUINO IDE 1.8.5
// Gustavo Murta 18/02/2018

int GPIO4 = 4;      // SCOPE CH 1   
int GPIO5 = 5;      // SCOPE CH 2  

void setup()
{
  pinMode (GPIO4, INPUT);                 // Interrupt PIN - ESP32 GPIO_4
  pinMode (GPIO5, OUTPUT);                // Scope PIN - ESP32 GPIO_5

  // Generating 8 MHz Pulses - For test, attach GPIO_2 to GPIO_4
  pinMode(2, OUTPUT);                     // GPIO_2 as Output
  ledcAttachPin(2, 0);                    // GPIO_2 attached to PWM Channel 0
  ledcSetup(0, 8000000, 2);               // Channel 0 , freq 8 MHz , 2 bit resolution
  ledcWrite(0, 2);                        // Enable frequency with duty cycle 50%

  attachInterrupt(digitalPinToInterrupt(GPIO4), PrintData, RISING);
  
  Serial.begin(115200);
  Serial.println(" Monitoring Interrupts ");
}

void setGPIO_5 ()
{
  digitalWrite(GPIO5, LOW);        // Monitor GPIO_5 with SCOPE CH 2 
  digitalWrite(GPIO5, HIGH);
  //delayMicroseconds(1);          // change nothing
  digitalWrite(GPIO5, LOW);
}

void PrintData ()
{
  //Serial.println(" An interrupt has occurred. "); // For slow tests 
  setGPIO_5 ();
}

void loop()
{
}

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Sat Dec 21, 2019 4:57 am
by HelWeb
My measurements show: 1.7 µs from external interrupt to interrupt routine => about 500000 Interrupts/s.
If you are willing to dedicate core 1 only for "interrupts" you can work with more than 3.000.000 interrupts per second.
Look at
https://github.com/MacLeod-D/ESp32-Fast-external-IRQs

Re: [Question]: Maximum interrupt rate on GPIO

Posted: Sat Dec 21, 2019 5:56 am
by HelWeb
Dear Mr. jgustavoam,

I do not get your results - and they are impossible.
Your display of channel 2 is wrong - I tested it with my scope.

With the PWM-frequency at pin 2 and connected to the interrupt pin 4 the following will happen:

Interrupt routine 5 is called. The total time from external interrupt to the end of the interrupt routine needs 2.26 µs.
Then the next comming pulse of pin2 starts the interrupt again.
There are a lot of pin 2 pulses which do just nothing - because the interrupt routine is busy.
So it does not really matter: PWM 80.000.000 or 20.000.000 or 500.000 - you get allways interrupts every 2.260 µs.
That is an interrupt frequency of 442477 Hz.

With higher PWM frequencies you will miss (a lot of) interrupts without a warning !
Sorry.

BTW Your scope and/or your probes are not the best.