[U-Boot] [RFC] Review of U-Boot timer API

J. William Campbell jwilliamcampbell at comcast.net
Tue May 24 17:23:21 CEST 2011


On 5/24/2011 7:12 AM, Wolfgang Denk wrote:
> Dear Albert ARIBAUD,
>
> In message<4DDB4C1C.7030301 at aribaud.net>  you wrote:
>> Not sure I still follow what the two options are -- a heads up is welcome.
>> However, I do like the simplicity in having a single time unit (ticks)
>> for the timer API -- asuming it covers all needs -- and providing other
>> time units only as helper functions.
> I don't think using ticks is a good idea.  You would need to change
> all definitiuons of timeouts and delays and such.
>
> Why not using a scaled unit like microsecods or the currently used
> milliseconds?
>
> I wonder why we suddenly have to change everything that has been
> working fine for more than a decade (ignoring the large number of
> incorrect, incomplete or broken implementations).  But so far we
> really never needed anything else but  udelay()  for the typical short
> device related timeouts, and  get_time()  for longer, often protocol
> defined,  timeouts.
>
> Is there anything wrong with these two solutions, based on standard
> units (us and ms) ?
Hi All,
         After really looking into this, I think I agree with Wolfgang 
that using ms for a get_timer timebase is the best way to go. This 
thinking is heavily influenced (in my case anyway) by the fact that in 
the interrupt driven cases (and these are the ONLY fully compliant cases 
ATM I think), the "cost" of using ms is 0, because that is the "native" 
unit in which the timer ticks. This makes everything real simple. We 
can, right today, produce an API that supports u32 get_time_ms(void) for 
all CPUs in use. This would allow u32 get_timer(u32 base) to continue to 
exist as-is. These implementations would still be technically "broken" 
in the non-interrupt case, but they would work at least as well as they 
presently do. In fact, they would operate better because they would all 
use a single routine, not a bunch of different routines (some of which I 
am pretty sure have errors). Wolfgang would need to accept the fact that 
we are not yet "fixing" all the non-interrupt cases. This needs to be 
done, but is a different problem (I hope). In the non-interrupt case 
there is some cost in converting to ms from the native units, but we are 
in a timout loop, so a few extra instructions do not matter much. It is 
only a few 32 bit multiplies, which these days are real fast. If we can 
figure out how to use interrupts eventually, even this will go away.

         Then, we can ADD an optional performance measuring API like 
Scott suggests. This API would be something similar to the following:
struct ticks
{
     u32    tickmsb;
     u32   ticklsb;
} ;
struct time_value
{
   u32 seconds;
   u 32 nano_seconds;
};


and the functions would be get_ticks(struct ticks * p) , 
get_tick_delta(struct ticks * minuend, struct ticks * subtrahend),  
and   cvt_tick_delta(struct time_value * result, struct ticks *input). I 
didn't use u64 on purpose, because I don't want any un-necessary 
functions pulled from the library. get_ticks reads a "hi precision" 
counter. How high the precision is depends on the hardware. 
get_tick_delta subtracts two tick values, leaving the difference in the 
first operand. Yes, this is may be simple to do in open code but it is 
better to hide the details. (What if msb is seconds and lsb is 
nanoseconds, then it is not so simple). cvt_tick_delta converts from 
ticks to seconds and nano_seconds. We also need a u32 
get_tick_resolution, which would return the tick resolution in ns. The 
user never needs to do any arithmetic on ticks, so that makes his life 
much easier. However, the user may want to know the resolution of these 
measurements. All these functions are quite fast except possibly 
cvt_tick_delta, which is only needed for printing anyway.
         If the hardware has a performance monitoring counter, 
implementing these functions is quite simple. The PPC and the x86 
certainly do (well, any x86 pentium and above anyway). This is a whole 
lot of chips off our plate. In cases where no such counter exists, we 
will use whatever counters there are available already. Some of the ARM 
counters are running at 32 kHz, so their resolution won't be great, but 
it is what it is. If we find out that some of these other CPUs have a 
performance counter, we will use it. This API will be completely 
optional in u-boot and can be removed by changing a #define.
Thoughts welcome.

Best Regards,
Bill Campbell

> Best regards,
>
> Wolfgang Denk
>



More information about the U-Boot mailing list