Harte Echtzeit mit Windows

#815292
Lesenswert?

Hallo will mit Delphi 6 unter Windows XP aller 10 ms ein Signal an einen 
Mikrocontroller senden und wieder empfangen.

Dann zähle ich die gesendeten und die empfangenen Bytes.
Sobald ich unter 400 ms komme gibt es eine Differenz.

Das liegt wohl am Multitasking vom Windows.
Gibt es möglichkeiten dieses zu umgehen?
Oder andere Möglichkeiten?

Danke
Gast #815303
Lesenswert?

Hi

Ich nehmen an du benutzt die delphieigene Timerkomponente. Also unter 
W98SE ging es >100ms halbwegs genau. Unter XP habe ich es noch nicht 
ausprobiert. Aber besser wird es bestimmt nicht. Evtl. solltest du mal 
verschiedene Timerkomponenten testen.

MfG Spess
#815330
Lesenswert?

benutze die dx timer komponente die soll von der Zeit her kein Problem 
machen   kann auch alle 10 ms mit ihr senden aber mit dem empfangen 
kommt er nicht hinterher.
empfange mit dem RX ereignis.
man kann leider nur einen dx timer verwenden.

würde es sinn machen das empfangen mit in die sendeprozedur mit 
reinzuhauen?

Ist das in den Timerkomponenten eventuell schon eingebaut das das 
Multitasking von Windows umgangen wird?
Gast #815336
Lesenswert?

hast du denn auch die Priorität der Anwendung hoch gesetzt? Nicht auf 
Realtime, das gibt schnell Totalblockaden, in RT darf man nicht alles 
machen.
Delphi kenne ich nicht so, gucke mal nach einer Timerkomponente die den 
Multimedia Timer nutzt. Ein einfacher Timer setzt nur eine Windows 
Message ab die in einer Queue landet wie Mausbewegungen und Tastendrücke 
usw. In dem Eventhandler sollten dann keinesfalls grafische Ausgaben 
oder aufwändige Sachen gemacht werden, nur die Daten speichern und in 
einem anderen Thread mit niedrigerer Prio die Daten dann verarbeiten.
Gast #815339
Lesenswert?

PS: und wenn die Probleme hauptsächlich beim Empfangen sind: da gibt es 
noch ein Hardwarefifo das erst einen Interrupt auslöst wenn eine 
einstellbare Anzahl Zeichen eingetroffen ist (1..16 üblicherweise). Wenn 
hier also >1 eingestellt ist dann wird dein Empfangsbuffer evtl. zu spät 
voll. Wenn man den Fifo Receive Level nicht in der seriellen Komponente 
einstellen kann dann gucke im Hardwaremanger in den erweiterten 
Eigenschaften der verwendeten COM Schnittstelle.
Gast #815397
Lesenswert?

SetTimer kann nur auf ca. 18ms auflösen.
QueryPerformanceCounter (in Verbindung mit QueryPerformanceFrequency) 
kann es wesentlich genauer. Den Timer dazu muß man sich selber 
schreiben, aber bitte nicht in die Windows Callback-Funktion 
einsortieren.
Eine eigener Thread, welcher die seriellen Daten per Eventhandler 
empfängt, mit HIGH-PRIORITY arbeitet und die Events mit einem 
Zeitstempel von oben genannter Funktion versieht und (mit 
PostThreadMessege) zu einem anderen Thread weiterleitet, der letzten 
Endes die Verarbeitung macht.

"Dauerblockaden", z.B. vom Netzwerk, können aber auch damit nicht 
umgangen werden.
Ein exaktes Zeitsignal durch Dauersenden von Daten zum seriellen Port 
kann man per Windows trotzdem erzeugen, nur muß man dann etwas Hardware 
an den seriellen Port bauen, um es wieder "filtern" zu können (z.B. 
immer nur Bit 0  lesen).
Nur beim Empfang gibt es nix genaues.
Das Einzige was mit ca. 1ms Zeitstempel IMMER gehen könnte, wäre eine 
Verarbeitung der (über den LINE-IN-Eingang o.ä.) eingehenden Daten mit 
den Waveform Funktionen. Also einen Wave-Buffer nach dem anderen abholen 
und verarbeiten. Dabei gibt es aber eine (konstante) Grundverzögerung, 
die vom verwendeten Soundchip abhängig ist.
Den MultiMediaTimer gibt es übrigens auch noch, der ist auf 1ms genau.

Blackbird
Persönliche Seite #815408
Lesenswert?

Die Granularität des Windows-Schedulers liegt bei den nicht 
DOS-basierten Windows-Versionen bei 15msec (alte NT-Versionen) oder bei 
10msec (2000, XP etc.). Der vorstehend genannte Wert von 18msec trifft 
für ernstgemeinte Windows-Versionen also definitiv nicht zu.

Die Granularität des Schedulers kann auf 1msec reduziert werden, das 
geschieht mit der Multimedia-API-Funktion timeBeginPeriod (definiert 
in mmsystem.h, implementiert in winmm.lib).
Als Argument ist der Funktion die gewünschte Timerauflösung in msec zu 
übergeben; mit

  timeBeginPeriod(1);

ist die Sache also erledigt.

Wirklich harte Echtzeit ist damit natürlich auch nicht zu erreichen, 
aber bessere Werte als die vom Threadstarter genannte, sofern die 
Auslastung des Systemes sich in Grenzen hält.

Eine interessante Alternative könnte folgendes kommerzielle Produkt 
sein: "RealTime Suite 2008" http://kithara.de/ge/prod.php

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren