From: Graeme Russ <graeme.russ@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC] Review of U-Boot timer API
Date: Wed, 25 May 2011 02:51:57 +1000 [thread overview]
Message-ID: <4DDBE22D.6050806@gmail.com> (raw)
In-Reply-To: <20110524141950.2AB1CCF5DBF@gemini.denx.de>
On 25/05/11 00:19, Wolfgang Denk wrote:
> Dear Scott McNutt,
>
> In message <4DDBB29D.2050102@psyent.com> you wrote:
>>
>> Why must get_timer() be used to perform "meaningful time measurement?"
>
> Excellent question! It was never intended to be used as such.
Because get_timer() as it currently stands can as it is assumed to return
milliseconds
> Also, neither udelay() nor get_timer() make any warranties about
> accuracy or precision. If they are a few percent off, that's perfectly
> fine. Even if they are 10% off this is not a big problem anywhere.
>
>> If all of this is about time measurement, why not start with your dream
>> time measurement API, and go from there? And make it an optional
>> feature.
>
> D'acore.
>
>> If the existing API, that has been used successfully for years,
>> primarily as a mechanism for detecting a time-out, has issues,
>> then let's resolve _those_ issues and avoid the "car-boat" ... the
>> vehicle that floats like a car and handles like a boat. ;-)
>
> :-)
OK, let's wind back - My original suggestion made no claim towards changing
what the API is used for, or how it looks to those who use it (for all
practical intents and purposes). I suggested:
- Removing set_timer() and reset_timer()
- Implement get_timer() as a platform independent function
Lets look at two real-world implementations of my suggested solution - One
which 'exposes' ticks and one which does not..
=============
Exposing ticks and tick_frequency to everyone via a 'tick' HAL
In /lib/timer.c
void prescaler(void)
{
u32 ticks = get_ticks();
u32 tick_frequency = get_tick_frequency();
/* Bill's algorithm */
/* result stored in gd->timer_in_ms; */
}
u32 get_timer(u32 base)
{
prescaler(ticks, tick_frequency);
return gd->timer_in_ms - 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;
}
=======================
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 16:51 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 [this message]
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=4DDBE22D.6050806@gmail.com \
--to=graeme.russ@gmail.com \
--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