Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The function millis() rolls over in about 72 minutes. Is there an alternative with longer rollover time/no rollover? #675

Closed
yunjova opened this issue Mar 31, 2016 · 7 comments

Comments

@yunjova
Copy link

yunjova commented Mar 31, 2016

The function millis() rolls over in about 72 minutes.
This is because it is based on a microseconds timing and 32-bit counter.

Is there an alternative with longer rollover time/no rollover?

@patrickjahns
Copy link
Member

No - but explain what you are trying to achieve so we can maybe assist you. This limitation should not cause any issues

@yunjova
Copy link
Author

yunjova commented Apr 4, 2016

One reason to make it longer would be to make it compatible with Arduino (which this library wants to be - I guess). The Arduino millis() is based on a 32-bit milliseconds counter making it roll over in about 49 days.

What I try to achieve is to measure the server's uptime. That's why I used the millis() function. I know the 49 days is still not enough. With the current millis() rolling over at 72 minutes, I was thinking that my server had restarted. Deeper investigation revealed that the millis() is different from the 49 days that I expected (Arduino experience - there will be more people that will experience this).

If the counter would be 64 bit wide then, based on the microsecond increment, the roll over would not happen in the first 500000 years. This would be OK for most practical cases.

It will be good to have this as a general feature in the Sming libraries - I think that also other people will benefit from this.

@patrickjahns
Copy link
Member

For tracking uptime you can use SystemClock (and NTP Client if you want the proper date/time with it)

Are you noticing the rollover on millis() or micros() ? micros should be 72minutes and millies 49days.

Either way, as you noticed even on arduino platforms you have a rollover - so wether or not it occurs every 72 minutes or every X days does not make a difference when it comes to code design - both need to account for a rollover to properly work.

The downside of utilizing a 64bit variable is, that the esp only has a 32bit fpu - so it would take a lot of extra clock cycles just for incrementing a counter. I don`t believe that is a good solution.

Just out of interest - what other use cases besides of calculating the difference between two millis() calls can you think of? (as mentioned uptime can be tracked with SystemClock)

@yunjova
Copy link
Author

yunjova commented Apr 4, 2016

Compatibility:
millis() on ESP8266 has a roll over of 72 minutes. (Based on microsecond tick.)
millis() on Arduino (AVR) has a roll over of 49 days. (Based on millisecond tick.)
I think these two should best be in-line, or at least be well documented just to avoid people have to experience the difference and then find a solution. E.g. On Arduino a controlled restart every day works to avoid the roll over, the same code on an ESP8266 will fail.

For the moment I only want to track the uptime, so I will have a look at the SystemClock that you suggested.

@patrickjahns
Copy link
Member

I had a look at the code - the "problem" currently is, that millis() relies on system_get_time() from espressif SDK which is a 32bit Integer and cannot be changed.

In order to create your feature - you will require a counter that tracks the amount of overflows and returns the proper value. I don`t see this needed/required since long running tasks can properly be done via timers and/or systemclock.

But you are right - the documentation will need to be updated to reflect the behavior - currently it states:


/** @brief  Get the time from clock in milliseconds
 *  @retval "unsigned long" Quantity of milliseconds elapsed since clock epoch
 *  @note   Clock epoch will reset every 49 days, 17 hours, 2 minutes, 47 seconds, 296 milliseconds
 */
unsigned long millis(void);

@hreintke hreintke added the Ideas label Apr 22, 2016
@hreintke
Copy link
Contributor

Issue resolved, The erroneous documentation has not been ported to SmingRTOS.

@hreintke hreintke removed the Ideas label May 23, 2016
@pumpindex
Copy link

it mat be useful;
http://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants