[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