Guten Morgen, für ein Firmware-Update müssen mehrere KByte Daten auf einen Mikrocontroller transportiert werden. Als Kommunikationsschnittstelle wird UDP eingesetzt. Meine jetzige Implementierung funktioniert so, dass die Übertragung durch ein erstes Segment an Daten gestartet wird. Sobald der Mikrocontroller ein Acknowledge Frame an den PC sendet wird daraufhin gleich das nächste Segment versendet. Der Upload Vorgang läuft nicht immer zuverlässig. Wie könnte man den Update-Vorgang stabiler realisieren?
user schrieb: > Wie könnte man den Update-Vorgang stabiler realisieren? Indem man herausfindet, weswegen es nicht stabil (Hardware und/oder Software) läuft. UDP läuft eigentlich sehr zuverlässig, somit ist es fraglich, ob ein eigenes Protokoll besser läuft.
Ja da bin ich auch überfragt ob es an der Hardware oder Software liegt.
user schrieb: > Ja da bin ich auch überfragt ob es an der Hardware oder Software liegt. Damit gibt es jetzt für Dich 3 Möglichkeiten: 1) Dich in die Hard- und Software soweit einzuarbeiten, dass Du mit geeigneten Werkzeugen (Oszilloskop, In-Circuit Emulator, etc.) den/die Fehler findest. 2) Eine gute Glaskugel besorgen. 3) Das Projekt ohne Lösung beenden.
Was passiert denn, wenn mal ein Daten-/ACK-Paket nicht durchkommt? Nutzt Du "retransmit timer"? (siehe TFTP)
Manchmal kommt auf der PC Seite das Ack Telegramm nicht an. Ein "retransmit timer" habe ich nicht.
reines UDP kann per Definition keine zuverlässige Kommunikation garantieren, dafür ist es nicht gemacht. Selbst wenn Du herausfindest, warum es in deiner Combo Hard/Software nicht zuverlässig tut und das fixt, wird die Kommunikation in anderen Netzwerken wieder haken. Für zuverlässige Kommunikation ist TCP gemacht. Wenn Du zuverlässig kommunizieren willst, aber auf UDP nicht verzichten willst oder kannst, musst Du die Mechanismen von TCP zur verlässlichen Kommunikation emulieren (also Paketsequenzierungen und retransmissions). Oder gleich TCP benutzen.
Bei UDP kann es immer vorkommen das Telegramme nicht beim Empfänger ankommen. Sei es durch Überlastung von zwischengeschalteten Netzwerkswitchen, dem Empfänger/Sender (Betriebs)-system oder EMV Störungen die die Übertragung stören. Das ist per Definition so. Braucht man sichere Datenübertragung per UDP muss mann sich ein Handshakeprotokoll ausdenken, bei dem jedes einzelne Telegram vom Empfänger bestätigt werden muss. Der Empfänger muss dann natürlich auch damit klar kommen Daten mehrfach zu empfangen, nämlich dann wenn seine Bestätigung nicht beim Sender der Daten ankommt und dieser deswegen die Übertragung wiederholt. Beispiele für solche Protokolle wäre das o.g TFTP oder auch das Connectionless DCERPC. Alternativ könnte man den gesamten Datenblob auch per Prüfsumme absichern und wenn diese falsch ist die Übertragung einfach nochmal komplett wiederholen. Wäre in diesem Fall eventuell einfacher.
UDP ist ein Hinausschreien in den Wald. Bedeutet irgendwas an Sicherheit muss selbst gemacht werden. Das Protokoll muss zustandsfrei sein. Also nicht ein Block kommt nach dem Anderen, mit autoincrement, sondern die Bloecke werden adressiert uebertragen. Die Quitierung, nach einem Block, inkl. CRC, enthaelt die Blocknummer. Dann ist auch klar welcher Block nochmals gesendet werden muss. Das Protokoll sieht also irgendwie so aus : PC : SendFirmware, Ver# 1234, len=1234, #bloecke=25, CRC uC : ok, SendFirmware, Ver# 1234, CRC PC : SendBlock=1, len=40, CRC uC : ok, SendBlock=1, CRC PC : SendBlock=2, len=40, CRC uC : ok, SendBlock=2, CRC
Ok vielen Dank für eure Beiträge. Gibt es das TFTP Protokoll quasi als open source Software ?
Wie andere schon gesagt haben, ist UDP für sowas nicht gedacht. Vorallem da du auch noch das System mit dem ack nutzst und Pakete hintereinander abschickst, bringt dir das nicht mal einen Geschwindigkeitsvorteil gegenüber anderen Protokollen (bei z.B. Multiplayer games wird aufgrund der Gewchwindigkeit oft zum Teil auf UDP gesetzt). Wenn du nach TFTP Lizenz googlest, findest du ein paar Open Source Implementationen, daher würde ich davon mal ausgehen. Alternativ mal TCP anschauen.
Ich würde einfach das Programm dahingehend ändern, dass Du auf der PC-Seite nicht stumpf auf ein ACK vom µC wartest, sondern auch erfasst, wie lange er auf das ACK wartet. Dann nach z.B. 100 ms abbrechen und den aktuellen Block wiederholen. Nach ein paar erfolglosen Versuchen noch das Senden mit Fehlermelsung beenden. Dazu ist es wichtig, die aktuelle Blocknummer mit zu übertragen. Auf der µC-Seite noch den zuletzt geschriebenen Block merken und bei Wiederholung einfach ignorieren. Wegen ein paar kb muss man keinen TCP-Stack oder ein komplettes TFTP implementieren.
Ich habe nun meine Applikation auf einem Microcontroller um eine TCP Verbindung erweitert. Nun kann ich per UDP und auch per TCP auf den Mikrocontroller zugreifen. Wie würde dies nun genauer aussehen, wenn nun größere Datenmenegen via TCP an den Mikrocontroller versendet werden?
Kann über TCP sichergestellt werden wenn zum Beispiel 500 Frames a 500 Bytes übertragen werden das diese Daten auch alle ankommen?
user schrieb: > Kann über TCP sichergestellt werden wenn zum Beispiel 500 Frames a 500 > Bytes übertragen werden das diese Daten auch alle ankommen? Was TCP sicherstellt ist Folgendes: Voraussetzung: Eine Verbindung ist etabliert (also asymmetrisches Open - listen/accept() auf Serverseite und connect() auf Clientseite - ist erfolgreich abgeschlossen). Du schiebst von der einen Seite x (z.B. 500) bytes mit send() Aufrufen in die Verbindung. TCP garantiert, dass Du auf der Anderen Seite mit recv() Aufrufen genau diese x bytes in genau der Reihenfolge zurückliest, solange die Verbindung nicht in der Zwischenzeit geschlossen wird. Exoten wie Out-Of-Band Data seien hier mal vernachlässigt. TCP stellt sicher, dass keine Daten verloren gehen oder im Datenstrom ihre Positionen wechseln. Im Nutzdatenstrom von TCP hat zunächst der Begriff des "frames" keine Bedeutung. In TCP gibt es einen "Stream," dessen innere Struktur TCP nicht interessiert. TCP entbindet Dich nicht davon, ein Protokoll auf höherer Ebene zu spezifizieren und zu implementieren. TCP ist inherent Voll Duplex, d.h. beide Seiten können unabhängig voneinander und asynchron jederzeit Daten senden. OB die das tun, hängt davon ab, welches Applikationsprotokoll über TCP realisiert ist. In vielen Fällen ist das darüberliegende Protokoll Halbduplex, d.h. die beiden Partner erwarten eine gewisse Ordnung der Daten und wechseln sich in einem PingPong Spiel mit Datensenden und -bestätigen ab. Das muss aber nicht sein. TCP garantiert keine Maximallatenz zwischen Senden und Empfangen derselben Daten. Programmtechnisch ist das Arbeiten mit TCP relativ einfach. Du brauchst im Kern nur send() (~write) und recv() (~read) mit einem socket (~Verbindungskennung, die nach Verbindungsaufbau geliefert wird) als Parameter. Dafür gibt es unendlich viele Beispiele im Netz. Es gibt aber zur Realisierung von stabilen Kommunikationen ein paar Fallstricke zu beachten. Z.B. machen nach wie vor erstaunlich viele Leute den Fehler, die Returnwerte von send() und recv() zu ignorieren und damit ihre Kommunikation zum Stolpern zu bringen. Ausserdem sollte jedes High Level Protokoll mit Timeouts abgesichert sein, um z.B. zu verhindern, dass ein Bug im Protokoll des peers die einene Seite der Kommunikation einfriert. Auch sollte das Protokoll über TCP einigen Anforderungen genügen (z.B. bei variabel langen Paketen die Paketlänge im header enthalten). Im Kapitel 7 meines Buches widme ich mich den Details relativ ausführlich.
:
Bearbeitet durch User
TCP ist nicht so einfach, bei vollständig implementiertem IP Layer ist es aber schon recht sicher. UDP kann ja da so ziemlich nichts. Ich würde trotzdem UDP nehmen und Redunanz einbauen, damit möglichst wenig schief geht. Manche Router machen z.B. bei USP komische Sachen! Wichtig ist in jedem Fall genaue Prüfungen der empfangenen SW bevor irgendwas geflascht wird. Auch golden image handling wird benltigt. Und wie gesagt, einiges an Redunanz auf dem Zuführkanal, weil sonst zu oft was schief geht. Wir haben gerade so ein nettes Problem. Es ist kaum was rein oder rauszubekommen von und ins Gerät.
> Welche Hardware, welche Software?
Beim ENC28j60 ist im Netz viel über Hardware-Probleme gerätselt worden,
die mit zusätzlichen Kondenstoren gelöst werden sollten. Ich hatte diese
HW-Probleme auch. Mit Verwendung geänderter Software waren sie weg.
Paul schrieb: > UDP läuft eigentlich sehr zuverlässig, ... UDP garantiert für überhaupt nichts. Der Empfänger eines Blockes kann nur entscheiden, ob es den Block richtig empfangen hat, aber es ist bei UDP völlig unklar, ob alle Blöcke beim Empfänger ankommen. Wenn es auf sichere Übertragung ankommt, muss eine Protokollschicht oberhalb von UDP dafür sorgen. Da kann man mit relativ wenig Aufwand sich selber etwas ausdenken, ohne gleich ein komplexes Protokoll komplett neu zu erfinden - aber UDP alleine reicht für die Aufgabe nicht.
user schrieb: > Ok vielen Dank für eure Beiträge. > > Gibt es das TFTP Protokoll quasi als open source Software ? TFTP ist in RFC-1350 definiert (mit ein paar optionalen Erweiterungen RFC-2347, 2348, 2349), es gibt etliche freie Implementierungen für Server und Client. TFTP ist so simpel gestrickt daß man in 2 Stunden mit nichts als der nackten socket API selber einen vollständigen Server zusammengeklöppelt hat, das hab ich am Donnerstag Nachmittag für mein Update-Tool gemacht, die paar Dutzend Zeilen Code schnell selber hinzuschreiben ging unter dem Strich schneller als lang herumzugoogeln um einen der vielen existierenden Server auszusuchen und dann so mit meinem eigenen Programm zu verheiraten daß es aussieht als wäre alles aus einem Guss. Im Prinzip wird einfach ein Block an Daten als ein UDP Paket geschickt, im 4 Byte langen Header stehen 2 Byte Sequenznummer und 2 Byte Datenlänge, jedes Paket muss vom Empfänger mit einem ACK-Paket quittiert werden, der Sender wartet nach jedem Block auf das ACK bevor er den nächsten sendet. Es gibt einen Timeout, dann wird das letzte Paket mit der letzten Sequenznummer einfach nochmal gesendet, so oft bis endlich ein ACK kommt. Das Ende wird markiert indem ein Block gesendet wird der weniger Daten als die maximale Blocklänge enthält. Das ist schon alles.
Bernd K. schrieb: > ... der Sender wartet nach jedem Block auf das ACK bevor er den > nächsten sendet. Bei einer längeren Datenübertragungskette macht das die Sache unnötig langsam. Der Sender könnte den nächsten Block durchaus schon vor Eintreffen des ACK senden und muss nur buchführen, welche Blöcke schon bestätigt sind. Dann kann immer noch ein Timeout greifen, ohne bei jedem Block die Warterei einzubauen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.