Skip to main content.

The (new) U-Boot Timer API

Being worked on by: Graeme Russ

The 'Old' API

Overview

U-Boot currently has a timer API consisting of the following functions:

Problems and Limitations

The 'New' API Proposal

At the core of the new API is two user-level functions per defined time base:

Three 'time bases' are initially proposed:

User API (/lib/timer.c)

                         %        #^        !&        @
          -----|---------|---------|---------|---------|------
               0         10        20        30        40

Using the User API

  1. Timeout Detection - Don't want to timeout early, so need to know the minimum time elapsed

        u32 start;
        u32 now;
        u32 timeout = 5 /* milliseconds */

        start_execute_command();

        start = timer_ms_now();

        while (!command_complete()) {
                now = timer_ms_now();
                if (time_ms_delta(start, now, TIME_DELTA_MIN)> timeout)
                        handle_timeout();

                udelay(100);
        }
  1. Timing Duration of an Activity - Useful for performance profiling, so need to know the maximum possible time taken

        u32 start;
        u32 end;
        u32 duration;

        start = timer_ms_now();

        do_something_complicated();

        end = timer_ms_now();

        duration = time_ms_delta(start, end, TIME_DELTA_MAX);

        printf("execution time: %ld millisec\n", duration);

A Note about Accuracy and 'Recursion'

The U-Boot Timer API make no guarantees regarding accuracy - It is provided as a means of performing operations that are known to require a minimum amount of time (hardware timeouts such as Flash operations in particular). Platform implementors must ensure that for any two calls to time_ms_now(), AT LEAST x milliseconds pass (in real time) where 'x' is the difference in the return value of the two calls - It is acceptable for the underlying hardware timer to run slow, but not fast.

Any further accuracy guarantees are highly platform specific. Individual platform implementors are free to document accuracy claims, but this is by no means a requirement.

Another important aspect of the Timer API is the ability to run timing loops inside other timing loops (recursive timing)

Behind the Scenes of the User API

        #define TIME_DELTA_MIN 0x00
        #define TIME_DELTA_MAX 0x01
        #define TIME_DELTA_RAW 0x02

        u32 time_ms_delta(u32 from, u32 to, u8 round)
        {
                u32 delta = to - from;

                if (round == TIME_DELTA_RAW) /* raw result, no rounding*/
                        return delta;

                if (round == TIME_DELTA_MAX) /* round up */
                        return delta + time_ms_resolution();

                /* round down */
                if (delta < time_ms_resolution())
                        return 0;

                return delta - time_ms_resolution();
        }

        __attribute__((weak))
        u32 time_ms_resolution(void) {return 1;}

-- GraemeRuss - 03 Jun 2011