Use of delay/micros/nillis within ISR

Status
Not open for further replies.

mario.contreras

New member
I have read a lot about why a delay/micros/millis functions within an ISR will not work on arduinos.
However, I have been using them in my Teensy projects (T3.2) and they seem to be working fine; I do not require very precise timing and that is why I might have not noticed any issue.
I even have used serial.print and works fine.
I am clear that using them are not the best coding practice but I would like to understand what is happening

Can anyone go deeper on this? why does it seem to work? are there any limitations? any recommendations?

Regards

M
 
While you are inside your ISR, no other ISR of a lower priority will be able to run, so if your code relies on a lower priority ISR to do something than you can hang.

Or for example if you have some hardware devices that have an ISR like a Serial port at a lower priority and data comes in and fills the hardware queue before your ISR returns, you could easily lose data.

Serial.print may not be much of an issue depending on your timing and how much. That is if your serial output will fit into an output queue and not need to trigger sending a packet, then makes no difference. But if you are outputting more data and it needs to send a packet, to complete the call and again if that device handler is lower priority, than...
 
This summary is something that should be used as a guide.

/external-interrupts/attachinterrupt/

While the nature of Teensy may allow micros() to work - that doesn't account for all the other things that are true and important and will cause trouble.

Teensy interrupts are more advanced with priority levels - but when an ISR() has any time spent in it any other interrupt of the same or less priority - as well as the main loop doesn't run.
 
Thanks for the quick explanation! Really helpful
One additional question. What about delay() function in Teensy environment; does it relies on timer interrupts? and if it does, does it hangs if used within an ISR?

M
 
What about delay() function in Teensy environment; does it relies on timer interrupts? and if it does, does it hangs if used within an ISR?

The answer is basically the same, it depends on the priority level of your interrupt.

Teensy LC & 3.x have priority nest interrupts. When an interrupt is running, all interrupts at the same or lower priority are blocked, but those assigned a higher priority are able to run.

Here's a video I recently made which explains this concept.


Priority levels are from 0 to 255, where 0 is the highest priority and 255 is the lowest. By default, most interrupts are at 128, exactly in the middle.

The millis interrupt runs at 32. So for most uses, you can use delay(), micros() and millis(), because almost all other interrupts are assigned lower priorities. Quite a lot of work as gone into default priority levels to make many combinations of common Arduino libs "just work", even cases that don't work on normal Arduino, as long as you don't mess with the settings. But if you've raised your interrupt priority to 32 or higher (lower numerical value), as was done in that video demo, then delay() would stall if called from such a high priority interrupt.
 
I should also mention Serial.print() does have known failure modes if you print from both main program and interrupts, or from 2 or more interrupts at different priority levels. It works fine if you do all your printing from the same priority level, or if your printing from different levels never overlaps (which sounds risky, but is actually pretty common).

I'm considering someday hardening Serial.print() and other stuff against these cases. But doing so without causing performance issues it quite difficult, maybe even impossible.
 
Status
Not open for further replies.
Back
Top