Forum: Compiler & IDEs Bootloader - Fehler bei unterschiedlich langen Hex-Files


von Hauke F. (axfire)


Lesenswert?

Hallo Leute,

ich habe ein Bootloader Programm für den ATMega644P geschrieben, wobei 
ich mich sehr an die Anleitung „AVR Bootloader in C – eine einfache 
Anletung“ gelehnt habe. Das zugehörige PC-Programm zum Überspielen des 
Hex-Files habe ich ebenfalls selbst geschrieben.

An sich funktioniert der Bootloader wünschenswert, nur gibt es ein 
scheinbar „zufälliges“ Problem:

Nachdem der Bootloader das neue Anwenderprogramm in den Flash-Speicher 
geschrieben hat, verlässt der Controller mittels Funktionspointer auf 
Adresse 0x0000 den Bootloader und startet das soeben „geflashte“ 
Anwenderprogrammen. Das Starten des Anwenderprogramms funktioniert 
leider nur meistens. Anscheinend ist es von der Größe des 
Anwenderprogramms abhängig.

Wenn ich zum Beispiel mittels Bootloader ein Anwenderprogramm, welches 
18942 Bytes groß ist, schreibe und starte, funktioniert alles.
Wenn das selbe Anwenderprogramm aber 18944 Bytes groß ist, da ein String 
leicht verändert wurde, springt der Controller nach dem Schreiben zwar 
auf Adresse 0x0000, ist dort aber anscheinend in einer Endlosschleife 
gefangen. Jedenfalls tut sich nichts mehr. Auch nach einem 
Controllerneustart läuft der Controller das Anwenderprogramm, nach dem 
Verlassen des Bootloaders, nicht an.

Ich habe eine kleine Versuchsreihe mit unterschiedlich großen 
Anwenderprogrammen gemacht. Die einzelnen Programme sind alle identisch, 
es wurde nur ein einziger String verändert, um die Größe des Programms 
zu verändern. Sie wurden mit dem Atmel Studio 6.2 erstellt. Hier die 
Ergebnisse:

Größe in Bytes:    Funktioniert:
18912      ja
18914      ja
18940      ja
18942      ja
18944      nein
18946      nein
18948      nein
18950      nein
18952      ja
18954      ja
18956      ja
18958      ja
18960      ja

Von einem Kollegen habe ich außerdem Programme getestet, welche mit 
Code::Blocks erstellt wurden. Auch diese Programme sind fast identisch.

Größe in Bytes:    Funktioniert:
18866      ja
18800      ja
18913      nein
18920      ja
18936      ja
18946      nein
18965      nein
18975      nein
19022      ja

Komisch finde ich, dass es mit Code::Blocks möglich ist, Programme zu 
erstellen, die eine ungerade Bytegröße haben. Mit dem Atmel Studio 
konnte ich nur „gerade“ Programme erstellen. (Wieso denn eigentlich)?

Hat Jemand eventuell eine Idee, wo in etwa der Fehler liegen könnte? Ich 
hatte zuerst Adressierungsfehler beim Schreiben des Hex-Files im Sinn, 
aber die Größenunterschiede der Programme sind ja so gering… So langsam 
gehen mir leider die Ideen aus, wo ich noch nach Fehlern suchen könnte 
:(

Liebe Grüße,

Hauke

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hauke F. schrieb:
> Anscheinend ist es von der Größe des
> Anwenderprogramms abhängig.

Meinst Du jetzt wirklich die Größe des Programms oder die Größe der 
Hex-Datei?

> Hat Jemand eventuell eine Idee, wo in etwa der Fehler liegen könnte?

Zeig mal die Zeile 42 aus Deinem Bootloader.

von Klaus F. (kfalser)


Lesenswert?

Hauke F. schrieb:
> Hat Jemand eventuell eine Idee, wo in etwa der Fehler liegen könnte?

Warum liest Du nicht in beiden Fällen den Flashspeicher aus und 
vergleichst die Inhalte?

von Loocee L. (loocee)


Lesenswert?

Klaus Falser schrieb:
> Warum liest Du nicht in beiden Fällen den Flashspeicher aus und
> vergleichst die Inhalte?

Der Grund für einen Bootloader ist oft dass man sich keinen
Programmer leisten will. Dann kann man auch keinen Speicher
auslesen. Soweit ich so herumsehe schaffen es die Bootloader
nicht ein Flash auszulesen.

von npn (Gast)


Lesenswert?

Eberhard F. schrieb:
> Klaus Falser schrieb:
>> Warum liest Du nicht in beiden Fällen den Flashspeicher aus und
>> vergleichst die Inhalte?
>
> Der Grund für einen Bootloader ist oft dass man sich keinen
> Programmer leisten will. Dann kann man auch keinen Speicher
> auslesen. Soweit ich so herumsehe schaffen es die Bootloader
> nicht ein Flash auszulesen.

Und der Bootlader ist ganz von alleine vom PC auf den ATmega gehüpft und 
hat sich die Fuses selbst gestellt? ;-)

von Karl H. (kbuchegg)


Lesenswert?

Eberhard F. schrieb:
> Klaus Falser schrieb:
>> Warum liest Du nicht in beiden Fällen den Flashspeicher aus und
>> vergleichst die Inhalte?
>
> Der Grund für einen Bootloader ist oft dass man sich keinen
> Programmer leisten will.

Wer einen Bootloader entwickelt, hat auch einen Programmer. Denn wie 
kommt sonst der Bootloader in den Flash?

von Loocee L. (loocee)


Lesenswert?

Karl Heinz schrieb:
> Denn wie
> kommt sonst der Bootloader in den Flash?

Da isser zum Kumpel gegangen der ihm ausgeholfen hat...

von npn (Gast)


Lesenswert?

Eberhard F. schrieb:
> Karl Heinz schrieb:
>> Denn wie
>> kommt sonst der Bootloader in den Flash?
>
> Da isser zum Kumpel gegangen der ihm ausgeholfen hat...

Wenn er sowieso für jeden einzelnen µC zum Kumpel geht, um den 
Bootloader aufspielen zu lassen, dann kann der Kumpel doch auch mal den 
Flash auslesen. Was ist daran so kompliziert?

von Loocee L. (loocee)


Lesenswert?

npn schrieb:
> dann kann der Kumpel doch auch mal den
> Flash auslesen.

Ja, aber dann müsste er extra dafür wieder zum Kumpel gehen ;-)

von npn (Gast)


Lesenswert?

Eberhard F. schrieb:
> npn schrieb:
>> dann kann der Kumpel doch auch mal den
>> Flash auslesen.
>
> Ja, aber dann müsste er extra dafür wieder zum Kumpel gehen ;-)

Sport hält jung! :-)

von Hauke F. (axfire)



Lesenswert?

Oh das ging ja schnell mit den Antworten :)

Frank M. schrieb:
> Zeig mal die Zeile 42 aus Deinem Bootloader.

Welchen Teil meinst du denn konkret? Ich habe das Programm aus der 
Anleitung nicht 1 zu 1 übernommen. Wenn man Zeile 42 aus dem original 
Programm nimmt, steht da ja nur der Kommentar "/* Set up little-endian 
word. */" welcher in der Funktion "void program_page (uint32_t page, 
uint8_t *buf)" steht.

Frank M. schrieb:
> Meinst Du jetzt wirklich die Größe des Programms oder die Größe der
> Hex-Datei?

Ich meine die tatsächliche Größe des Mikrocontrollerprogramms, welche 
auch nach der Compelierung unter "Program Memory Usage" im AVR Studio in 
der Konsole angezeigt wird.

Klaus Falser schrieb:
> Warum liest Du nicht in beiden Fällen den Flashspeicher aus und
> vergleichst die Inhalte?

Gute Idee, hab ich vor lauter Fehlersuche noch garnicht dran gedacht. 
Und ja, einen Prommer hab ich auch ;)
Auf was sollte ich denn bei einem Vergleich genau achten?

Ich jetzt mal zwei Programme vom Atmel Studio und zwei Programme von 
Code::Blocks mit dem Bootloader auf den Controller gespielt und den 
Speicher wieder ausgelesen.

Auffällig ist, dass bei den eingelesenden fehlerhaften Programmen vom 
Atmel Studio in den ersten Zeilen als Nutzdaten nur 0xFF zu lesen ist.
Bei den fehlerhaften Programmen von Code::Blocks ist dies nicht der 
Fall...

Ich habe einmal die entsrechenden Hex-Files vom Einlesen als Anhang 
beigefügt.

Code::Blocks Programme:
"Read_Flash_LIN_Bridge_DS_4-Fehler.hex"  verursacht den besagten Fehler
"Read_Flash_LIN_Bridge_DS_4-OK.hex "     läuft wünschenswert

Atmel Studio Programme:
"Read_Flash_Hauptprogramm_18944_bytes_-_Fehler.hex"  verursacht den 
besagten Fehler

"Read_Flash_Hauptprogramm_18942_bytes_-_Ok.hex"      läuft wünschenswert

"Hauptprogramm_18944_bytes_-_Fehler.hex"             habe ich 
ausversehen hinzugefügt ;) ist das Hex-File aus dem Atem-Studio

von Walter (Gast)


Lesenswert?

Hauke F. schrieb:
> Auf was sollte ich denn bei einem Vergleich genau achten?

na ob sie gleich sind!
Wenn nicht was der Unterschied ist

von Hauke F. (axfire)


Lesenswert?

Walter schrieb:
> na ob sie gleich sind!
> Wenn nicht was der Unterschied ist

So ich habe nun einmal diverse Tests durchgeführt.

Ich habe die Hex-Files, bei denen der besagte Fehler auftritt, mit 
meinen Programmer in den Controller geflasht und den Speicher wieder 
ausgelesen. Und ich habe sie mit dem Bootloader in den Controller 
gespielt, und danach mit dem Prommer den Speicher ausgelesen.
Die beiden gewonnenden Hex-Files habe ich gegenüber gestellt und nach 
unterschieden gesucht. Dabei ist mir folgendes aufgefallen:

Mit Prommer geflasht und ausgelesen:

:100000000C943E230C945B230C945B230C945B2395
:100010000C945B230C945B230C945B230C945B2368
:100020000C945B230C945B230C945B230C945B2358
:100030000C945B230C945B230C945B230C945B2348
:100040000C945B230C945B230C945B230C945B2338
:100050000C94E0230C940E240C945B230C945B23EF
:100060000C945B230C945B230C945B230C945B2318
:100070000C948B240C94B9240C945B230000000096
:10008000000000000000000303030303030000005E
:10009000000000000000000303030303030000004E
:1000A000000000000000000303030303030000003E
:1000B0000000000000000003030303030303030325
:1000C0000303030303030303030303030303030201
:1000D000010000000000000000000000000000001F
:1000E0000000000000000000000000000000000010
:1000F0000000000000000000000000000000000000
:1001000000000000000000000000000000000000EF
:1001100000000000000708090A02020000FFFF00BB
:1001200000807F00000000000000000000000000D0
...

Mit Bootloader geflasht und mit Prommer ausgelesen:

:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:1001000000000000000000000000000000000000EF
:1001100000000000000708090A02020000FFFF00BB
:1001200000807F00000000000000000000000000D0
...

Der Bootloader hat also ab Adresse 0x0000 bis 0x0100 die Nutzdaten 
falsch in den Flash gespielt. Dies entspricht eine Page des 
Flashspeichers.

Mir ist jedoch schleierhaft, wieso dieser Fehler auftritt.
In meinem Bootloader werden, wie auch im Original der Anleitung, die 
Nutzdaten in "flash_data" zwischen gespeichert, bis genug Daten 
gesammelt wurden, um eine Page des Flashspeichers zu schreiben. Danach 
werden mittels der Funktion "void program_page(uint32_t page, uint8_t 
*buf)" die Nutzdaten aus "flash_data" geschrieben.

Unmittelbar vor dem Aufruf von "program_page" habe ich zu Testzwecken 
den Inhalt von "flash_data" über die Schnittstelle ausgegeben. Zu meiner 
Verwunderung stimmte dieser, also keine "FF" sondern die gewünschten 
Daten. Nun frage ich mich, "wer" mir nun die "FF" in die erste Page des 
Flashspeichers haut.
"program_page" etwa? "program_page" habe ich jedoch 1 zu 1 übernommen 
und sollte doch daher fehlerfrei laufen, oder? Einen Adressierungsfehler 
habe ich nach meiner Überprüfung ausgeschlossen...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wir sollen jetzt also einen Fehler in einem Quellcode suchen, den wir 
nicht sehen können, weil Du ihn nicht zeigen magst?

Was soll das werden? Blinde Kuh? Man kann keine Programmierfehler in 
einem Code finden, den der andere in Gedichtsform vorträgt. ;-)

Hauke F. schrieb:
> Frank M. schrieb:
>> Zeig mal die Zeile 42 aus Deinem Bootloader.
>
> Welchen Teil meinst du denn konkret?

Du hast mich absolut missverstanden. Nicht nur Zeile 42 ist interessant, 
sondern auch 1 bis 41 und 43-99999. Ich dachte, der Wink mit dem 
Zaunpfahl würde sitzen. Aber anscheinend hat er noch nichtmals eine 
Beule zurückgelassen...

von Karl H. (kbuchegg)


Lesenswert?

Es wäre nett gewesen, wenn du einen Link zum Artikel gesetzt hättest, 
aus dem du die Funktionen hast. Dann müsste man nicht suchen.

Dort wird auch
   boot_page_erase
aufgerufen. Und diese Aufrufe würde ich mir mal ansehen, ob dort die 
Page Nummern korrekt sind.

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.