Timeout.attach() for longer times than 1hr 11m

14 Jan 2010

It looks like mbed's timeout.attach(), despite taking float number of seconds, is limited to 1hr 11m (0xFFFFFFFF microseconds). It looks like a limit on the internal conversion to 32-bit microseconds. Using timeout.attach() for tasks like SNTP for time synchronization requires longer timeouts. Frequent SNTP updates are discouraged by NTP.org, and it makes perfect sense to want to schedule SNTP updates say once a day (24 hrs = 0x141DD76000 us) or even once a week (168 hrs = 0x8CD0E3A000 us), given that MBED's RTC runs on its own quartz crystal. If tried, they all would end up firing after 1 hour 11 minutes if using timeout.attach().

14 Jan 2010 . Edited: 14 Jan 2010

Hi Ilya,

Yep, the timer3 that all the mbed timer related things hang off (Timer, Ticker, Timeout, wait) is ticking at 1us and is a 32-bit modulo counter. Therefore, the maximum delay is going to be 2^31 us (as it assumes half the range is "past" and half is "future").

For delays of the order us, ms, seconds, these are fine. If you are talking minutes, hours, days, that is more in the realms of an RTC as you suggest (or slower timers).

There is an argument to say the timer abstractions could be made to time any delay at any accuracy, but you get in to the realms of atomicity, interrupts and/or variable granularity to support that; certainly possible, but not sure it is the right solution; I'd be interested in what you think is the right solution or your "ideal" api would be for this application.

Simon

14 Jan 2010 . Edited: 14 Jan 2010

Hi Simon,

I agree that extending timers abstraction to handle times longer than few minutes is not the right solution. I have a sense that it will be very power inefficient for battery-operated applications. I think RTC is better suited for such use, since it will allow to keep the whole chip in deep sleep, as opposed to keep microsecond-scale timer running and waking up every microsecond.

I  think an ideal API for long times would be something like

rtc.attach(function_pointer, time_seconds);

- similar to the timeout API, but time_seconds should be the same type (time_t) and value would be as returned by time(NULL) when the RTC time is reached.

I am not familiar if there is a hardware provision on LPC1768 to set up something like an alarm (RTC interrupt at preset time?), but if there is something like that, it can be used for this task. Alternatively, a once-a-second interrupt from RTC (most chips with RTC have that) will also be good. What I did for DST in SNTP Client is a ticker once a second, that compares time(NULL) to the alarm value, and calls the handler if it is time. Ticker works functionally, but again, is not very power-efficient, compared to using RTC that would allow waking the chip from deep sleep only when it is time.

Few more thoughts... The API should probably allow multiple handlers at various times. Also, there should be detach (function_ptr) to remove specific handler (at all scheduled times), and maybe even detach(function_ptr, time_seconds) to detach specific handler at this specific time. For the RTC attach() API, the implementation should make sure to call any attached handlers if RTC is changed by set_time() beyond their time.

// RTC alarms example
rtc.attach(my_alarm1, time(NULL)+2*3600);    // schedule my_alarm1 for 2 hours from now
rtc.attach(my_alarm1, time(NULL)+2*24*3600); // schedule my_alarm1 for 2 days from now
rtc.attach(my_alarm2, time(NULL)+4*24*3600); // schedule my_alarm2 for 4 days from now  

rtc.detach(my_alarm1); // cancel all times for my_alarm1
rtc.attach(my_alarm1, time(NULL)+1*24*3600); // schedule my_alarm1 for 1 days from now 

 // now we have my_alarm1 scheduled for 1 day from now and my_alarm2 for 4 days from now 
rtc.detach();    // remove all alarms 

--

Ilya

14 Jan 2010

Hi Ilya,

I like it. It could be made exactly analogous to the virtualised Ticker/Timeout etc where you could have as many events as you want.

So perhaps there are alternates with "second" granularity; almost like RTCTicker, RTCTimeout, RTCTimer? Not quite sure that is right, but the general idea sounds good. It is also an abstraction that could be generally implemented; RTCs will have various mask/alarm functions, but an alarm at a specific time in the future would certainly be supported by all, so this approach would always work.

Simon

14 Jan 2010

Totally agree.

Ilya