Niedrige Latenz für die serielle Kommunikation unter Linux
Ich bin die Implementierung eines Protokolls über serielle ports unter Linux. Das Protokoll basiert auf einem Anfrage-Antwort-Schema, so dass der Durchsatz ist begrenzt durch die Zeit, die es dauert, ein Paket zu senden, an ein Gerät und eine Antwort bekommen. Die Geräte sind meist arm-basierte und Linux ausführen >= 3.0. Ich bin die Probleme der Verringerung der Umlaufzeit unter 10ms (115200 baud, 8 Daten-bit, keine Parität, 7 byte pro Nachricht).
Was IO-Schnittstellen geben mir die niedrigste Latenz: select, poll, epoll oder polling von hand mit ioctl? Tut blocking oder non-blocking IO Auswirkungen der Latenz?
Ich habe versucht, die low_latency Flagge mit setserial. Aber es schien, hatte es keinen Effekt.
Gibt es irgendwelche anderen Dinge kann ich versuchen zu reduzieren die Latenz? Da ich die Steuerung aller Geräte, es wäre sogar möglich, um den kernel zu patchen, aber seine lieber nicht.
- - - - - Edit - - - - -
Den serial controller verwendet wird, ist ein 16550A.
Sie müssen prüfen, wo die 10 ms ausgegeben werden, denn wenn Sie verloren sind, von dem anderen Gerät, das Sie nicht optimieren können mehr als das.
Was sind die Größen von Anfrage-und Antwort-Nachrichten? Wenn beide mehr als 100 bytes ist, können Sie nicht bekommen, round-trip-Zeit <10ms (mit 115200).
115200 ist extrem langsam, so dass Sie garantiert große Latenz einfach verschieben die bytes über. Ihre beste Wette wird die Zahl der baud-zu so etwas wie 921600. Oder besser noch, wechseln Sie zu gigabit-ethernet.
beide 7 byte.
InformationsquelleAutor JustMaximumPower | 2012-10-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Anfrage /Antwort-Schemas neigt dazu, ineffizient zu sein, und es zeigt sich schnell auf dem seriellen port. Wenn Sie daran interessiert sind, throughtput, Blick auf Fenster-Protokoll, wie kermit Datei-senden-Protokoll.
Nun, wenn Sie wollen stick mit Ihrem Protokoll und reduzieren die Latenz, select, poll, Lesen Sie alle geben Sie etwa die gleiche Latenz, denn wie Andy Ross angegeben, die Reale Latenz ist in der hardware-fifo handling.
Wenn Sie Glück haben, können Sie zwicken die Fahrer Verhalten, ohne zu patchen, aber Sie brauchen noch einen Blick auf den Fahrer-code. Jedoch ist der ARM Griff 10 kHz interrupt-rate wird sich sicherlich nicht gut für die Gesamtleistung des Systems...
Anderen Optionen ist, Ihr pad Paket, so dass Sie auf die fifo-Schwelle jedes mal. Es wird auch bestätigen, dass, wenn es ist oder nicht eine fifo-Schwelle-problem.
10 msec @ 115200 ist genug, um sende-100 bytes (vorausgesetzt, 8N1), so was Sie sehen, ist wahrscheinlich, weil die low_latency flag nicht gesetzt ist. Versuchen
Er die low_latency flag, das verwendet wird y der kernel beim verschieben von Daten in den tty-layer :
Den schedule_work nennen könnte verantwortlich sein für die 10 msec Latenz, die Sie beobachten.
versuchen zu kompilieren setserial für Ihre Plattform, und tun, ein setserial /dev/ttySx low_latency
Lesen Sie die Dokumentation low_latency es scheint zu sein, genau das was ich brauche. Allerdings hat es keine Auswirkungen auf mein Programm. Ich habe eine Theorie, warum ich für den test brauchen. Ich erhalten zurück zu Ihnen.
InformationsquelleAutor shodanex
Serielle ports unter linux sind "verpackt" in unix-style-terminal-Konstrukte, die trifft dich mit 1 tick Verzögerung, also 10ms. Versuchen Sie, wenn
stty -F /dev/ttySx raw low_latency
hilft, keine Garantie obwohl.Auf einem PC, können Sie gehen, hardcore und sprechen Sie mit seriellen standard-Schnittstellen direkt, Ausgabe
setserial /dev/ttySx uart none
zu lösen linux-Treiber vom serial-port hw-und control port überinb/outb
port-Register. Ich habe das ausprobiert, es funktioniert Super.Der Nachteil ist, dass Sie nicht bekommen, interrupts, wenn Daten ankommen und Sie haben die Umfrage registrieren. oft.
Sollten Sie in der Lage sein zu tun, denselben auf dem arm-Gerät Seite, kann viel schwieriger sein, auf exotische serielle Schnittstelle hw.
InformationsquelleAutor Dima Tisnek
Er mit etwas mehr Ingenieure über das Thema kam ich zu dem Schluss, dass dieses problem nicht lösbar ist im user-space. Da müssen wir über die Brücke in das kernel-land, planen wir die Implementierung eines kernel-Moduls, die Gespräche, unser Protokoll und gibt uns die Latenzen < 1ms.
--- edit ---
Stellt sich heraus, ich lag völlig falsch. Alle, die notwendig war, wurde zur Erhöhung der kernel-tick-rate. Die Standard-100-ticks Hinzugefügt, die 10ms delay. 1000Hz und einen negativen nice-Wert für den seriellen Prozess gibt mir die Zeit Verhalten, das ich erreichen wollte.
InformationsquelleAutor JustMaximumPower
Keiner von denen, die die Systemaufrufe haben eine Auswirkung auf die Latenz. Wenn Sie möchten, dass Lesen und schreiben ein byte, so schnell wie möglich aus dem userspace, Sie sind wirklich nicht besser zu machen, als ein einfaches
read()/write()
- pair-Mädchen. Versuchen austauschen der serielle Datenstrom mit einer Steckdose aus einem anderen userspace-Prozess und sehen, ob die Latenzen zu verbessern. Wenn Sie nicht, dann werden Ihre Probleme von der CPU-Geschwindigkeit und hardware-Einschränkungen.Sind Sie sicher, dass Ihre hardware dies überhaupt tun? Es ist nicht ungewöhnlich, UARTs mit einem Puffer-design, die führt viele bytes Wert der Latenz.
Ist das nur eine serielle PC-port? Wenn ja, könnten Sie Graben, um in die linux-Treiber (wie es aussieht ist in drivers/tty/serial/8250) um zu sehen, ob es gibt einen ioctl bieten programmgesteuerte Kontrolle über die FIFO-tiefen.
InformationsquelleAutor Andy Ross
Bei diesen Geschwindigkeiten sollte man nicht sehen, Latenzzeiten, große, unabhängig davon, wie Sie überprüfen Sie auf Bereitschaft.
Müssen Sie sicherstellen, dass der serielle port im raw-Modus (so dass Sie "mitgliedattribut liest"), und dass VMIN und VTIME richtig eingestellt sind. Sie wollen sicherstellen, dass VTIME ist null, so dass eine inter-character-timer nie in tritt. Ich würde wahrscheinlich beginnen mit der Einstellung VMIN auf 1 und Stimmen von dort.
Den syscall-overhead ist nichts im Vergleich zu der Zeit auf die Leitung, so dass select() und poll(), etc. unwahrscheinlich ist, einen Unterschied zu machen.
InformationsquelleAutor janm
Hier ist, was
setserial
macht zu geringer Latenz auf einen Datei-Deskriptor für ein port:cat
), aber nicht wirklich Einfluss auf die Latenz. Muss ich schließen und öffnen Sie den port, oder etwas zu tun, nachdem Sie die Einstellung der fahne?Sie sollten nicht brauchen, um etwas anderes zu tun.
Es scheint, dass Sie brauchen, um den code ausführen, als root zu arbeiten.
Das ist, was bekommt man für die Prüfung nicht die return-codes 🙂
Die
serial_struct
ist in<linux/serial.h>
, BTW.InformationsquelleAutor Kuba Ober
Kurz gesagt: Verwenden Sie einen USB-adapter und ASYNC_LOW_LATENCY.
Ich habe einen FT232RL-basierte USB-adapter) über Modbus an mit 115,2 kbs. Ich bekomme etwa 5 Transaktionen (bis 4 Geräte) in etwa 20 mS insgesamt mit ASYNC_LOW_LATENCY. Dies umfasst zwei Transaktionen zu einem slow-poke-Gerät (4 mS Reaktionszeit). Ohne ASYNC_LOW_LATENCY die Gesamtzeit beträgt etwa 60 mS. Mit FTDI USB-Adapter ASYNC_LOW_LATENCY legt die inter-character-timer auf dem chip selbst zu 1 mS (anstatt der Standard 16 mS). Ich bin derzeit mit einem Eigenbau-USB-adapter, und ich kann die Latenzzeit für den adapter selbst verwendet werden, um welchen Wert ich will. Einstellung bei 200 µS Rasiert, eine andere mS aus 20 mS.
InformationsquelleAutor Renate