The current solucion also gets a problem because really depends on the CONFIGURE_MICROSECONDS_PER_TICK parameter. If this value is small enough it is possible to get another overrun of tv_nsec while executing<div><br></div>
<div><span class="Apple-style-span" style="border-collapse: collapse; "><p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; "> /* code added */</span></font></p><p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">    /* if an interrupt occurred while interrupts were disabled and the nanoseconds is too little */</span></font></p>
<p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">    /* means that a clock interrupt occurred BEFORE the nanoseconds were read */</span></font></p><p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">    if (pending && offset.tv_nsec < rtems_configuration_get_microseconds_per_tick() / 2) {</span></font></p>
<p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">        struct timespec clockTick = {0, rtems_configuration_get_microseconds_per_tick()*1000};</span></font></p><p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">        _Timespec_Add_to(&offset, &clockTick); /* so add one clock tick to the offset */</span></font></p>
<p><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial; ">    }</span></font></p><p><br></p><p>I see that _TOD_Uptime is updated every clock tick in cpukit/score/src/coretodtickle.c (see bellow) with microseconds precision. It is not enough with the next patch?</p>
<p><br></p><p></p><p>=== modified file 'cpukit/score/src/coretodgetuptime.c'</p><p>--- cpukit/score/src/coretodgetuptime.c 2009-03-31 07:56:38 +0000</p><p>+++ cpukit/score/src/coretodgetuptime.c 2009-03-31 09:49:25 +0000</p>
<p>@@ -20,6 +20,7 @@</p><p> #include <rtems/score/isr.h></p><p> #include <rtems/score/timespec.h></p><p> #include <rtems/score/tod.h></p><p>+#include <rtems/config.h></p><p><br></p><p> /*</p><p>  *  _TOD_Get_uptime</p>
<p>@@ -46,8 +47,8 @@</p><p><br></p><p>   _ISR_Disable( level );</p><p>     *uptime = _TOD_Uptime;</p><p>-    if ( _Watchdog_Nanoseconds_since_tick_handler )</p><p>-      offset.tv_nsec = (*_Watchdog_Nanoseconds_since_tick_handler)();</p>
<p>+//    if ( _Watchdog_Nanoseconds_since_tick_handler )</p><p>+//      offset.tv_nsec = (*_Watchdog_Nanoseconds_since_tick_handler)();</p><p><br></p><p>   _ISR_Enable( level );</p><p></p><p><br></p></span><div><br></div>
<div><br><br><div class="gmail_quote">On Tue, Mar 31, 2009 at 11:22 AM, Manuel Coutinho <span dir="ltr"><<a href="mailto:manuel.coutinho@edisoft.pt">manuel.coutinho@edisoft.pt</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">










<div lang="EN-US" link="blue" vlink="blue">

<div>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">I’m not sure that the
isClockInterruptPending() is a function that can be available to all BSPs. Some
CPU might not support this. I don’t know :(. </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">In either case, here’s the function for
the ERC32 board (I know, the names can be improved):</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">#define INTERRUPT_PENDING_ADDRESS
0x01F80048</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">/**</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> * RTC interrupt level</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> **/</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">#define RTC_ISR_INTERRUPT_LEVEL 13</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">#define RTC_INTERRUPT_PENDING_MASK (1
<< RTC_ISR_INTERRUPT_LEVEL)</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">uint32_t isClockInterruptPending() {</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">    uint32_t *pointer_pending = (uint32_t
*) INTERRUPT_PENDING_ADDRESS;</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">    return pending (*pointer_pending ) &
RTC_INTERRUPT_PENDING_MASK;</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">}</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">

<div>

<div align="center" style="text-align:center"><font size="3" face="Times New Roman"><span style="font-size:12.0pt">

<hr size="2" width="100%" align="center">

</span></font></div>

<p><b><font size="2" face="Tahoma"><span style="font-size:10.0pt;font-family:Tahoma;font-weight:bold">From:</span></font></b><font size="2" face="Tahoma"><span style="font-size:10.0pt;font-family:Tahoma">
<a href="mailto:aitorvs@googlemail.com" target="_blank">aitorvs@googlemail.com</a> [mailto:<a href="mailto:aitorvs@googlemail.com" target="_blank">aitorvs@googlemail.com</a>] <b><span style="font-weight:bold">On Behalf Of </span></b>Aitor Viana<br>

<b><span style="font-weight:bold">Sent:</span></b> Tuesday, March 31, 2009 10:09
AM<br>
<b><span style="font-weight:bold">To:</span></b> Manuel Coutinho<br>
<b><span style="font-weight:bold">Cc:</span></b> Joel Sherrill;
<a href="mailto:rtems-users@rtems.com" target="_blank">rtems-users@rtems.com</a><div><div></div><div class="h5"><br>
<b><span style="font-weight:bold">Subject:</span></b> Re: Bug with clock
nanoseconds</div></div></span></font></p>

</div><div><div></div><div class="h5">

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Yep,</span></font></p>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">crystal clear. BTW, isClockInterruptPending() is not present in the
RTEMS distribution, it should be implemented for all BSPs I guess.</span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Best regards,</span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Aitor</span></font></p>

</div>

<div>

<p style="margin-bottom:12.0pt"><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">On Tue, Mar 31, 2009 at 10:30 AM, Manuel Coutinho <<a href="mailto:manuel.coutinho@edisoft.pt" target="_blank">manuel.coutinho@edisoft.pt</a>>
wrote:</span></font></p>

<div link="blue" vlink="blue">

<div>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">Hi. Thanks for testing in leon2…was just about to do that :)!</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">Basically, the test aims to see that the clock is always
increasing. But the result is that, sometimes, it decreases.</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">This happens when a clock tick occurs.</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">The RTEMS algorithm to read the time consists of:</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">1. Disabling interrupts</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">2. Read how many clock interrupts occurred</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">3. Read nanoseconds elapsed</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">4. Enable interrupts</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">The problem occurs if an interrupt occurs between the 1 and 3
steps: -> the number of clock ticks is NOT updated (because interrupts are
disabled) and the nanoseconds field (which is read directly from the CPU
registers) is restarted.</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">For example, the clock is 2 clock ticks and 99999 us (a clock
tick is just about to occur). Suppose you disable interrupts, read 2 clock
ticks, then the CPU clock counter overflows and the nanoseconds is reset to 0
and you read 0 nanoseconds. </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">You end up reading 2 clock ticks and 0 nanoseconds when in
fact you should read 3 clock ticks and 0 nanoseconds - you cannot stop the
clock counter (nor do you wish to!).</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">Hope this explains the problem a little bit better :)</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">By the way, by glancing at the code of the remaining BSPs,
specifically at the Clock_driver_nanoseconds_since_last_tick macro, I don’t
believe this is a problem just with SPARC. I don’t see this problem address in
any board. But, of course, I might be wrong since it was just a very brief
look.</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">Kind regards</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy">Manuel Coutinho</span></font></p>

<p><font size="2" color="navy" face="Arial"><span style="font-size:10.0pt;font-family:Arial;color:navy"> </span></font></p>

<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">

<div>

<div align="center" style="text-align:center"><font size="3" face="Times New Roman"><span style="font-size:12.0pt">

<hr size="2" width="100%" align="center">

</span></font></div>

<p><b><font size="2" face="Tahoma"><span style="font-size:10.0pt;font-family:Tahoma;font-weight:bold">From:</span></font></b><font size="2" face="Tahoma"><span style="font-size:10.0pt;font-family:Tahoma"> <a href="mailto:aitorvs@googlemail.com" target="_blank">aitorvs@googlemail.com</a>
[mailto:<a href="mailto:aitorvs@googlemail.com" target="_blank">aitorvs@googlemail.com</a>]
<b><span style="font-weight:bold">On Behalf Of </span></b>Aitor Viana<br>
<b><span style="font-weight:bold">Sent:</span></b> Tuesday, March 31, 2009 8:31
AM<br>
<b><span style="font-weight:bold">To:</span></b> Joel Sherrill<br>
<b><span style="font-weight:bold">Cc:</span></b> Manuel Coutinho; <a href="mailto:rtems-users@rtems.com" target="_blank">rtems-users@rtems.com</a><br>
<b><span style="font-weight:bold">Subject:</span></b> Re: Bug with clock
nanoseconds</span></font></p>

</div>

<div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Just
tried in tsim-leon and happens the same.</span></font></p>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">I didn't
completely understand what's the problem Manuel could you explain to me again?
is early in the morning :D</span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Best
regards,</span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Aitor</span></font></p>

</div>

<div>

<p style="margin-bottom:12.0pt"><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">On Mon,
Mar 30, 2009 at 6:49 PM, Joel Sherrill <<a href="mailto:joel.sherrill@oarcorp.com" target="_blank">joel.sherrill@oarcorp.com</a>>
wrote:</span></font></p>

<div>

<p style="margin-bottom:12.0pt"><font size="3" face="Times New Roman"><span style="font-size:12.0pt">Manuel Coutinho wrote:<br>
><br>
> Hi<br>
><br>
><br>
><br>
> We have discovered a bug of RTEMS relating to the clock. Even though<br>
> we only tested it for the ERC32 board (for now), we believe it is<br>
> common throughout all the targets.<br>
></span></font></p>

</div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">No you
have discovered a bug in the ERC32's get nanoseconds since last<br>
tick handler.<br>
Apparently it doesn't recognize that is has been longer than a tick<br>
since the last clock<br>
tick.  It should determine that is has overflowed and return 1 clock<br>
tick + partial clock<br>
tick.<br>
<br>
It is returning the wrong answer.</span></font></p>

<div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"><br>
><br>
><br>
> The test consists in checking if the time given by rtems_clock_get is<br>
> always increasing. The code is as follows:<br>
><br>
><br>
></span></font></p>

</div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">>
.....<br>
<br>
<br>
....</span></font></p>

<div>

<div>

<p style="margin-bottom:12.0pt"><font size="3" face="Times New Roman"><span style="font-size:12.0pt">><br>
> As you can see, the problem is raised when a clock tick occurs: the<br>
> time read in “new” is older than “old”. This cannot happen since “new”<br>
> is updated AFTER “old”! This problem occurs if a clock interrupt is<br>
> triggered after the number of clock ticks have been read but BEFORE<br>
> the nanosecond field has been read. The resulting number of clock<br>
> ticks is “small” (should be plus one).<br>
><br>
><br>
><br>
> We can use the interrupt pending CPU registers info to determine if,<br>
> while we are reading the number of clock ticks that occurred and the<br>
> nanoseconds, a clock interrupt could be pending.<br>
><br>
><br>
><br>
> We do not have enough knowledge to say that this solution can be used<br>
> for all boards (determining if an interrupt is pending). In the SPARC<br>
> architecture, at least, it is possible. If it is possible in all<br>
> architectures, then a solution to RTEMS would be to change the code of<br>
> the _TOD_Get_uptime function to:<br>
><br>
><br>
><br>
><br>
><br>
> void _TOD_Get_uptime(struct timespec *uptime) {<br>
><br>
>     ISR_Level level;<br>
><br>
>     struct timespec offset;<br>
><br>
>     volatile uint32_t pending;<br>
><br>
><br>
><br>
>     /* assume uptime checked by caller */<br>
><br>
><br>
><br>
>     offset.tv_sec = 0;<br>
><br>
>     offset.tv_nsec = 0;<br>
><br>
><br>
><br>
>     _ISR_Disable(level);<br>
><br>
>     *uptime = _TOD_Uptime;<br>
><br>
>     if (_Watchdog_Nanoseconds_since_tick_handler)<br>
><br>
>         offset.tv_nsec =
(*_Watchdog_Nanoseconds_since_tick_handler)();<br>
><br>
><br>
><br>
>     /* code added: */<br>
><br>
>     pending = isClockInterruptPending();<br>
><br>
><br>
><br>
>     _ISR_Enable(level);<br>
><br>
><br>
><br>
>     /* code added */<br>
><br>
>     /* if an interrupt occurred while interrupts were disabled
and the<br>
> nanoseconds is too little */<br>
><br>
>     /* means that a clock interrupt occurred BEFORE the
nanoseconds<br>
> were read */<br>
><br>
>     if (pending && offset.tv_nsec <<br>
> rtems_configuration_get_microseconds_per_tick() / 2) {<br>
><br>
>         struct timespec clockTick = {0,<br>
> rtems_configuration_get_microseconds_per_tick()*1000};<br>
><br>
>         _Timespec_Add_to(&offset, &clockTick);
/* so add one clock<br>
> tick to the offset */<br>
><br>
>     }<br>
><br>
><br>
><br>
>     /* else, the clock tick occurred AFTER the nanoseconds were
read,<br>
> so no problem */<br>
><br>
><br>
><br>
>     _Timespec_Add_to(uptime, &offset);<br>
><br>
> }<br>
><br>
><br>
><br>
><br>
><br>
> At least, with these modifications, the test passes :)!<br>
><br>
><br>
><br>
> Kind regards<br>
><br>
> Manuel Coutinho<br>
></span></font></p>

</div>

</div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt">--<br>
Joel Sherrill, Ph.D.             Director of
Research & Development<br>
joel.sherrill@OARcorp.com        On-Line Applications Research<br>
Ask me about RTEMS: a free RTOS  Huntsville AL 35805<br>
  Support Available             (256)
722-9985<br>
<br>
<br>
_______________________________________________<br>
rtems-users mailing list<br>
<a href="mailto:rtems-users@rtems.com" target="_blank">rtems-users@rtems.com</a><br>
<a href="http://rtems.rtems.org/mailman/listinfo/rtems-users" target="_blank">http://rtems.rtems.org/mailman/listinfo/rtems-users</a></span></font></p>

</div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

</div>

</div>

</div>

</div>

</div>

</div>

<p><font size="3" face="Times New Roman"><span style="font-size:12.0pt"> </span></font></p>

</div>

</div></div></div>

</div>

</div>


</blockquote></div><br></div></div>