0

I am assuming millis() is a Timer ISR function. If so : When using millis() as mentioned in Arduino Reference : unsigned long currentMillis = millis(); What would happen if the ISR asynchronously changes the value being read in a function. I mean if I have read one byte into currentMillis, but millis had changed the value before the remaining 7 bytes are read.

Cheers and TIA

1
  • 1
    Embedded systems developer? look into the source code of millis() before asking
    – Juraj
    Apr 30, 2021 at 17:02

1 Answer 1

2

I am assuming millis() is a Timer ISR function.

It is a function that retrieves a value that is updated by and ISR.

What would happen if the ISR asynchronously changes the value being read in a function.

Cannot happen: the value is read with interrupts disabled.

See for example, in the AVR core:

// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;

I mean if I have read one byte into currentMillis, but millis had changed the value before the remaining 7 bytes are read.

An unsigned long is only 4 bytes. That is, until someone comes with a 64-bit Arduino platform.

5
  • 1
    Sure, a 64 bit Arduino with 2k of RAM :-)
    – PMF
    Apr 30, 2021 at 17:54
  • @Edgar Bonet ,Just as an aside ( I am actually writing a millis() like function for another uC ) : Is it valid, to say , use a lock bit to prevent read while timer is updating the variable , instead of disabling the interrupt? Thanks much !
    – EmbSysDev
    May 1, 2021 at 19:57
  • 1
    @EmbSysDev: There is no need to “prevent read while timer is updating the variable”: the ISR is not interruptible, so nothing can read the variable while it is being updated. You need to prevent the update while the main program is reading it. May 1, 2021 at 21:33
  • @EdgarBonet: cli() disables all interrupts, so too many calls to millis() would affect all interrupt based events.Would it not be sufficient to only disable TIM0 ? In the function they don't seem to be enabling the interrupts again, is it being done elsewhere(otherwise no interrupt would be enabled).Would make sense to enable the interrupts again before exiting millis() ? Thanks for your time !
    – EmbSysDev
    May 4, 2021 at 7:11
  • 1
    @EmbSysDev: You may indeed disable selectively TIM0, although that would take a few more cycles than cli(). This critical section is very short, so globally disabling interrupts is fine here. Re “they don't seem to be enabling the interrupts again”: that's what SREG = oldSREG; does: re-enable interrupts, but only if they were initially enabled when the function was called. May 4, 2021 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.