Linux High-Speed-Zeichenerkennung RS232

430
romaric crailox

Ich muss einen Code in C machen, um die Zeit zwischen den Zeichen innerhalb einer RS232-Zeile unter Linux zu ermitteln. Die zu erkennende Zeit zwischen den Zeichen könnte 1 ms betragen. Ich brauche also etwas, um sehr schnell einen eintreffenden Charakter mit einem Zeitstempel zu versehen. Wenn ich sehr schnell sage, ist weniger als 1ms. Das Ziel besteht darin, das Ende eines Frames und den Beginn eines neuen Frames in der Zeile zu erkennen.

Ich frage nicht nach einer Kodierungslösung, ich möchte nur eine erste Hilfe, um zu wissen, welchen Weg ich einschlagen muss: Ist es möglich, dies unter Linux zu tun? Ich muss einen Fahrer ändern, um diese Zeit zu erreichen. Oder etwas aus dem Benutzerraum kann das (ich glaube nicht).

0
Klingt nach weichem Echtzeitverhalten. Mit PC-Hardware und -Software ist dies nur schwer zu erreichen Daniel B vor 6 Jahren 1
Auch wenn ich den Treiber bereits modifiziere (ich werde näher an der Hardware sein ...)? romaric crailox vor 6 Jahren 0
Ich denke, Sie könnten besser versuchen, die rohen Signale zu erfassen. Bei niedrigen Bitraten können Sie möglicherweise den Audioeingang verwenden, für höhere Geschwindigkeiten benötigen Sie jedoch eine Hochgeschwindigkeits-AD-Aufnahmeschnittstelle. In der Tat benötigen Sie ein Software-Oszilloskop. AFH vor 6 Jahren 1
Danke AFH, aber ich denke es ist ein Fehler. Ich möchte dieses C-Programm nicht für das Debuggen ausführen, sondern in der Lage sein, ein Stummschalten von 1 ms zwischen dem Empfang von zwei Zeichen in der Zeile rs232 zu erkennen. Ich möchte das tun, weil ein Stummschalten von mehr als 1 ms das Ende eines Frames und den Beginn eines neuen Frames bedeutet. romaric crailox vor 6 Jahren 0

2 Antworten auf die Frage

1
dirkt

Ist das ein On-Board-UART oder ein USB-Dongle? Zum einen würde ich die Interrupt-Routine des seriellen Treibers so ändern, dass die Daten zusammen mit einem Zeitstempel gespeichert werden, die Daten mit dem Zeitstempel an den Benutzerbereich übermittelt werden und der Benutzerbereich den Inhalt bestimmen lässt. Während Linux nicht in Echtzeit ist, würde ich erwarten, dass es alle Interrupts in weniger als 1 ms beantworten kann. Das sollte ausreichen.

Für einen USB-Dongle werden usbmonbereits Zeitstempel in Mikrosekunden bereitgestellt. Daher sollte ich in der Lage sein, entweder usbmonden normalen seriellen USB-Treiber gemeinsam zu verwenden und den seriellen USB-Treiber zu modifizieren, um diese Zeitstempel zugänglich zu machen.

Es ist ein UART an Bord. Dies ist auch meine "Lieblings" -Lösung, da in meiner Situation ein benutzerdefinierter Treiber leider einfacher ist als das Ändern der Hardware. romaric crailox vor 6 Jahren 0
1
sawdust

Ich muss einen Code in C machen, um die Zeit zwischen den Zeichen innerhalb einer RS232-Zeile unter Linux zu erkennen ...

Sie haben ein XY-Problem gepostet .

Ich möchte das tun, weil ein Stummschalten von mehr als 1 ms das Ende eines Frames und den Beginn eines neuen Frames bedeutet.

(Übrigens ist bei der asynchronen seriellen Kommunikation wie RS-232 die uneingeschränkte Verwendung von "Frame" nicht eindeutig, da jedes Zeichen gerahmt wird. ZB wenn ein UART einen "Framing-Fehler" meldet, ging (möglicherweise) ein Zeichen verloren. Vermutlich meinen Sie damit Paket oder Nachrichteneinheit.)

Ihr zusätzlicher Kommentar enthüllt schließlich das eigentliche X-Problem, das gelöst werden muss.
Da das eigentliche Problem das Erkennen von Lücken zwischen Nachrichten ist, ist die ursprüngliche Frage zu Y nicht nur schwer in Software genau zu implementieren, sondern es ist nicht einmal eine praktikable Lösung für das X-Problem.

Jede Lösung, die das "Messen" des Zeitintervalls zwischen empfangenen Zeichen durch Software zum Erkennen einer Lücke zwischen Nachrichten umfasst, ist eine fehlerhafte Lösung. Dieser Ansatz schlägt für den degenerierten Fall fehl:
Wenn das letzte Zeichen einer Nachricht ankommt und keine Zeichen mehr vorhanden sind (für eine Weile), wird die zuletzt empfangene Nachricht auf unbestimmte Zeit blockiert, während der Algorithmus auf das nächste Zeichen (das erste Byte von) wartet nächste Nachricht), damit die Zeitdifferenz berechnet werden kann.
Solange dieses "nächste Zeichen" nicht empfangen wird, wird das "Ende der Nachricht" nicht bestimmt, und die letzte gültige Nachricht ist abgeschlossen, aber nicht verarbeitet.

Die richtige Lösung ist die Verwendung von Hardware, mit der gemessen werden kann, wann ein Zeichen empfangen wurde oder nicht. Einige Atmel USARTs verfügen über eine Empfänger-Timeout- Funktion, um die Lücke zwischen den Nachrichten zu erkennen.

Eine mögliche Softwarelösung würde einen (hochauflösenden) periodischen Zeitgeber erfordern, den der U (S) ART-Treiber verwenden würde, um Zeitintervalle zwischen empfangenen Zeichen zu zählen. Wenn PIO anstelle von DMA verwendet wird, muss der Treiber die Anzahl der Intervalle zurücksetzen, wenn ein Zeichen empfangen wird. Wenn der Zählwert einen Schwellenwert überschreitet (z. B. zählintervallzeit> inter_message_gap_time), war der Empfänger zu lange stumm, was auf eine Lücke zwischen den Nachrichten hindeutet.

* Jede Lösung, die das "Messen" des Zeitintervalls zwischen empfangenen Zeichen durch Software zum Erkennen einer Lücke zwischen Nachrichten umfasst, ist eine fehlerhafte Lösung. * Leider ist MODBUS über die serielle Leitung so etwas und wahrscheinlich nicht das einzige Protokoll, das dies tut. pim vor 6 Jahren 1
@pim - Ich kenne das MODBUS-Protokoll, also was ist dein Standpunkt? Anscheinend haben Sie entweder die Antwort nicht gelesen oder verstehen die damit verbundenen Probleme nicht. Die richtige Lösung für solche Protokolle ist das Erkennen einer Empfangszeitüberschreitung, wohingegen Zeitstempelzeichen und das Berechnen der Deltazeit (dh Messen des Zeitintervalls) fehlerhaft sind (dh, sie funktionieren nicht in allen Situationen). sawdust vor 6 Jahren 1
Ich bin mir nicht sicher, Ihren degenerierten Fall zu verstehen: Wenn ich eine sehr schnelle Lösung habe, die jeden eingehenden Charakter mit einem Zeitstempel versehen kann, dann muss dies durch eine niedrigere Ebene erfolgen. Danach liest ein Benutzer-Space-Programm irgendwann alle verfügbaren Zeichen und bestimmt mit einem Zeitstempel ein Zeichenpaket. Dieser Ansatz umgeht den degenerierten Fall: Wenn das Benutzerraumprogramm das letzte verfügbare Zeichen liest, wird mit dem Zeitstempel und der Systembetriebszeit berechnet, wie viele Zeitzeichen verfügbar sind. Und kann feststellen, ob es sich um ein Zeichenpaket handelt oder nicht. Ich liege falsch ? romaric crailox vor 6 Jahren 0
* "Wenn das Benutzerraumprogramm das letzte verfügbare Zeichen liest" * - Das ist nicht zuverlässig. Dieses * letzte Zeichen * (abhängig von der * termios * -Konfiguration) kann einfach ein Fragment der Nachricht und nicht das Ende der Nachricht sein. * "Berechnet mit Zeitstempel und Systembetriebszeit" * - Diese Berechnung gibt nur die Latenz zwischen Interrupt-Level und Ihrer App an. was ist das gut? Außerdem kann diese Latenzzeit erheblich sein (z. B. mehrere Millisekunden), insbesondere wenn der Benutzerraum ausgesetzt ist. Daher könnte Ihre Berechnung falsche Positive für die 1ms der Stille auf den falschen Charakter erzeugen. sawdust vor 6 Jahren 1
@pim - Hier ist eine 3 Jahre alte Antwort, um meine Widerlegung zu Ihrem Kommentar zu bestätigen: https://stackoverflow.com/questions/27152926/parsing-time-delimited-uart-data/27156684#27156684 sawdust vor 6 Jahren 1