Could ticker interrupts interfere with hardware interrupts?

566 Views Asked by At

Background

I was wondering if using ticker interrupts could interfere with hardware interrupts triggered by a button press.

Example

Imagine I would like to use these two types of interrupts:

  1. a ticker timer to update a progress bar on a small display every n second
  2. a hardware interrupt that starts/stops the process whose progress is displayed if the user presses a button

Important: Both interrupts set shared global volatile flags.

Main question

Would it be possible for the ticker interrupt to occur during a button induced interrupt and as a result for the program to end up in a state where the global flags are set contradictorily?

More specific questions

Does a hardware and a software interrupt have the same 'rank'?

If they occured at the same time, would the interrupt request occurring slightly later (but still overlapping with the first one) be ignored, or just put into a queue and execute straight after the first interrupt has finished? In this case, the flags would be set in an unexpected manner.

Can I disable one type of the interrupts inside the other type's ISR - i.e. ignore it?

I hope the problem statement is clear enough even without a code example.

1

There are 1 best solutions below

8
On BEST ANSWER

I'mm assuming you are using an AVR.

When an interrupt fires, other interrupts are disabled while the interrupt routine is running. So any interrupts that occur in this time simply get flagged. When the interrupt routine returns, the global interrupt flag is re-enabled and any polled interrupts can then fire one at a time.

You can manually enable the global interrupts inside the routine for critical things that must run, but are disabled by default.

EDIT:

Is there a way to disable this flag setting? I don't want the ticker timer to perform an interrupt once the button has been pressed. This is why I asked about ranks and the ability to disable on type of interrupt, if there is such a thing

You can clear the pending interrupt, however you'll have to read the datasheet for your Arduino's AVR. You need to find the register for the external interrupt.

For example, on an atmega328p, external interrupt 0 can be cleared by setting its flag bit to 1:

EIFR |= (1 << INTF2);

EIFR = External Interrupt Flag Register
INTF2 = Bit 0 – INTF0: External Interrupt Flag 0

However, it may be far simpler to poll the button in your loop() function. Or at best, simply set a flag for you to act upon back in the loop() function. There you would be able to decide if you want to react or ignore to the interrupt

There is the issue of having your interrupts far too large. If you use timing, or require accuracy, this could be affected by a large amount over time. As the interrupt queue length is only 1 deep some interrupts could be lost. And the interrupt which powers millis() & micros() runs multiple times per millisecond, so a bulky interrupt could end up slowing down time.

Also do you have any debouncing code or hardware?

If not, the interrupt handling the button could be run multiple times on a single press.