You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nuttx.apache.org by Roberto Bucher <ro...@supsi.ch> on 2022/03/09 17:57:01 UTC

NuttX timers

Hi

I've tried to modify the base timer from 10ms to 1ms, but in the 
execution of the generated RT Thread i get a overrun (of about 5ms...).

I modified for this the "CONFIG_SCHED_TICKLESS" from 10000 to 1000.

My board is a the STM32F746:nucleo-144 board. Are there other 
possibilities to get a shorter sampling time in my RT thread?

The code for the sampling time is programmed as:

-------------------------------------------------------------------------
   while(!end){

     /* periodic task */
     T = calcdiff(t_current,T0);
     NAME(MODEL,_isr)(T);

     t_next.tv_sec = t_current.tv_sec + t_isr.tv_sec;
     t_next.tv_nsec = t_current.tv_nsec + t_isr.tv_nsec;
     tsnorm(&t_next);

     /* Check if Overrun */
     clock_gettime(CLOCK_MONOTONIC,&t_current);
     if (t_current.tv_sec > t_next.tv_sec ||
     (t_current.tv_sec == t_next.tv_sec && t_current.tv_nsec > 
t_next.tv_nsec)) {
       int usec = (t_current.tv_sec - t_next.tv_sec) * 1000000 + 
(t_current.tv_nsec -
                                  t_next.tv_nsec)/1000;
       fprintf(stderr, "Base rate overrun by %d us\n", usec);
       t_next= t_current;
     }
     clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
     t_current = t_next;
   }

---------------------------------------------------------------------

Thanks in advance

Roberto


Re: NuttX timers

Posted by Gregory Nutt <sp...@gmail.com>.
> Try to sleep less than 1000us, because the sleep(X) means it will
> sleep at least X us, not less, not equal.

More info here: 
https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays

Many timers are based on on one-shot watchdog timers.  Basing any 
periodic timer on a one-shot timers is an inherently bad design. Both 
because of (1) inaccuracies introduced waiting for execution priority 
and restarting the one shot, and (2) because of the different 
requirements of one shot timers and periodic timers: One shot timers 
need to wait at least as long as requested as Alan mentioned.  Periodic 
timers need to be as close to the frequency of the requested timer.  You 
really can't do both with the same time.

This problems basically do go away if you can increase the resolution of 
the timer as you have done.  But if the accuracy that you want is close 
to the quantization error due to the timer resolution, then it is tricky 
to get the timers to behave in a satisfactory way.

Most people I have talked to in the past to who needed high resolution 
sampling frequencies ended up using a peripheral timer running at a 
relatively high frequency and automatically restarting to provide 
periodicity




Re: NuttX timers

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
Hi Roberto,

Try to sleep less than 1000us, because the sleep(X) means it will
sleep at least X us, not less, not equal.

BR,

Alan

On 3/9/22, Roberto Bucher <ro...@supsi.ch> wrote:
> Hi
>
> I've tried to modify the base timer from 10ms to 1ms, but in the
> execution of the generated RT Thread i get a overrun (of about 5ms...).
>
> I modified for this the "CONFIG_SCHED_TICKLESS" from 10000 to 1000.
>
> My board is a the STM32F746:nucleo-144 board. Are there other
> possibilities to get a shorter sampling time in my RT thread?
>
> The code for the sampling time is programmed as:
>
> -------------------------------------------------------------------------
>    while(!end){
>
>      /* periodic task */
>      T = calcdiff(t_current,T0);
>      NAME(MODEL,_isr)(T);
>
>      t_next.tv_sec = t_current.tv_sec + t_isr.tv_sec;
>      t_next.tv_nsec = t_current.tv_nsec + t_isr.tv_nsec;
>      tsnorm(&t_next);
>
>      /* Check if Overrun */
>      clock_gettime(CLOCK_MONOTONIC,&t_current);
>      if (t_current.tv_sec > t_next.tv_sec ||
>      (t_current.tv_sec == t_next.tv_sec && t_current.tv_nsec >
> t_next.tv_nsec)) {
>        int usec = (t_current.tv_sec - t_next.tv_sec) * 1000000 +
> (t_current.tv_nsec -
>                                   t_next.tv_nsec)/1000;
>        fprintf(stderr, "Base rate overrun by %d us\n", usec);
>        t_next= t_current;
>      }
>      clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
>      t_current = t_next;
>    }
>
> ---------------------------------------------------------------------
>
> Thanks in advance
>
> Roberto
>
>