[U-Boot] [RFC][Timer API] Revised Specification - Implementation details

Wolfgang Denk wd at denx.de
Thu May 26 19:49:01 CEST 2011


Dear Graeme Russ,

In message <4DDE5548.3020906 at gmail.com> you wrote:
> 
> Assumed Capabilities of the Platform
>  - Has a 'tick counter' that does not rely on software to increment

I think we should delete the "does not rely on software to increment"
part. It is not really essential.

>  - tick interval may by a fixed constant which cannot be controlled
>    via software, or it could be programmable (PIT)
> 
> API Functions (/lib/timer.c)
>  - u32 get_timer(u32 start)
>     - Returns the number of elapsed milliseconds since 'start'

If you really want to make the code flexible, then say
	"returns the number of "1/CONFIG_SYS_HZ" time units since
	'start'"

	The 1 ms resolution is actually tied to the CONFIG_SYS_HZ
	definition (which is the reason why I always fought that
	CONFIG_SYS_HZ must be defined as 1000).

	Of course we could also drop this definition completely...

> API Functions (/arch/...)
>  - void udelay(u32 delay)
>     - Used for 'short' delays (generally up to several seconds)

	no.  only good for delays well below one second.

>     - Can use the tick counter if it is fast enough
>     - MUST NOT RESET THE TICK COUNTER

Should ne not state that the tick counter must never be reset during
the life-time -f U-Boot?

We should also note that neither get_timer() nor udelay() make any
guarantee for the precision of the returned timing information, except
that udelay(N) is always supposed to delay for _at_least_ N
microseconds.

> 'Helper' Functions (/lib/timer.c)
>  - void sync_timebase(void)

Can be a macro (to avoid call overhead).

>     - Updates the millisecond timer

We need to define that term.. Eventually you want to change the
definition of get_timer() into "returns the content of the millisecond
timer" or similar.

>     - Utilises HAL functions to access the platform's tick counter
>     - Must be called more often than the rollover period of the
>       platform's tick counter
>     - Does not need to be called with a regular frequency (immune
>       to interrupt skew)
>     - Is always called by get_timer()
>     - For platforms with short tick counter rollovers it should
>       be called by an ISR
>     - Bill Campbell wrote a good example which proved this can be common
>       and arbitrary (and optionally free of divides and capable of
>       maintaining accuracy even if the tick frequency is not an even
>       division of 1ms)
> 
> HAL Functions (/arch/... or /board/...)
>  - u64 get_ticks(void)
>     - Returns a tick count as an unsigned 64-bit integer
>     - Abstracts the implementation of the platform tick counter
>       (platform may by 32-bit 3MHz counter, might be a 16-bit
>       0-999 microsecond plus 16-bit 0-65535 millisecond etc)
>  - u64 ticks_per_millisecond()
>     - Returns the number of ticks (as returned by get_ticks()) per
>       millisecond

I recommend to stick with the existing ticks2usec() and usec2ticks();
you can then use usec2ticks(1000) to get the ticks per millisecond.

>  - void timer_isr()
>     - Optional (particularly if tick counter rollover period is
>       exceptionally log which is usually the case for native 64-bit tick
>       counters)
>     - Simply calls sync_timebase()
>     - For platforms without any tick counter, this can implement one
>       (but accuracy will be harmed due to usage of disable_interrupts() and
>       enable_interrupts() in U-Boot
> 
> So to get the new API up and running, only two functions are mandatory:
> 
> get_ticks() which reads the hardware tick counter and deals with any 'funny
> stuff' including rollovers, short timers (12-bit for example), composite
> counters (16-bit 0-999 microsecond + 16-bit millisecond) and maintains a
> 'clean' 64-bit tick counter which rolls over from all 1's to all 0's. The
> 64-bit tick counter does not need to be reset to zero ever (even on startup
> - sync_timebase tacks care of all the details)
> 
> ticks_per_millisecond() simply return the number of ticks in a millisecond
> - This may as simple as:
> 
> inline u64 ticks_per_millisecond(void)
> {
> 	return CONFIG_SYS_TICK_PER_MS;
> }

Better move this part up to the description of usec2ticks() / ticks2usec().


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"There are three principal ways to lose money: wine, women,  and  en-
gineers.  While  the first two are more pleasant, the third is by far
the more certain."                      -- Baron Rothschild, ca. 1800


More information about the U-Boot mailing list