64bit OS time

Discussions and support about ChibiOS/RT, the free embedded RTOS.
Thargon
Posts: 109
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 11 times
Been thanked: 19 times

Re: 64bit OS time

Postby Thargon » Wed Jul 08, 2020 8:29 pm

I implemented the feature some time ago in my project. Just have a look at the _systimer in my code (https://opensource.cit-ec.de/projects/a ... s_system.c).

The idea is quite simple. That virtual timer fires periodically, accumulates the _uptime value (64 bit, us precision) and saves the according systime_t (_synctime) value when this accumulation was done. Whenever the uptime is retrieved via the aosSysGetUptimeX() function, the current delta to _synctime is added to _uptime.

As result, retrieving the current system uptime involves "only" a 64 bit add. Accumulation however can be quite expensive if the hardware timer overflows quickly (e.g. 16 bit timer @ 1MHz). In my code, however, you can set the timer to an arbitrary frequency/precision and calculation of the uptime automatically maps everything to us precision. Further note that the timer period is defined as (TIME_MAX_SYSTIME - CH_CFG_ST_TIMEDELTA) so the ISR never misses an overflow.

- Thomas

User avatar
Giovanni
Site Admin
Posts: 12945
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 731 times
Been thanked: 609 times
Contact:

Re: 64bit OS time

Postby Giovanni » Wed Jul 08, 2020 8:35 pm

This is not working, it needs some extra checks because "lasttime" needs to be updated, it impacts virtual timers. Needs some more thinking but I would like to have time stamps as a service in the OS if it can be done on top of existing code.

Giovanni

Giovanni wrote:Assuming you don't need to "poll" the counter value but only get stamps: Just make the difference between "lasttime" and "now" when you need your stamp, add this value to your counter. No need to use the hook I think, you need to do this at least one time for each systime wrap.

Under those assumptions it could become a std functionality I think, something like:

Code: Select all

volatile systamp_t last_stamp = 0ULL;

sysstamp_t chVTGetTimeStamp(void) {

  chSysLock();
  stamp = last_stamp;
  stamp += (sysstamp_t)chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX());
  last_stamp = stamp;
  chSysUnlock();
 
  return stamp;
}


Not yet sure, to be verified. Note that it would fail if system time wrapped 2 times. A wrap counter could be added to be checked in an assertion.

Giovanni

Thargon
Posts: 109
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 11 times
Been thanked: 19 times

Re: 64bit OS time

Postby Thargon » Thu Jul 09, 2020 7:35 am

Just put some more thought in the topic and realized that my solution could be enhanced to some kind of "almost tickless" mode, allowing for timers and timeouts of arbitrary duration.

First off, the accumulation ISR actually is a periodic tick. Now, whenever a timer is set or a timeout was specified, the according functions can check, whether the interval fits into a single accumulation period, thus it can be mapped directly to the hardware timer. In case the interval is longer, it can be 'postponed' and put into an ordered queue, which is evaluated by the accumulation ISR. Any timers and timeouts that would fire within the next accumulation period are then 'activated' by the ISR.

pros:
  • timers and timeouts of arbitrary duration
  • high-precision timing (potentially sub us) due to 64 bit representation of time
cons:
  • complexity of accumulation ISR scales linearly with the length of the queue, potentially introducing strong jitter to the system
  • 64 bit time is generally more expensive (memory + CPU) than systime_t
Some further notes on the complexity: In my project, I implemented some more advanced timers, which already allow arbitrary intervals. However, each timer ticks at least once per accumulation period and reactivates itself as long as the remaining interval cannot be represented by the hardware timer. On the one hand, this "distributed approach" is in total more expensive than the "central approach" I just described, due to the lots of ISRs (one per VT). On the other hand, though, each of those ISRs is very brief and of constant complexity, thus providing better performance in terms of jitter. Personally, I don't think that the worse jitter of the "central approach" is a real issue for most cases, but it's something to consider. If want to go all in when implementing the feature in ChibiOS, there could even be a compile switch to select between those modes (standard, tickless, almost tickless w/ distributed queues, almost tickles w/ central queue).

Thargon wrote:I implemented the feature some time ago in my project. Just have a look at the _systimer in my code (https://opensource.cit-ec.de/projects/a ... s_system.c).

The idea is quite simple. That virtual timer fires periodically, accumulates the _uptime value (64 bit, us precision) and saves the according systime_t (_synctime) value when this accumulation was done. Whenever the uptime is retrieved via the aosSysGetUptimeX() function, the current delta to _synctime is added to _uptime.

As result, retrieving the current system uptime involves "only" a 64 bit add. Accumulation however can be quite expensive if the hardware timer overflows quickly (e.g. 16 bit timer @ 1MHz). In my code, however, you can set the timer to an arbitrary frequency/precision and calculation of the uptime automatically maps everything to us precision. Further note that the timer period is defined as (TIME_MAX_SYSTIME - CH_CFG_ST_TIMEDELTA) so the ISR never misses an overflow.

- Thomas

User avatar
FXCoder
Posts: 267
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 106 times
Been thanked: 85 times

Re: 64bit OS time

Postby FXCoder » Thu Jul 09, 2020 7:59 am

Giovanni wrote:
Not yet sure, to be verified. Note that it would fail if system time wrapped 2 times. A wrap counter could be added to be checked in an assertion.


Having a wrap count (uint64) for systime would be useful in making the uptime (for logging) calculation straightforward.
Just use it as in the calculation...
(uint64_t)uptime = syswrap << CH_CFG_ST_RESOLUTION + systime;
Or is that too simple?

User avatar
Giovanni
Site Admin
Posts: 12945
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 731 times
Been thanked: 609 times
Contact:

Re: 64bit OS time

Postby Giovanni » Sat Jul 11, 2020 7:20 am

I made something slightly different, lets discuss it here: viewtopic.php?f=3&t=5589

Giovanni


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 5 guests