Skip to main content
Arduino

Return to Answer

added 1746 characters in body
Source Link

The quoted phrase is not a warning, it is merely a statement about how things work.

There's nothing intrinsically wrong with using millis() or micros() within a properly-written interrupt routine.

On the other hand, doing anything at all within an improperly-written interrupt routine is by definition wrong.

An interrupt routine that takes more than a few microseconds to do its job is, in all likelihood, improperly written.

In short: A properly-written interrupt routine will not cause or encounter issues with millis() or micros().

Edit: Regarding "why micros() "starts behaving erratically"", as explained in an "examination of the Arduino micros function " webpage, micros() code on an ordinary Uno is functionally equivalent to

unsigned long micros() {
 return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}

This returns a four-byte unsigned long comprised of the three lowest bytes from timer0_overflow_count and one byte from the timer-0 count register.

The timer0_overflow_count is incremented about once per millisecond by the TIMER0_OVF_vect interrupt handler, as explained in an examination of the arduino millis function webpage.

Before an interrupt handler begins, AVR hardware disables interrupts. If (for example) an interrupt handler were to run for five milliseconds with interrupts still disabled, at least four timer 0 overflows would be missed. [Interrupts written in C code in the Arduino system are not reentrant (capable of correctly handling multiple overlapping executions within the same handler) but one could write a reentrant assembly language handler that reenables interrupts before it begins a time-consuming process.]

In other words, timer overflows don't "stack up"; whenever an overflow occurs before the interrupt from the previous overflow has been handled, the millis() counter loses a millisecond, and the discrepancy in timer0_overflow_count in turn makes micros() wrong by a millisecond too.

Regarding "shorter than 500 μs" as an upper time limit for interrupt processing, "to prevent blocking the timer interrupt for too long", you could go up to just under 1024 μs (eg 1020 μs) and millis() still would work, most of the time. However, I regard an interrupt handler that takes more than 5 μs as a sluggard, more than 10 μs as slothful, more than 20 μs as snail-like.

The quoted phrase is not a warning, it is merely a statement about how things work.

There's nothing intrinsically wrong with using millis() or micros() within a properly-written interrupt routine.

On the other hand, doing anything at all within an improperly-written interrupt routine is by definition wrong.

An interrupt routine that takes more than a few microseconds to do its job is, in all likelihood, improperly written.

In short: A properly-written interrupt routine will not cause or encounter issues with millis() or micros().

The quoted phrase is not a warning, it is merely a statement about how things work.

There's nothing intrinsically wrong with using millis() or micros() within a properly-written interrupt routine.

On the other hand, doing anything at all within an improperly-written interrupt routine is by definition wrong.

An interrupt routine that takes more than a few microseconds to do its job is, in all likelihood, improperly written.

In short: A properly-written interrupt routine will not cause or encounter issues with millis() or micros().

Edit: Regarding "why micros() "starts behaving erratically"", as explained in an "examination of the Arduino micros function " webpage, micros() code on an ordinary Uno is functionally equivalent to

unsigned long micros() {
 return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}

This returns a four-byte unsigned long comprised of the three lowest bytes from timer0_overflow_count and one byte from the timer-0 count register.

The timer0_overflow_count is incremented about once per millisecond by the TIMER0_OVF_vect interrupt handler, as explained in an examination of the arduino millis function webpage.

Before an interrupt handler begins, AVR hardware disables interrupts. If (for example) an interrupt handler were to run for five milliseconds with interrupts still disabled, at least four timer 0 overflows would be missed. [Interrupts written in C code in the Arduino system are not reentrant (capable of correctly handling multiple overlapping executions within the same handler) but one could write a reentrant assembly language handler that reenables interrupts before it begins a time-consuming process.]

In other words, timer overflows don't "stack up"; whenever an overflow occurs before the interrupt from the previous overflow has been handled, the millis() counter loses a millisecond, and the discrepancy in timer0_overflow_count in turn makes micros() wrong by a millisecond too.

Regarding "shorter than 500 μs" as an upper time limit for interrupt processing, "to prevent blocking the timer interrupt for too long", you could go up to just under 1024 μs (eg 1020 μs) and millis() still would work, most of the time. However, I regard an interrupt handler that takes more than 5 μs as a sluggard, more than 10 μs as slothful, more than 20 μs as snail-like.

Source Link

The quoted phrase is not a warning, it is merely a statement about how things work.

There's nothing intrinsically wrong with using millis() or micros() within a properly-written interrupt routine.

On the other hand, doing anything at all within an improperly-written interrupt routine is by definition wrong.

An interrupt routine that takes more than a few microseconds to do its job is, in all likelihood, improperly written.

In short: A properly-written interrupt routine will not cause or encounter issues with millis() or micros().

AltStyle によって変換されたページ (->オリジナル) /