Blockierendes Lesen, synchrone uns asynchrone Verbindungen...


TheJadix

Erfahrenes Mitglied
Hallo,

habe mal den Link zum Protokoll angesehen ! Sehr interessant !

Hat es einen bestimmten Grund warum du die Daten beim Empfang in einen
String umwandelst ?
Ich denke mal da wird nicht viel als Klartext zu erkennen sein ?
Also warum kein Array of byte oder int, auch wegen der Bit-Test-Operationen !
Die Maximal länge eines Frames ist ja bekannt (18 Byte richtig ?)
Ich würde sofort beim Empfang mit dem Packet-Objekt arbeiten,
welches dann das Array kapselt !

Synchronisiert sich das Protokoll nur über das Startbyte ?
Und kann im Datenstrom ein weiteres Byte mit dem Wert
des Startbytes erscheinen ?

Gruß JAdix
 

antimon

Mitglied
Ähm ja... eigentlich hats keinen richtigen Grund, ich gestehe meine Faulheit ein, bei Strings gehts halt recht einfach, was hinzuzufügen etc. - aber du hast Recht, ich kenne die maximale Länge, könnte also einfach mit Arrays arbeiten - werd ich wohl mal bei Gelegenheit umstellen.

Neben dem Startbyte gibt es noch eine zwei Byte breite Checksum, mit der überprüft werden kann ob ein Paket korrekt ist - leider kann das Startbyte auch in den Daten auftreten, aber da bei Ansteuerung des Adapters maximal 1 MBit/s möglich sind, genau wie auf dem abzuhörenden Bus, so ist jedes eingesparte Bit wichtig...

Hat natürlich den Nachteil dass ich bei jedem eintreffenden Byte, das gleich dem Startbyte ist, schauen muss ob es sich um einen Paketanfang handelt, sonst könnte irgendwann die Synchronisierung verlorengehen und es kommt nur noch Müll an...
 

TheJadix

Erfahrenes Mitglied
Hallo,

genau auf das Sync-Problem zielte meine Frage ab.

Wichtig wäre es also den Code so zu gestallten, dass ein evtl. Verlust
der Synchronisierung nach kürzester Zeit wieder aufgefangen wird.
Sprich nach einem CRC fehler keine Pakete mehr erzeugen bevor
nicht mindestens ein Frame wieder korrekt empfangen wurde !

Nochmal zur Geschwindigkeit :

1MBit also ca. 125kByte also Pi mal Daumen 10000 Pakete in der Sekunde
ist aber Mega-Worst-Case oder ?

Mit welcher Baudrate arbeitet die serielle Schnittstelle dabei ?

Gruß JAdix
 

antimon

Mitglied
Hmm jetzt glaub ich brauche ich zum Nachvollziehen deines Gedankenganges erst eine Begriffsdefinition...

keine Pakete mehr erzeugen bevor
nicht mindestens ein Frame wieder korrekt empfangen wurde

Meinst du mit "Pakete erzeugen" die Objekte, die aus den empfangenen Daten konstruiert wurden? Oder ausgehende Pakete?
Die Pakete werden nur weitergereicht, wenn alle benötigten Pakete vorhanden sind und die CRC stimmt - allerdings brauche ich da auch noch etwas Feintuning, dass beispielsweise erkannt wird wenn ein Paket zu lang ist und dann das Ganze verworfen wird...

Ja, 1 MBaud ist absoluter worst-case, aber so ein Adapter sollte ja auch unter diesen Bedingungen arbeiten können - nicht dass genau die Nachrichten verloren gehen, die eigentlich interessant wären. Wenn ich wüsste dass Nachrichten einfach so mal verloren gehen könnten, hätte ich ein ungutes Gefühl im Bauch. Leider hilft ein großer Empfangspuffer im Mikrocontroller auch nur über Traffic-Spitzen hinweg, bei Dauerbelastung ist der auch schnell voll (und "großer" Puffer im Mikrocontroller ist bei 256 Byte RAM eh blanker Hohn).

Gut, wenn ich mir so eine "professionelle" Sniffer-Software ansehe, sollte ich mir eigentlich nicht so viel Gedanken machen, die behauptet steif und fest, sie könnte bei einer Busdatenrate von 5 kbit/s jede Milisekunde eine Nachricht von ca. 16 Byte senden... ohne irgendwie Fehlermeldung, selbst der Sendepuffer ist angeblich zu 0% belegt...

Die Baudrate ist übrigens für RS232 genauso wie für den CAN-Bus 1 MBit/s... und du wirst dich vielleicht fragen, wie man bei RS232 auf 1 MBit/s kommt - das geht auch nur, weil vom USB-/RS232 Wandler bis zum Mikrocontroller verdammt wenig Leiterbahnstrecke vorhanden ist...

Wie würdest du denn die Empfangsroutine gestalten, du hast doch da Erfahrung - ich bin mir da leider irgendwie meist recht unsicher, und ausserdem bin ich Perfektionist und momentan mit meiner Lösung überhaupt nicht zufrieden...

Die Überprüfung ob ein Paket korrekt empfangen ist, geschieht im Paket-Objekt selbst - ich erzeuge also erst ein leeres Objekt, übergebe einer "parseString()"-Methode meine empfangenen Daten, die schaut ob die Datenlänge (je nach Frametyp) passt und ob die CRC stimmt - wenn nein wirft sie eine Exception.

Die Daten, die ich der parseString()-Methode übergebe, lese ich byteweise aus und sammle sie, die gesammelten Daten übergebe ich nach jedem empfangenen Zeichen erneut zum Parsen, könnte ja sein dass das Paket mittlerweile vollständig ist. Irgendwann ist dies erreicht, dann wird keine Exception geworfen und das fertige Paket wird zur Verteilung weitergereicht.

Was mir nicht gefällt: Auch wenn noch ansatzweise nicht alle Daten vorhanden sind, wird nach _jedem_ Byte die Vollständigkeit überprüft. Ich weiss dass ich aber _mindestens_ 4 Byte brauche, stellt sich nur die Frage - prüfe ich das am besten bevor ich die Daten zum Parsen ans Packet-Objekt übergebe oder übergeb ich sie und warte die Exception ab, wenn es noch nicht passt?

Und angenommen es tritt folgender (zugegebenermaßen, bzw. hoffentlich) seltener Fall ein:
Zwei Pakete werden hintereinander gesendet, wobei erstes das Startbyte in seinen Daten enthält und dummerweise ist genau das Startbyte vom ersten Paket verlorengegangen.
Das heisst, das Byte in den Daten des ersten Pakets wird als Startbyte erkannt, allerdings passt der Rest nicht dazu, bei der CRC sollte es dann nen Fehler geben. Verwerfe ich ab dort die Daten, so sind mindestens zwei Pakete verloren, obwohl das zweite vielleicht korrekt und vollständig ist...
Ich könnte natürlich aber nur ab dem vermeintlich ersten Paket alle Daten verwerfen bis das nächste Startbyte im Datenstrom auftritt und dann erneut mit der Auswertung beginnen. Dann wäre zumindest das zweite Paket nicht verloren, die ganze Auswertungsgeschichte wird aber auch erheblich komplizierter... was ist da wohl sinnvoller?
 

Forum-Statistiken

Themen
272.355
Beiträge
1.558.612
Mitglieder
187.829
Neuestes Mitglied
AlDi31