GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Serielle Kommunikation mit geringer Latenz unter Linux

Anforderungs-/Antwortschemata sind in der Regel ineffizient und werden schnell an der seriellen Schnittstelle angezeigt. Wenn Sie am Durchsatz interessiert sind, schauen Sie sich das Fensterprotokoll an, wie das Kermit-Protokoll zum Senden von Dateien.

Wenn Sie nun an Ihrem Protokoll festhalten und die Latenz reduzieren möchten, erhalten Sie mit select, poll, read ungefähr die gleiche Latenz, da, wie Andy Ross angedeutet hat, die tatsächliche Latenz in der Hardware-FIFO-Verarbeitung liegt.

Wenn Sie Glück haben, können Sie das Treiberverhalten ohne Patchen optimieren, aber Sie müssen sich immer noch den Treibercode ansehen. Wenn der ARM jedoch eine Unterbrechungsrate von 10 kHz handhabt, ist dies sicherlich nicht gut für die Gesamtsystemleistung ...

Eine weitere Option besteht darin, Ihr Paket so aufzufüllen, dass Sie jedes Mal den FIFO-Schwellenwert erreichen. Es wird auch bestätigen, ob es sich um ein FIFO-Schwellenwertproblem handelt oder nicht.

10 ms @ 115200 reichen aus, um 100 Bytes zu übertragen (unter der Annahme von 8N1), was Sie also sehen, liegt wahrscheinlich am low_latency Flag ist nicht gesetzt. Versuchen Sie es

setserial /dev/<tty_name> low_latency

Es setzt das low_latency-Flag, das vom Kernel verwendet wird, wenn Daten in der tty-Schicht nach oben verschoben werden:

void tty_flip_buffer_push(struct tty_struct *tty)
{
         unsigned long flags;
         spin_lock_irqsave(&tty->buf.lock, flags);
         if (tty->buf.tail != NULL)
                 tty->buf.tail->commit = tty->buf.tail->used;
         spin_unlock_irqrestore(&tty->buf.lock, flags);
 
         if (tty->low_latency)
                 flush_to_ldisc(&tty->buf.work);
         else
                 schedule_work(&tty->buf.work);
}

Die schedule_work Der Anruf könnte für die beobachtete Latenz von 10 ms verantwortlich sein.


Serielle Ports unter Linux werden in Terminalkonstrukte im Unix-Stil "verpackt", was Sie mit einer Verzögerung von 1 Tick, dh 10 ms, trifft. Versuchen Sie es mit stty -F /dev/ttySx raw low_latency hilft, aber keine Garantien.

Auf einem PC können Sie Hardcore spielen und direkt mit seriellen Standardanschlüssen sprechen, geben Sie setserial /dev/ttySx uart none aus um den Linux-Treiber vom seriellen Port hw zu lösen und den Port über inb/outb zu steuern Register zu portieren. Das habe ich ausprobiert, es funktioniert super.

Der Nachteil ist, dass Sie keine Interrupts erhalten, wenn Daten ankommen, und Sie das Register abfragen müssen. oft.

Sie sollten in der Lage sein, dasselbe auf der Seite des Armgeräts zu tun, möglicherweise ist dies bei exotischen seriellen Port-HW viel schwieriger.


Nachdem ich mit einigen weiteren Ingenieuren über das Thema gesprochen hatte, kam ich zu dem Schluss, dass dieses Problem nicht im Benutzerraum lösbar ist. Da wir die Brücke ins Kernel-Land überqueren müssen, planen wir die Implementierung eines Kernel-Moduls, das unser Protokoll spricht und uns Latenzen <1 ms gibt.

--- Bearbeiten ---

Es stellte sich heraus, dass ich völlig falsch lag. Dazu musste lediglich die Tickrate des Kernels erhöht werden. Die standardmäßigen 100 Ticks fügten die Verzögerung von 10 ms hinzu. 1000Hz und ein negativer netter Wert für den seriellen Prozess gibt mir das Zeitverhalten, das ich erreichen wollte.


Hier ist was setserial tut, um eine niedrige Latenz für einen Dateideskriptor eines Ports festzulegen:

ioctl(fd, TIOCGSERIAL, &serial);
serial.flags |= ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);

Linux
  1. Einführung in den Leitfaden zur Kommunikation zwischen Prozessen in Linux

  2. Linux – Lautstärke des Bluetooth-Headsets zu niedrig (nur in Arch)?

  3. Fehlerbehebung bei langsamer Netzwerkkommunikation oder Verbindungszeitüberschreitungen in Linux

  4. Virtueller serieller Port für Linux

  5. Wie kann ich Daten an einer seriellen Schnittstelle in Linux überwachen?

Serielle Kommunikation unter modernem Linux

Fehlerbehebung bei geringem Speicherplatz für einen Linux-Cloud-Server

Listener und Interpreter für serielle Linux-Ports?

Debuggen der Linux-I/O-Latenz

Was sind High Memory und Low Memory unter Linux?

Begrenzen Sie die ein- und ausgehende Bandbreite und Latenz in Linux