From: J. William Campbell <jwilliamcampbell@comcast.net>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC] Review of U-Boot timer API
Date: Tue, 24 May 2011 11:59:01 -0700 [thread overview]
Message-ID: <4DDBFFF5.1020601@comcast.net> (raw)
In-Reply-To: <4DDBE22D.6050806@gmail.com>
On 5/24/2011 9:51 AM, Graeme Russ wrote:
> On 25/05/11 00:19, Wolfgang Denk wrote:
> =============
<snip>
Hi all,
I have a few of questions.
First, it seems that the get_timer interface is expected to work
properly only after relocation and only when bss is available. I say
this because the PPC version uses an (initialized) variable, timestamp,
to hold the time. If that is the case, there is no need to hold the
timer static data in gd, as I have been doing up to now. Am I correct ?
Second, udelay is expected to be available before bss is
available, very early in the startup process. There a comments to that
effect in several places in the code. Therefore, udelay cannot use
global or static variables. Is this true?
And third, udelay is only expected/required to work correctly for
"short", like say 10 seconds. I say this based on comments contained in
powerpr/lib/time.c. Please ack or nak this as well.
I have a couple of "small" changes to the previously submitted code,
based partly on the above
> Exposing ticks and tick_frequency to everyone via a 'tick' HAL
>
> In /lib/timer.c
ulong timestamp = 0;
/*
This routine is called to initialize the timer after BSS is available
*/
void __weak prescaler_init(void)
{
u32 tick_frequency = get_tick_frequency();
/* initialize prescaler variables */
}
> void __weak prescaler(void)
> {
> u32 ticks = get_ticks();
/* Bill's algorithm */
/* result stored in timestamp; */
> }
>
> u32 get_timer(u32 base)
> {
#if defined(CONFIG_SYS_NEED_PRESCALER)
> prescaler();
#endif
> return timestamp - base;
> }
>
> In /arch/cpu/soc/timer.c or /arch/cpu/timer.c or /board/<board>/timer.c
>
> u32 get_ticks(void)
> {
> u32 ticks;
>
> /* Get ticks from hardware counter */
>
> return ticks;
> }
>
> u32 get_tick_frequency(void)
> {
> u32 tick_frequency;
>
> /* Determine tick frequency - likely very trivial */
>
> return tick_frequency;
> }
or instead the user may override prescaler_init and prescaler if, for
some reason, a highly optimized version is desired. Note also that if
the configuration variable CONFIG_SYS_NEED_PRESCALER is not defined, the
additional prescaler routines will not be called anywhere so the
routines should not be loaded. Yes, it it a #define to manage, but it
should allow the existing u-boots to be the same size as before, with no
unused code. This size matters to some people a lot!
> =======================
> Not exposing ticks and tick_frequency to everyone
>
> In /lib/timer.c
>
> void prescaler(u32 ticks, u32 tick_frequency)
> {
> u32 current_ms;
>
> /* Bill's algorithm */
>
> /* result stored in gd->timer_in_ms; */
> }
>
> In /arch/cpu/soc/timer.c or /arch/cpu/timer.c or /board/<board>/timer.c
>
> static u32 get_ticks(void)
> {
> u32 ticks;
>
> /* Get ticks from hardware counter */
>
> return ticks;
> }
>
> static u32 get_tick_frequency(void)
> {
> u32 tick_frequency;
>
> /* Determine tick frequency */
>
> return tick_frequency;
> }
>
> u32 get_timer(u32 base)
> {
> u32 ticks = get_ticks();
> u32 tick_frequency = get_tick_frequency();
>
> prescaler(ticks, tick_frequency);
>
> return gd->timer_in_ms - base;
> }
>
> ===============
> I personally prefer the first - There is only one implementation of
> get_timer() in the entire code and the platform implementer never has to
> concern themselves with what the tick counter is used for. If the API gets
> extended to include get_timer_in_seconds() there is ZERO impact on
> platforms. Using the second method, any new feature would have to be
> implemented on all platforms - and we all know how well that works ;)
>
> And what about those few platforms that are actually capable of generating
> a 1ms timebase (either via interrupts or natively in a hardware counter)
> without the prescaler? Well, with prescaler() declared weak, all you need
> to do in /arch/cpu/soc/timer.c or /arch/cpu/timer.c or
> /board/<board>/timer.c is:
>
> For platforms with a 1ms hardware counter:
> void prescaler(void /* or u32 ticks, u32 tick_frequency*/)
> {
> gd->timer_in_ms = get_milliseconds();
> }
>
> For platforms with a 1ms interrupt source:
> void timer_isr(void *unused)
> {
> gd->timer_in_ms++;
> }
>
> void prescaler(void /* or u32 ticks, u32 tick_frequency*/)
> {
> }
>
>
> And finally, if the platform supports interrupts but either the hardware
> counter has better accuracy than the interrupt generator or the interrupt
> generator cannot generate 1ms interrupts, configure the interrupt generator
> to fire at any rate better than the tick counter rollover listed in
> previous post and:
>
> void timer_isr(void *unused)
> {
> /*
> * We are here to stop the tick counter rolling over. All we
> * need to do is kick the prescaler - get_timer() does that :)
> */
> get_timer(0);
> }
>
> In summary, platform specific code reduces to:
> - For a platform that cannot generate 1ms interrupts AND the hardware
> counter is not in ms
> - Implement get_ticks() and get_tick_frequency()
> - Optionally implement as ISR to kick the prescaler
> - For a platform that can generate 1ms interrupts, or the hardware
> counter is in ms
> - Override the prescaler() function to do nothing
>
> If none of the above not look 'simple', I invite you to have a look in
> arch/arm ;)
>
> Regards,
>
> Graeme
>
>
next prev parent reply other threads:[~2011-05-24 18:59 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
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 [this message]
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=4DDBFFF5.1020601@comcast.net \
--to=jwilliamcampbell@comcast.net \
--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