This is the mail archive of the
ecos-discuss@sourceware.cygnus.com
mailing list for the eCos project.
Re: Timer tick length
- To: Gary Thomas <gthomas at redhat dot com>
- Subject: Re: [ECOS] Timer tick length
- From: Jonathan Larmour <jlarmour at redhat dot co dot uk>
- Date: Tue, 04 Apr 2000 20:02:25 +0100
- CC: Grant Edwards <grante at visi dot com>, ecos-discuss at sourceware dot cygnus dot com
- Organization: Red Hat UK Ltd.
- References: <XFMail.000404123359.gthomas@redhat.com>
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