[Rtai] Period measurement and odd behaviour

Paolo Mantegazza mantegazza at aero.polimi.it
Thu Sep 25 18:17:10 CEST 2008


A López wrote:
> start_rt_timer(period) is returning 0 all the time.
> 

OK, easy to check. I'll do ASAP, can you remind me of your system 
features, num cpus, frequency, APIC available if UP, and so on?

Paolo.

> Values (Period in ticks as returned by nano2count, used as argument in 
> start_rt_timer()):
> 
> Period(us)   Period(ticks)   Returned Period   Doubled
> 20                  125                   0                               no
> 21                  131                   0                               no
> 22                  137                   
> 0                               YES
> 23                  143                   
> 0                               YES
> 24                  150                   0                               no
> 25                  156                   0                               no
> 50                  311                   
> 0                               YES
> 51                  318                   0                               no
> 
> Antonio
> 
> On Thu, Sep 25, 2008 at 5:30 PM, Paolo Mantegazza 
> <mantegazza at aero.polimi.it <mailto:mantegazza at aero.polimi.it>> wrote:
> 
>     A López wrote:
>      > Just changing in my code "rt_set_periodic_mode()" by
>      > "rt_set_oneshot_mode" makes the "doubling" effect disappear, but
>      > produces less exact periods:
>      >
>      > Configured Period     Mean      Max         Min
>      > 20000                           20000    23093    16408
>      > 21000                           21000    24355    17770
>      > 22000                           22000    26205    17213
>      > 23000                           23000    26418    19190
>      > 24000                           24000    28049    21030
>      > 25000                           24999    28632    21419
>      > 50000                           50000    53122    45999
>      > 51000                           51000    54043    47912
>      >
>      > Should I use one shot mode?
> 
>     No, we must fix it.
> 
>      > Timing is good enough for my requirements
>      > but, why is this happening? And why does it work ok in the latency
>      > example with periodic mode?
>      >
> 
>     I think that your problem might be related to the way RTAI uses periodic
>     mode timing. In fact the scheduling resolution is just at the pace of
>     the period set by start_rt_timer(period). Nonetheless the internal
>     resolution of RTAI is always better so it tries to round intermediate
>     requests to stay in the closest period half. If you want to be sure to
>     be scheduled exactly you have to use the period, or multiple integer of
>     it, returned by start_rt_timer(period). Doing it differently there can
>     be jumps because you conversion is, even if slightly only, different
>     form that return by starting the timer. You should check if it is so now
>     printing both value, then use "period = start_rt_timer(WANTED_PERIOD)"
>     only and see if it is OK.
>     Let me know.
> 
>     Paolo.
> 
> 
>      > Regards
>      > Antonio
>      >
>      > On Thu, Sep 25, 2008 at 3:22 PM, Paolo Mantegazza
>      > <mantegazza at aero.polimi.it <mailto:mantegazza at aero.polimi.it>
>     <mailto:mantegazza at aero.polimi.it
>     <mailto:mantegazza at aero.polimi.it>>> wrote:
>      >
>      >     A López wrote:
>      >
>      >         Hi Paolo, changing the period in the latency test (user mode)
>      >         everything seems OK to me:
>      >
>      >         Period     Lat avg     ovl max     Ovr
>      >         20             64             3643           0
>      >         21             27             2962           0
>      >         22             -170         3981           0
>      >         23             -207         2753           0
>      >         25             39             2321           0
>      >         50             -241         3592           0
>      >         51             42             4362           0
>      >
>      >         I cannot find what I am doing wrong, probably something
>     related
>      >         to the calculations....but it gets me unsure about the
>      >         application (by the way, the code is part of the
>     application, I
>      >         removed all other stuff in the loop and the "doubling" is
>     still
>      >         happening).
>      >
>      >
>      >     OK then try using the oneshot mode for start_rt_timer and
>     report the
>      >     result. Notice that I'm aware that running with periods of
>     the order
>      >     of 20 us make it better to use the periodic mode for sure.I'm not
>      >     asking you to use it for production, even if in the case your
>      >     machine is relatively recent it will make just a small
>     differencem,
>      >     it is just to frame what is the problem.
>      >
>      >     Paolo.
>      >
>      >         Regards
>      >         Antonio
>      >
>      >
>      >         On Thu, Sep 25, 2008 at 1:22 PM, Paolo Mantegazza
>      >         <mantegazza at aero.polimi.it
>     <mailto:mantegazza at aero.polimi.it> <mailto:mantegazza at aero.polimi.it
>     <mailto:mantegazza at aero.polimi.it>>
>      >         <mailto:mantegazza at aero.polimi.it
>     <mailto:mantegazza at aero.polimi.it>
>      >         <mailto:mantegazza at aero.polimi.it
>     <mailto:mantegazza at aero.polimi.it>>>> wrote:
>      >
>      >            Your test is the nth rewrite of the latency check
>     available
>      >         in RTAI.
>      >            You have the code and can change the period as you
>     like. What
>      >            results does it give to you?
>      >
>      >            Paolo.
>      >
>      >            A López wrote:
>      >
>      >                Dear all,
>      >
>      >                I have a LXRT application with RTAI 3.6 and kernel
>      >         2.6.23.9 <http://2.6.23.9> <http://2.6.23.9>
>      >                <http://2.6.23.9> <http://2.6.23.9/> in a Pentium M
>      >         1600MHz PC
>      >
>      >                to control a laser process in real time.
>      >
>      >
>      >                When i measure the period I find that, depending
>     on the
>      >                configured period, I get almost exact results or
>     strange
>      >         ones.
>      >                Let me explain it with some example data:
>      >
>      >                Configured Period: 51 microsec
>      >                Measured Periods: Mean=51.044 usec Max=51.045
>     Min=51.044
>      >
>      >                Configured Period: 50 microsec
>      >                Measured Periods: Mean=49.921 usec *Max=99.522*
>     Min=49.760
>      >
>      >                What I get is a maximum measured period that is around
>      >         two times
>      >                the configured period for around 0.01% of the
>     periods. This
>      >                happens depending on the configured period with a
>     pattern
>      >         that I
>      >                cannot figure out. For example, configured periods
>     of 20,
>      >         21, 24
>      >                and 25 microsecs work ok, but 22 and 23 microsecs
>     get doubled
>      >                periods. In all the cases when I get wrong
>     measurements the
>      >                result is the same: the measured maximum period is
>     around
>      >         twice
>      >                the configured period.
>      >
>      >                Why? How can I fix it?
>      >
>      >                Here is the code:
>      >
>      >                I create the task here:
>      >
>      >                // Crea la tarea "buddy" en el espacio del kernel
>      >                if (!(maint = rt_task_init(nam2num("MAIN"), 1, 0,
>     0))) {
>      >                   printf("CANNOT INIT TASK > MAIN <\n");
>      >                   ErrorRTAI = ON;
>      >                   ProcesarError();
>      >                   return -1;
>      >                }
>      >
>      >                // se pone a OFF tras entrar en RT (ejecutar
>      >                rt_make_hard_real_time en timer_handler)
>      >                endthread = ON;
>      >                endhandler = ON;
>      >
>      >                // Crea el thread del timer
>      >                if (!(timerthread = rt_thread_create((void
>     *)timer_handler,
>      >                NULL, 10000))) {  // create thread
>      >                   printf("CANNOT INIT TIMERTHREAD\n");
>      >                   ErrorRTAI = ON;
>      >                   ProcesarError();
>      >                   return -1;
>      >                }
>      >                  // espera hasta que se haya destruido el handler
>     para
>      >         proseguir
>      >                while (!endhandler) {          usleep(10000);
>      >                }          return 0;
>      >
>      >                The timer handler code:
>      >
>      >                int error = false;
>      >
>      >                // contador de iteraciones
>      >                static long long ContadorCiclos = 0;
>      >
>      >                // Contador de ciclos anormalmente largos
>      >                static long long ContadorCiclosLargos = 0;
>      >
>      >                // Guarda el tiempo en el que terminó el ciclo
>     anterior
>      >                static RTIME tAnterior = 0;
>      >
>      >                // Para obtener el tiempo y poder calcular la
>     duración de
>      >         los bucles
>      >                static RTIME tActual = 0;
>      >
>      >                // Variables para almacenar los valores de
>     duración de ciclos
>      >                static double duracionCiclo = 0;
>      >                static double duracionCicloMax = 0;
>      >                static double duracionCicloMin = 1000000000;
>      >                static double duracionCicloPromedio = 0;
>      >                static double duracionCicloLargoPromedio = 0;
>      >
>      >                if (!(timer_task_handler =
>     rt_task_init(nam2num("TIMER"),
>      >         1, 0,
>      >                0))) {
>      >                   printf("CANNOT INIT TASK > TIMER <\n");
>      >                   ErrorRTAI = ON;
>      >                   ProcesarError();
>      >                }
>      >                  // permite acceso a los recursos io
>      >                rt_allow_nonroot_hrt();
>      >                  // se fija en memoria para evitar swap
>      >                mlockall(MCL_CURRENT | MCL_FUTURE);
>      >
>      >                // Modo periodico:
>      >                rt_set_periodic_mode();
>      >
>      >                // Inicia el timer
>      >                Periodo = nano2count(PERIODO_MICROSEGUNDOS*1000);
>      >                start_rt_timer(Periodo);
>      >
>      >                // HARD RT
>      >              
>      /////////////////////////////////////////////////////////////
>      >                rt_make_hard_real_time();
>      >
>      >                // Control del bucle while y sincronismo
>      >                endthread = OFF;
>      >                endhandler = OFF;
>      >                      // Fija el inicio y el periodo de la tarea
>      >                rt_task_make_periodic(timer_task_handler,
>     rt_get_time() +
>      >                Periodo, Periodo);
>      >
>      >
>      >        
>      //////////////////////////////////////////////////////////////////////////////////////////////////
>      >                // BUCLE DE CONTROL DEL PROGRAMA: ESTA ACTIVO
>     DURANTE TODA LA
>      >                VIDA DEL MISMO, MANTENIENDO EL TIMER
>      >
>      >        
>      //////////////////////////////////////////////////////////////////////////////////////////////////
>      >
>      >                tAnterior = rt_get_time_ns();
>      >
>      >                while ( !endthread ) {
>      >
>      >        
>     //////////////////////////////////////////////////////////////////
>      >                   //ESPERA EL TIEMPO CORRESPONDIENTE A UN PERIODO
>      >                   rt_task_wait_period();
>      >
>      >        
>     //////////////////////////////////////////////////////////////////
>      >                             //ESTADISTICAS del tiempo de los ciclos
>      >                   if (debug_ciclos) {
>      >                             ContadorCiclos++;
>      >                             // Calcula la duración del ciclo
>      >                       tActual = rt_get_time_ns();
>      >                       duracionCiclo = (double)(tActual - tAnterior);
>      >                                                 // Suma en el
>     acumulado para
>      >                calcular la media
>      >                       duracionCicloPromedio += duracionCiclo;
>      >                                 // detecta máximo y mínimo
>      >                       if (duracionCiclo > duracionCicloMax)
>      >         duracionCicloMax =
>      >                duracionCiclo;
>      >                       if (duracionCiclo < duracionCicloMin)
>      >         duracionCicloMin =
>      >                duracionCiclo;
>      >                                         // cuentas de ciclos
>     largos (más
>      >         del 5%
>      >                del periodo actual)
>      >                       if (duracionCiclo >=
>      >         (double)(PERIODO_MICROSEGUNDOS*1000
>      >                * 1.05) ) {
>      >                                     ContadorCiclosLargos++;
>      >                           duracionCicloLargoPromedio +=
>     duracionCiclo;
>      >                                 }
>      >                                 tAnterior = tActual;
>      >                         }
>      >                  }
>      >
>      >                // Detiene el timer
>      >                stop_rt_timer();
>      >                  // SOFT RT
>      >              
>      /////////////////////////////////////////////////////////////
>      >                rt_make_soft_real_time();
>      >                rt_task_delete(timer_task_handler);
>      >                endhandler = ON;
>      >                  //ESTADISTICAS del tiempo de los ciclos
>      >                if (debug_ciclos) {
>      >
>      >        
>     printf("##############################################################################################\n");
>      >                   printf("Bucles: %lld \nPromedio Ciclo(ns): %f
>     Max(ns): %f
>      >                Min(ns): %f\nLargos: %lld Promedio Largos(ns): %f\n",
>      >                ContadorCiclos, duracionCicloPromedio/ContadorCiclos,
>      >                duracionCicloMax, duracionCicloMin,
>     ContadorCiclosLargos,
>      >              
>      float(duracionCicloLargoPromedio/ContadorCiclosLargos));
>      >
>      >        
>     printf("##############################################################################################\n");
>      >                  }          return 0;
>      >
>      >
>      >                Thanks in advance
>      >                Antonio López
>      >
>      >
>      >
>      >        
>      ------------------------------------------------------------------------
>      >
>      >                _______________________________________________
>      >                Rtai mailing list
>      >                Rtai at rtai.org <mailto:Rtai at rtai.org>
>     <mailto:Rtai at rtai.org <mailto:Rtai at rtai.org>>
>      >         <mailto:Rtai at rtai.org <mailto:Rtai at rtai.org>
>     <mailto:Rtai at rtai.org <mailto:Rtai at rtai.org>>>
>      >
>      >                https://mail.rtai.org/cgi-bin/mailman/listinfo/rtai
>      >
>      >
>      >
>      >
>      >
>      >
>      >
> 
> 
>     _______________________________________________
>     Rtai mailing list
>     Rtai at rtai.org <mailto:Rtai at rtai.org>
>     https://mail.rtai.org/cgi-bin/mailman/listinfo/rtai
> 
> 




More information about the Rtai mailing list