[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