How to cancel the Interrupts Stack?

human890209
Posts: 54
Joined: Wed Aug 15, 2018 8:56 am

How to cancel the Interrupts Stack?

Postby human890209 » Mon Sep 03, 2018 8:29 am

Hi,
My code is similar to this:

Code: Select all

const byte interruptPin = 25;
volatile int interruptCounter = 0;
int numberOfInterrupts = 0;
 
[b]portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;[/b]
 
void [b]IRAM_ATTR [/b]handleInterrupt() {
  [b]portENTER_CRITICAL_ISR(&mux);[/b]
  interruptCounter++;
  [b]portEXIT_CRITICAL_ISR(&mux);[/b]
}
 
void setup() {
 
  Serial.begin(115200);
  Serial.println("Monitoring interrupts: ");
  pinMode(interruptPin, INPUT_PULLUP);
  [b]attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);[/b]
 
}
 
void loop() {
 
  if(interruptCounter>0){
 
      [b]portENTER_CRITICAL(&mux);[/b]
      interruptCounter--;
      [b]portEXIT_CRITICAL(&mux);[/b]
 
      numberOfInterrupts++;
      Serial.print("An interrupt has occurred. Total: ");
      Serial.println(numberOfInterrupts);
  }
}
I used the mux technique to replace the cli() and sei() of normal Arduino.
But I've found that even portENTER_CRITICAL_ISR(&mux); and portEXIT_CRITICAL_ISR(&mux); is placed in void IRAM_ATTR handleInterrupt() to stop other Interrupts. If the interrupt is triggered multiple times in a short time, there will be ONE extra interrupt behind the triggered one.

I've tested several times, there always ONE in the queue, won't get 2 or 3. I googled the situation and found this article about Switch Bounce.
https://www.allaboutcircuits.com/techni ... l-with-it/
and some microcontrollers might stack up one waiting interrupt.
I guess ESP32 stacks up ONE waiting interrupt.
I don't remember I've meat this situation when using AVR or ESP8266, cause normally an interrupt won't be interrupted and there seems no stack, the extra interrupt is ignored or not be detected.

Cause I'm using my code and other libraries which are written for ESP8266 and normal Arduinos.

Are there any solutions to cancel the interrupt stack of ESP32 to make it act like a normal Arduino?

And why the first line of {portENTER_CRITICAL_ISR(&mux);} won't cancel the following interrupt?
There is no other interrupt happen in the middle of handleInterrupt(), but if an interrupt is triggered when the handleInterrupt() processing, it will be stacked and wait in the queue. How to cancel this? I want interrupts to be ignored when an Interrupt() is processing.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: How to cancel the Interrupts Stack?

Postby ESP_Angus » Mon Sep 03, 2018 9:42 am

Sorry, I don't understand the question. Can you please clarify a few things:

- What exactly is connected to the pin you have the interrupt attached to?
- What exactly do you expect to happen? (ie what action do you take, and what do you expect to see the code do.)
- What is currently happening? (ie when you take the action, what does the code do.)
- What is your goal, in terms of the code you're writing?

It shouldn't be necessary to put any critical section portENTER_CRITICAL/etc inside the ISR, if it is only registered once as shown here. ISRs are only bound to a single CPU and a single CPU won't run the same interrupt on top of itself. You do need portENTER_CRITICAL/portEXIT_CRITICAL where you change the counter in the loop() function, to prevent the loop itself being interrupted while modifying the counter.

It is quite likely that if the pin is connected to a switch, you're getting multiple interrupt events because of "switch bounce". The interrupts aren't really being "stacked up", it's just that the CPU can handle each individual interrupt very quickly - multiple additional switch "bounces" can happen in the time it takes the loop to respond to the first bounce, in particular having the serial port print a message takes "a while" at the CPU scale. However I'm not sure that's the situation you have, will wait for clarification.

boarchuz
Posts: 605
Joined: Tue Aug 21, 2018 5:28 am

Re: How to cancel the Interrupts Stack?

Postby boarchuz » Mon Sep 03, 2018 9:55 am

Have a look at this code, similar to yours, for how you might implement debouncing:
http://www.switchdoc.com/2018/04/esp32- ... nterrupts/

Take note also that the interruptCounter is reset there (interruptCounter=0) rather than decremented (interruptCounter--). Just doing this might get you closer to the output you expect, because like Angus I suspect it's probably firing the interrupt multiple times before your loop gets around to decrementing it even once. Regardless, you still ought to debounce the signal else you're likely to get multiple interrupts on press and/or release.

human890209
Posts: 54
Joined: Wed Aug 15, 2018 8:56 am

Re: How to cancel the Interrupts Stack?

Postby human890209 » Mon Sep 03, 2018 1:42 pm

Hi, @ESP_Angus
Thanks for your reply.
I get the code from this page:
https://techtutorialsx.com/2017/09/30/e ... nterrupts/
Thanks for your advice that these lines could be canceled in the ISR,

Code: Select all

portENTER_CRITICAL_ISR(&mux);

Code: Select all

portEXIT_CRITICAL_ISR(&mux);
I'm trying to do SoftwareSerial with Interrupts by ESP32, I used to use a MOD from plerup/espsoftwareserial on my ESP8266.
The rxRead() is triggered by GPIO interrupts, by raising or falling depending on Invert setting.
I've tested sending 1 byte with BAUD 115200 in a 1000us interval, and I used another PIN to display the bit reading process and debug every pin with my Saleae Logic.
For example, the test byte is 0b10101010, I see 2 rxRead() triggered by each received byte.
The second one is triggered in the process of the rxRead() and queued behind the first interrupt. And no matter how many gaps in the Byte, only One Extra interrupt.
I tested sending a 0b00000000 or 0b11111111 which will only trigger rxRead() once. No more queued interrupt.

The extra interrupt is really annoying, though I add a digitalRead at the beginning of rxRead() to filter if it is a real one. But the extra intrrupt disturbs the next real interrupt's timing. I have to add an extra StopBit to make the reaction stable. And for now, the 240mHz ESP32 didn't beat the 80mHz ESP8266, I lower the BAUD to 76800 to get stable results which could get with ESP8266(80mHz) at 115200. The interrupt trigger time is not stable, which is caused by the extra queued interrupt...

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: How to cancel the Interrupts Stack?

Postby ESP_Angus » Tue Sep 04, 2018 2:04 am

Interrupt latency on the ESP32 is a little higher than ESP8266, although there are also a lot of other variables which can effect interrupt timing. Without seeing and debugging the full code it's hard to tell what the problem might be.

Regarding SoftwareSerial, did you know that ESP32 has 3 hardware UARTs? And each one can be mapped to any pins for TX/RX?

human890209
Posts: 54
Joined: Wed Aug 15, 2018 8:56 am

Re: How to cancel the Interrupts Stack?

Postby human890209 » Tue Sep 04, 2018 9:59 am

Hi, thanks.@ESP_Angus

I know that. It's cool to have more hardware serials on ESP32, but I use the Hardware Serial to communicate with other Device, cause that should be Normal.
I use software serials to communicate with my programmed boards, for example, ESP32 to ESP32. I don't use I2C or SPI to communicate, cause they need more Pins or haven't slave mode support.

After I delete the lines in ISR, the interrupt's reaction seems to be improved.
I guess maybe it's possible to hit 115200, still tuning now.

I'm still a newbie. :D Cause ESP8266 don't have extra Hardware serial, that's a reason I switch to ESP32 because some other devices need normal RX pin and TX pin. And SoftwareSerial could hardly serve 2 or more standard serials at the same time.

Is ESP32's HardwareSerial safe to interrupts? When an ISR triggered, will the HardwareSerial be infected?
If the buffer is not updated like delay() during an interrupt, it's okay. Will the data sending or receiving in the background be broken by an interrupt?

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: How to cancel the Interrupts Stack?

Postby rodmcm » Wed Sep 12, 2018 9:11 am

Hi
Could you please explain a little more on the stacking and halting please.

I am using a timer interrupt and a digital pin interrupt. Both will not work together but they each run fine alone..
If run together then the onTimer operates but the handeInterrupt seems to just report a constant count.

This is the arrangement of the interrupts. Is it possible or likely that one stops the other? What can I do to eliminate

void IRAM_ATTR handleInterrupt()

void IRAM_ATTR onTimer()

Who is online

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