[U-Boot] [RFC][Timer API] Revised Specification - Implementation details
Graeme Russ
graeme.russ at gmail.com
Fri May 27 00:51:35 CEST 2011
On Fri, May 27, 2011 at 3:49 AM, Wolfgang Denk <wd at denx.de> wrote:
> 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.
I am sure there has been confusion with a misunderstanding the the
tick counter is NOT interrupt driven
>> - 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...
>
I think we should - If CONFIG_SYS_HZ _MUST_ be 1000 anyway, what is the
point. Also, get_timer() utilisation as it stands for the most part already
assumes a 1ms time base. Maybe we should change get_timer() to
get_ms_timer() to avoid any ambiguity
>> 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?
Yes, I think you are right
> 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.
Correct
>> 'Helper' Functions (/lib/timer.c)
>> - void sync_timebase(void)
>
> Can be a macro (to avoid call overhead).
True
>> - 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.
Can do - And that would mean a sync_us_timer() would call usec2ticks(1)
>> - 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().
OK
Regards,
Graeme
More information about the U-Boot
mailing list