This is the mail archive of the ecos-discuss@sourceware.cygnus.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Timer tick length


Gary Thomas wrote:
> >
> > The problem of application code not knowing how long a "tick"
> > is seems to keep popping up.  In most other RTOS systems I've
> > used, there was a constant or a pair of macros defined in a
> > header that allowed application code to convert between ticks
> > and "real" time (seconds or milliseconds).  This allowed one to
> > write code that didn't break when the length of a clock tick
> > was changed.
> 
> The information _is_ there, it's just not pretty.
> 
> Here's how to get at it (culled from ecc/kernel/XXX/tests/tm_basic.cxx):
> 
>   #include <pkgconf/kernel.h>
> 
>   long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
>   long ns_per_system_clock;
> 
>   // To convert system clock 'ticks' to nanoseconds (ns)
>   ns_per_system_clock = 1000000/rtc_resolution[1];
>   ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
> 
> Does this suffice?

Actually there's something even more relevant in <cyg/kernel/clock.hxx> for
the Cyg_Clock class:

    // There is a need for converting from "other" ticks to clock ticks.
    // We will construct 4 numbers to do the conversion as:
    //   clock_ticks = (((otherticks*mul1)/div1)*mul2/div2)
    // with the values chosen to minimize the possibility of overflow.
    // Do the arithmetic in cyg_uint64s throughout.
    struct converter {
        cyg_uint64 mul1, div1, mul2, div2;
    };
 
    // There are two of these because the 4 numbers are different depending
    // on the direction of the conversion, to prevent loss of significance.
    // NB these relate to the resolution of the clock object they are
    // called against, not necessarily "the" system real time clock.
    void get_other_to_clock_converter( cyg_uint64 ns_per_other_tick,
                                       struct converter *pcc );
 
    void get_clock_to_other_converter( cyg_uint64 ns_per_other_tick,
                                       struct converter *pcc );
 
    // A utility to perform the conversion in the obvious way, with
    // rounding to nearest at each stage.  Static because it uses a
    // previously acquired converter.
    static cyg_tick_count convert( cyg_tick_count value,
                                   struct converter *pcc );


The interface is a bit abstract but I believe the principle is that, if you
wanted to find the number of ns per clock tick, you could then go (I
think):

struct pcc;
cyg_tick_count ns_per_tick;

Cyg_Clock::real_time_clock->get_clock_to_other_convertor( 1, &pcc);
ns_per_tick = Cyg_Clock::convert(1, &pcc);

Looking at the clockcnv.cxx test may help too, but that's also a bit
esoteric :). Have a play...

Admittedly these functions haven't been brought out as KAPI functions. But
the advantage is that you are dealing with this at a much higher level, not
the _real_ kernel internals, and making too many assumptions.

The fact that we don't use this ourselves is simply because it's a bit of
cleanup that hasn't been done since the functionality was added.

Jifl
-- 
Red Hat, 35 Cambridge Place, Cambridge, UK. CB2 1NS  Tel: +44 (1223) 728762
"Plan to be spontaneous tomorrow."  ||  These opinions are all my own fault

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]