This is the mail archive of the ecos-discuss@sources.redhat.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]
Other format: [Raw text]

RE: More Wallclock questions


Hi.

This discussion comes just in right time for me.
In this moment I'm trying to implement wallclock driver for my MIPS based
board.

Grant Edwards wrote:
> What I had expected was that eCos would set it's system time
> based on the HW clock at startup, and from then on, the eCos
> system time would be used for everything: time() and
> cyg_current_time() would be referencing the same time-base.

Jonathan Larmour wrote:
> Yes this is something we've known about, but have never gotten round to
> fixing[1]. time() should be instantiated from the wallclock driver only
> once, and from then on should use the kernel's ticks to keep
> track of time.

I noticed that, and implemented wallclock driver in this way:

void Cyg_WallClock::init_hw_seconds(void)
{
        Cyg_Clock::cyg_resolution res =
Cyg_Clock::real_time_clock->get_resolution();
        cyg_tick_count_t current = get_scmxx_hwclock();
        current *= (( res.divisor * 1000000000LL ) / res.dividend);
        Cyg_Clock::real_time_clock->set_value(current);
}

cyg_uint32 Cyg_WallClock::get_hw_seconds(void)
{
    Cyg_Clock::cyg_resolution res =
Cyg_Clock::real_time_clock->get_resolution();
    cyg_tick_count_t secs = Cyg_Clock::real_time_clock->current_value();
    secs /= (( res.divisor * 1000000000LL ) / res.dividend) ;
    return secs;
}

So, kernel realtime clock is actually synchronized with wallclock in the
initialization and later when you want to read wallclock you actually read
kernel clock.
Maybe this is not most cleanest solution (I didn't want to change too much
of eCos code), but it works.
Hm, I thought that it should work. :-(
Problem occurs when you want to change wallclock time with
cyg_libc_time_settime().
I implemented it this way:

void Cyg_WallClock::set_hw_seconds( cyg_uint32 secs )
{
        set_scmxx_hwclock(secs);
        init_hw_seconds();
}

We set hardware clock and reinitialize kernel real time clock. But kernel
clock reinitialization can cause problems because all active threads and
alarms are linked with old value of kernel clock and changed value can cause
them to misbehave (never happen or happen too late).
So, I suppose that we shouldn't use real_time_clock->set_value() except in
initialization. But how to implement Cyg_WallClock::set_hw_seconds and keep
time() and cyg_current_time() to return same value ?

Thanks

Damir Salantic



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