Timer unter RTai - rt_set_periodic_mode ist nicht periodisch.

26/02/2009 - 22:03 von Martin Freiberg | Report spam
Hallo,

Bei meinen Basteleien möchte ich unter Linux mit RTai einen
zyklischen Timer laufen lassen.

Linux Vanilla Kernel 2.6.23
RTai 3.6.1

Stark gekürzt:

include tralala...

RT_TASK my_Timer; // Zeiger auf Timer-Function
RTIME expected;
RTIME period_counts;
int period = 50000;
int intrcount = 0; // Zaehlschleife

// hier sonstiges .

void my_Timertask(long my_Timer) {

++intrcount;

// hier noch anderes Zeug ...
}

int init_module (void) { // Modul initialisierung

printk (KERN_INFO ": Modul Initialisierung gestartet");
// hier noch diverse andere Codezeilen...

rt_task_init( /* create our measuring task */
&my_Timer, /* poiter to our RT_TASK */
my_Timertask, /* implementation of the task */
0, /* we could transfer data -> task */
5000, /* stack size */
0, /* priority */
0, /* do we use the FPU? 0 = No */
0 /* signal? XXX */
);
rt_set_periodic_mode ();
period_counts = start_rt_timer (nano2count(period));
expected = rt_get_time();
rt_task_make_periodic (&my_Timer,expected,period_counts);

printk (KERN_INFO "Modul erfolgreich installiert");
return (0);
}

void cleanup_module (void) { // Modul sauber deaktivieren

stop_rt_timer();
rt_task_delete(&my_Timer);

// hier noch div. anderes Zeug
printk (KERN_INFO "Modul Resourcen wieder freigegeben");
}


:# modprobe mytreiber

:# cat /proc/myTreiber
1

:#


Die Variable intrcount lasse ich über das /proc Dateisystem
anzeigen. Sie wird bei diesem Beispiel nur einmal inkrementiert
was bedeutet, das die Funktion definitiv nur einmal aufgerufen
wird und nicht periodisch. Initialisiere ich intrcount mit 3
wird 4 ausgegeben.

Für einen einmaligen Durchlauf würde normalerweise ein
rt_set_oneshot_mode ();
verwendet.


Sàmtliche Beispiele die ich gefunden habe verwenden in der
Timerroutine als Hack eine Endlosschleife mit while (1),

void my_Timertask(long my_Timer) {
while (1) {
++intrcount;
rt_sleep (period);
}
}

und für die Verzögerung ein rt_sleep Kommando. :(


Aber das kann es ja auch nicht sein. Die Lösung ist sehr
unsauber. Denn der Aufruf erfolgt so definitiv nicht exakt,
sondern schwankt mit der Dauer die diese Funktion selber
benötigt. Wenn ich hier eine Schwankung von +- 1 ms habe,
dann erfolgt der Aufruf ebenfalls mit +- 1 ms (50 ms +
Durchlaufzeit) anstatt wie eigendlich gewünscht exakt alle
50 ms ( 0 mal in der Sekunde).

Dieses fehlerhafte Beispiel für die Timerschleife entstammt
übrigend aus einem Demo-Beispiel von rtai
rtai/testsuite/kern/latency/latency-module.c

(Siehe Zeile 150)
Und hier hàtte ich ein korrektes Beispiel erwartet. :(

Wo ich auch noch einen Fehler in dem Beispiel sehe ist,
das ein zweifaches einstellen für periodic verwendet wird,
und im Singledurchlauf einmal oneshot und dann wieder ein
periodic. Der Fehler wird zugleich durch eine geànderte
Berechnung in der Funktion kaschiert (Zeile 162).

Meiner Ansicht nach müsste entweder hier Rtai selber die
Funktion regelmàssig aufrufen (wegen dem periodic-Befehl)
oder zumindest in der Funktion durch einen Befehl dies
veranlassen (so wie mit einem normalen Kerneltimer).

Kennt jemand ein korrektes funktionierendes Beispiel
ohne die while(1) Hilfskrücke oder Abhilfe?


Gruß
Martin
 

Lesen sie die antworten

#1 Martin Freiberg
02/03/2009 - 18:34 | Warnen spam
Martin Freiberg schrieb:

Wo bin ich mit Fragen zu RTAI richtig?

Gibt es da ein deutschsprachiges Forum, oder nur
englischsprachige?

Gruß
Martin

Ähnliche fragen