From: Reinhard Meyer <u-boot@emk-elektronik.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC] Review of U-Boot timer API
Date: Mon, 23 May 2011 05:26:07 +0200 [thread overview]
Message-ID: <4DD9D3CF.2070600@emk-elektronik.de> (raw)
In-Reply-To: <4DD9A6F7.1040509@comcast.net>
Dear J. William Campbell,
> On 5/22/2011 1:15 AM, Reinhard Meyer wrote:
>> Dear J. William Campbell,
>>
>> please demonstrate for me (and others), by a practical example,
>> how _any_ arithmetic (even less with just shifts and multiplies)
>> can convert a free running 3.576 MHz (wild example) free running
>> 32 bit counter (maybe software extended to 64 bits) into a ms
>> value that will properly wrap from 2**32-1 to 0 ?
> Hi All
> I accept the challenge! I will present two ways to do this, one using a 32 bit by 16 bit divide, and one using only multiplies.
> This first method is "exact", in that there is no difference in performance from a "hardware" counter ticking at the 1 ms rate. This is accomplished by operating the 1 ms counter based on the delta time in the hardware time base. It is necessary to call this routine often enough that the hardware counter does not wrap more than once between calls. This is not really a problem, as this time is 1201 seconds or so. If the routine is not called for a long time, or at the first call, it will return a timer_in_ms value that will work for all subsequent calls that are within a hardware rollover interval. Since the timer in ms is a 32 bit number anyway. The same rollover issue will exist if you "software extend" the timer to 64 bits. You must assume 1 rollover. If it is more than 1, the timer is wrong.
>
>
> The variables in the gd are
> u32 prev_timer;
> u32 timer_in_ms;
> u16 timer_remainder;
>
> /* gd->timer remainder must be initialized to 0 (actually, an number less than 3576, but 0 is nice). Other two variables don't matter but can be initialized if desired */
>
> u32 get_raw_ms()
> {
> u32 delta;
> u32 t_save;
>
> read(t_save); /* atomic read of the hardware 32 bit timer running at 3.576 MHz */
> delta_t = (t_save - gd->prev_timer) ;
>
> gd->prev_timer = t_save;
> /*
> Hopefully, the following two lines only results in one hardware divide when optimized. If your CPU has no hardware divide, or if it slow, see second method .
> */
> gd->timer_in_ms += delta_t / 3576; /* convert elapsed time to ms */
> gd->timer_remainder += delta_t % 3576; /* add in remaining part not included above */
> if (gd->timer_remainder >= 3576) /* a carry has been detected */
> {
> ++gd->timer_in_ms;
> gd->timer_remainder -= 3576; /* fix remainder for the carry above */
> }
>
> return(gd->timer_in_ms)
> }
Thank you! Basically this is similar to a Bresenham Algorithm.
>
> This approach works well when the number of ticks per ms is an exact number representable as a small integer, as it is in this case. It is exact with a clock rate of 600 MHz, but is not exact for a clock rate of 666 MHz. 666667 is not an exact estimate of ticks per ms, It is off by 0.00005 % That should be acceptable for use as a timeout delay. The accumulated error in a 10 second delay should be less than 0.5 ms.
I would think the non exact cases result in such a small error that can be
tolerated. We are using the ms tick for timeouts, not for providing a clock
or exact delays. We should just round up when calculating the divider.
Hence the hick-ups that result when this is not called frequent enough to
prevent a multiple rollover of the raw value between calls do not matter
either (they should be just documented).
>
> There is a way that the divide above can be approximated by multiplying by an appropriate fraction, taking the resulting delta t in ms, multiplying it by 3576, and subtracting the product from the original delta to get the remainder. This is the way to go if your CPU divides slowly or not at all. This approach is presented below.
>
[...]
Optimizations would be up to the implementer of such a hardware and work
only if the divider is a compile time constant. Often the divider will be
run time determined (AT91 for example).
Reinhard
next prev parent reply other threads:[~2011-05-23 3:26 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-21 12:38 [U-Boot] [RFC] Review of U-Boot timer API Graeme Russ
[not found] ` <4DD7DB64.70605@comcast.net>
2011-05-22 0:06 ` Graeme Russ
2011-05-22 0:43 ` J. William Campbell
2011-05-22 4:26 ` Reinhard Meyer
2011-05-22 6:23 ` Graeme Russ
2011-05-22 7:21 ` J. William Campbell
2011-05-22 7:44 ` Graeme Russ
2011-05-22 8:15 ` Reinhard Meyer
2011-05-23 0:02 ` Graeme Russ
2011-05-23 0:20 ` J. William Campbell
2011-05-23 0:14 ` J. William Campbell
2011-05-23 1:00 ` Graeme Russ
[not found] ` <4DD9B608.7080307@comcast.net>
2011-05-23 1:42 ` Graeme Russ
2011-05-23 5:02 ` J. William Campbell
2011-05-23 5:25 ` Graeme Russ
2011-05-23 6:29 ` Albert ARIBAUD
2011-05-23 10:53 ` Graeme Russ
2011-05-23 16:22 ` J. William Campbell
2011-05-23 12:09 ` Wolfgang Denk
2011-05-23 12:29 ` Graeme Russ
2011-05-23 13:19 ` Wolfgang Denk
2011-05-23 17:30 ` J. William Campbell
2011-05-23 18:24 ` Albert ARIBAUD
2011-05-23 19:18 ` Wolfgang Denk
2011-05-23 18:27 ` J. William Campbell
2011-05-23 19:33 ` Wolfgang Denk
2011-05-23 20:26 ` J. William Campbell
2011-05-23 21:51 ` Wolfgang Denk
2011-05-23 20:48 ` Graeme Russ
2011-05-23 3:26 ` Reinhard Meyer [this message]
2011-05-23 5:20 ` J. William Campbell
2011-05-22 6:57 ` J. William Campbell
2011-05-23 12:13 ` Wolfgang Denk
2011-05-24 3:42 ` Mike Frysinger
2011-05-24 4:07 ` Graeme Russ
2011-05-24 4:24 ` Mike Frysinger
2011-05-24 4:35 ` Graeme Russ
2011-05-24 5:31 ` Reinhard Meyer
2011-05-24 5:43 ` Graeme Russ
2011-05-24 6:11 ` Albert ARIBAUD
2011-05-24 7:10 ` Graeme Russ
2011-05-24 14:15 ` Wolfgang Denk
2011-05-24 14:12 ` Wolfgang Denk
2011-05-24 15:23 ` J. William Campbell
2011-05-24 19:09 ` Wolfgang Denk
2011-05-24 13:29 ` Scott McNutt
2011-05-24 14:19 ` Wolfgang Denk
2011-05-24 16:51 ` Graeme Russ
2011-05-24 18:59 ` J. William Campbell
2011-05-24 19:31 ` Wolfgang Denk
2011-05-24 19:19 ` Wolfgang Denk
2011-05-24 22:32 ` J. William Campbell
2011-05-25 5:17 ` Wolfgang Denk
2011-05-25 16:50 ` J. William Campbell
2011-05-25 19:56 ` Wolfgang Denk
2011-05-25 0:17 ` Graeme Russ
2011-05-25 2:53 ` J. William Campbell
2011-05-25 3:21 ` Graeme Russ
2011-05-25 5:28 ` Wolfgang Denk
2011-05-25 6:06 ` Graeme Russ
2011-05-25 8:08 ` Wolfgang Denk
2011-05-25 8:38 ` Graeme Russ
2011-05-25 11:37 ` Wolfgang Denk
2011-05-25 11:52 ` Graeme Russ
2011-05-25 12:26 ` Wolfgang Denk
2011-05-25 12:42 ` Graeme Russ
2011-05-25 12:59 ` Wolfgang Denk
2011-05-25 13:14 ` Graeme Russ
2011-05-25 13:38 ` Wolfgang Denk
2011-05-25 21:11 ` Graeme Russ
2011-05-25 21:16 ` Wolfgang Denk
2011-05-25 23:13 ` Graeme Russ
2011-05-26 0:15 ` J. William Campbell
2011-05-26 0:33 ` Graeme Russ
2011-05-26 4:19 ` Reinhard Meyer
2011-05-26 4:40 ` Graeme Russ
2011-05-26 5:03 ` J. William Campbell
2011-05-26 5:16 ` Wolfgang Denk
2011-05-26 5:25 ` Graeme Russ
2011-05-26 5:55 ` Albert ARIBAUD
2011-05-26 6:18 ` Graeme Russ
2011-05-26 6:36 ` Reinhard Meyer
2011-05-26 8:48 ` Wolfgang Denk
2011-05-26 9:02 ` Graeme Russ
2011-05-26 4:54 ` J. William Campbell
2011-05-25 5:25 ` Wolfgang Denk
2011-05-25 6:02 ` Graeme Russ
2011-05-25 8:06 ` Wolfgang Denk
2011-05-25 8:26 ` Graeme Russ
2011-05-25 11:32 ` Wolfgang Denk
2011-05-25 11:53 ` Graeme Russ
2011-05-25 12:27 ` Wolfgang Denk
2011-05-25 12:36 ` Scott McNutt
2011-05-25 12:43 ` Graeme Russ
2011-05-25 13:08 ` Scott McNutt
2011-05-25 13:16 ` Graeme Russ
2011-05-25 13:46 ` Scott McNutt
2011-05-25 14:21 ` Graeme Russ
2011-05-25 19:46 ` Wolfgang Denk
2011-05-25 20:40 ` J. William Campbell
2011-05-25 20:48 ` Wolfgang Denk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DD9D3CF.2070600@emk-elektronik.de \
--to=u-boot@emk-elektronik.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox