Forum: Mikrocontroller und Digitale Elektronik Optimierungsmöglichkeiten am Bootloader


von Ronny Schulz (Gast)


Lesenswert?

Ich habe für meinen ATmega128 einen Bootloader geschrieben. Dabei wird
Zeichen für Zeichen das Image übertragen. Die Bestätigung erfolgt durch
zurücksenden des selbigen Zeichens. Die Geschwindigkeit ist okay, klnnte
aber sicher besser sein. Folgende Ideen zur Optimierung habe ich und
würde gern wissen, welche Möglichkeiten sinnvoll sind:

- in Blöcken senden, also 8, 16 oder ähnlich und Checksumme errechnen
und nur die Checksumme vom Slave zurücksenden, anstatt die Zeichen zu
"echo'en"

- in Blöcken senden, also 8, 16 oder ähnlich und diese auch in einem
Stück zurücksenden

Machen die Änderungen überhaupt Sinn oder sollte ich es lassen, wie ich
es habe?

Bei der ersten Möglichkeit müsste ich auch noch eine Adresse mitsenden,
da sonst kein Eingriff im Fehlerfall möglich wäre.

von Werner B. (Gast)


Lesenswert?

Ein Blockübertragung wirst Du Dir spätestens wünschen sobald Du mit USB
-> RS232 Umsetzern arbeiten musst. Das wird bei einzelnen Bytes extrem
langsam.
Zur Blockgröße: Warum nicht gleich die flash-pagesize verwenden?

von Ronny Schulz (Gast)


Lesenswert?

Naja auf 256 Bytes wird die Checksumme dann nicht mehr so real sein,
denke ich. Es sei denn ich erhöhe sie auf 16 Bit.

Ist die Flashpagesize immer gleich oder differiert die zwischen den
einzelnen AVRs? Spätestens da wird es interessant, wo man den
Bootloader anpassen muss.

Aber ich denke ich werde das wirklich mit der Blocksache so
realisieren.

von Daniel B. (khani)


Lesenswert?

Hallo Ronny,

die Größe der Pages differiert.

Das ist auch der Grund, warum Atmel sich in der AppNote 109 "Self
programming" ein wenig verbiegt.

Wenn  Du Deinen Bootloader optimieren willst, dann schau die mal die
beiden Appnotes 109 und 911 von Atmel an. Die beschreiben eine
Kombination aus Bootloader und PC-Software zum Programmieren.

Der Vorteil des (auch von mir eingesetzten) Modells liegt in der
leichten Anpassbarkeit an andere Mikrocontroller aus der AVR-Familie.

MfG, Daniel.

P.S.: Der Bootloader wurde übrigens von mir nach WinAVR portiert.

von Unbekannter (Gast)


Lesenswert?

Ronny, was Du implementiert hast, ist ein so genanntes "Stop and Go
Protocol".

D.h. der Sender überträgt ein Datenpaket (kann auch nur ein Byte sein)
und wartet bis der Empfänger eine Antwort schickt und überträgt dann
das nächste Paket etc.

Dieses Verfahren ist immer langsam, weil Du nur maximal die Bandbreite
in einer Richtung nutzen kannst. In Deinem speziellen Fall, der
Byteweisen-Übertragung, nutzt Du nur maximal die halbe Bandbreite der
seriellen Verbindung.

Denn der Sender sendet in einer Zeiteinheit ein Byte. Nun muss er aber
eine Zeiteinheit warten in der der Empfänger ein Byte sendet. D.h. die
hälfte der Zeiteinheiten in der der Sender senden könnte, wartet er und
sendet eben nicht.

Und noch deutlich langsamer wird es, wenn Sender und Empfänger noch
Latenzzeiten haben in der Größenordnung der Übetragungszeiteinheiten.
D.h. wenn sie nicht sofort antworten, sondern erst etwas ausrechnen
müssen und deshalb noch mehr Zeit vergeht und dann antworten.

Die einfachste Lösung des Problems ist schon mal, die Senderpakete
größer machen, und die Paket die vom Empfänger zurück geschickt werden
möglichst klein zu halten.
Aber selbst dann erreichst Du nie 100% Bandbreite.

Die einzige Möglichkeit besteht darin, eine Art "Fenster" zu
verwenden. D.h. der Sender sendet unentwegt die Daten, und sendet z.B.
bis zu 5 unbestätigte Datenpakete an den Empfänger.
Der Empfänger wiederum bestägt jedes Datenpaket sofort, wenn er es
komplett erhalten hat.
Im Idealfall sieht das dann so aus.

1.) Sender sendet erstes Paket komplett, erhält keine Bestätigung.
2.) Sender sendet sofort danach das zweite Paket an den Empfänger.
3.) Während der Sender das zweite Paket sendet, empfängt er die
Bestätigung für das erste Paket.
4.) Sender sendet unverzüglich nach dem zweiten Paket das Dritte.
5.) Währed der Sender das dritte Paket sender, erhält er die
Bestätigung für das zweite Paket.
6.) ...
7.) Der Sender sendet das letzte Paket und erhält währed dessen die
Bestätigung für das vorletzte Paket.
8.) Der Sender hat aufgehört zu senden und muss nun auf die Bestätigung
des letzten Pakets warten.

So in etwa funktionieren Netzwerkprotokolle im Internet. Nur so ist
eine schnelle Datenübertragung möglich.

Was die Sache eben etwas komplizierter macht, ist wenn Pakete frisch
gesendet werden sollen, oder der Empfänger zu langsam ist etc.

Gute Literatur, ein Klassiker, zu diesem Thema ist:

   "Computer Networks" von Andrew S. Tanenbaum

   http://www.amazon.de/exec/obidos/ASIN/0130384887/

von Ronny Schulz (Gast)


Lesenswert?

Ich bedanke mich für die vielen Ratschläge. Allerdings so riesig
Unterlagen wälzen wollte ich jetzt nicht.

Deshalb habe ich meinen Code jetzt weitgehend fertiggestellt. Ist zwar
noch nicht gestestet, aber so solls laufen:

Bootloaderprogramm wird auf PC gestartet und wartet bis sich der Slave
meldet. Dann passiert folgendes:

- Übertragung der Blockgröße vom Slave (PGM_PAGESIZE)
- Übertragung der Blocknummer vom Master
- Übertragung der Dtaen im Block vom Master (wichtig bei Dateiende,
sonst PGM_PAGESIZE)
- Übertragung der Daten vom Master
- Übertragung der Checksumme der Daten vom Slave

Stimmt die Checksumme nicht, wird der gleiche Block erneut übertragen.

Ich denke so kann die Lösung aussehen udn wird sicher auch schneller
sein.

Was meint ihr?

von Ronny Schulz (Gast)


Lesenswert?

Also Punkt 3 meine ich:
- Übertragung der Datenpaketgröße .. wichtig bei Dateiende, sonst immer
PGM_PAGESIZE

hatte mich da etwas verwirrt ausgedrückt.

von Barti (Gast)


Lesenswert?

Interessant. Müßte ausreichend sein. Werde das Schema mal auf meinen
Bootloader anwenden. Zur Zeit ist er halt noch im "Versuchsstadium".
Er überträgt und flashed perfekt. Habe aber noch keine Fehlererkennung
à la Checksumme integriert. Wie berechnest Du deine? Einfach alle Bytes
aufaddieren in eine 16-bit Variable? Wäre das Einfachste.

Ich bin auch begeistert von dem Bootloader, da er so schön schnell ist
und ich meine Controller jetzt über RS232 und mit Wandler über USB
flashen kann. Mega16 ist in ca. 3sek beschrieben(Flash-Sektion ohne
Bootloader-Sektion =15kB - leider noch ohne Checksummen-Prüfung), nicht
wie bei PonyProg, das immer ne Ewigkeit braucht und ich immer noch
Zusatzkabel ranklemmen muß.

MfG Barti

von Ronny Schulz (Gast)


Angehängte Dateien:

Lesenswert?

Also ich hatte jetzt noch einen Fehler in der Checksummenprüfung, der
jetzt behoben ist. Die Übertragung funktioniert super und auch
schnell.

Und ja ich addiere einfach die Datenbytes in 16 Bit.

Der Flashvorgang scheint aber noch nicht zu funktionieren. Die
Byte-für-Byte-Version ging. Warum das jetzt nicht geht, weiß ich auch
noch nicht. Sollte eigentlich funktionieren. Der Flash bleibt aber
leer. Das werde ich mir bei Zeiten mal ansehen.

Ich habe mal den Quellcode des bootloaders rangehangen. Wen es
interessiert... aber wie gesagt der Flashvorgang geht noch nicht so
recht.

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
Noch kein Account? Hier anmelden.