Hallo miteinander,
Ich habe mir einen Bootloader (UART) für die Tinys und Megas
geschrieben. Der funktioniert auch soweit gut; jedoch habe ich eine
Sache nicht berücksichtigt: Die Lines aus der Hex/EEP müssen alle gleich
lang sein. Ich habe gedacht, dass die boot Funktionen (mit page
fill/write) das selbsttändig erledigen - aber nein. Wenn ich nun eine
File sende, wo mal kurze und lange Einträge vorhanden sind kommt im
Programm quark raus.
Einheitlich genormt auf eine Länge funktioniert es wunderbar. Habe zwar
ein Programm gefunden, welches das "umwandelt", aber leider nicht den
Quellcode dazu. Mein Terminal läuft in VisualBasic - also dort müsste
dann das Parsen passieren. Dieses Terminal verbindet sich auch via
Serielle-Schnittstelle mit dem Controller. Das wandelt für die EEP habe
ich hinbekommen (einfach den Rest mit FF aufgefüllt und die Checksumme
angepasst). Das geht aber bei den Hex-Lines nicht. Die Checksumme
bekomme ich berechnet, und ich weiß auch das man die Daten vom nächsten
String "einfach" anhängt, aber wie verhalten sich dabei die Adresse?
Klappt das auch so dann noch bei 256kb AVRs?
Ich hoffe, jmd. kann mir helfen - ich würde es lieber in meinem Terminal
(VB) machen, da der Bootloader mit knapp 2kb an der Grenze liegt (gerade
bei den Tinys).
Dann machst du aber etwas grundlegend falsch beim Einlesen der Datei.
Hier
1
:1000000014C026C025C024C023C022C021C020C0E7
2
**
steht die Länge der Daten in Bytes. Brauchst du nur lesen und auswerten
bzw. im Programm berücksichtigen. Wenn du natürlich in deinen Programmen
(Bootloader) davon ausgehst, dass das immer 16 Bytes wären, dann musst
du eben mal ein wenig universeller und mit weniger Annahmen
programmieren.
Ach Karlheinz,
Das klappt nicht wirklich, denn der TO wird vermutlich kaum den Linker
oder Locator dazu überreden können, Zeilen fester Länge zu produzieren.
Das ginge ja nur, wenn der erzeugte Code auch tatsächlich in solchen
Stücken anfällt - und das tut er in aller Regel NICHT. Ihn dann
aufzufüllen, wäre Mumpitz, denn da würde man ja Speicherstellen aud
irgendwas festlegen, die garnicht Inhalt des MC sind.
Das einzige, was der TO tun kann ist, seinen Bootlader den Regeln des
Hex-Fileformates anzupassen - oder sich sein eigenes Format zu kreieren.
Für die ganz kleinen PIC's gibt es sowas, da braucht der Bootlader nur
exakt 100 Befehle und er läuft nur mit einem passenden Programm auf dem
PC. Aber das dürfte ja sowieso nötig sein, denn zum Brennen eines
längeren Programms brauct es nen Handshake zwischen PC und µC, weil das
eigentliche Programmieren je nach Alter des Flashes im µC
unterschiedlich lange brauchen kann.
W.S.
- Im Terminalprogramm ein "binäres" Feld mit der Größe des Bootladers
definieren und mit 0xff oder einer anderen genehmen Konstante füllen.
- Das Hexfile in dieses Feld einlesen.
- Die Daten des Feldes wieder in Hex mit konstanter Rekordlänge wandeln
und programmieren.
Alles andere geht auf Grund der Seitenstruktur des AVR Programmspeichers
nur sehr mühsam. In einem Hexfile müssen nämlich nicht die Rekords mit
den Adressen aufeinander folgend abgelegt sein.
Unmögliches wird sofort erledigt, Wunder dauern etwas länger.
In Anbetracht der Tatsache, dass spätestens die letzte Zeile ihre
"eigene" Anzahl an Bytes enthält, sollte es egal sein, wenn noch ein
paar gute "Bekannte" dabei sind.
Hallo Marius,
Marius Dege schrieb:> Die Checksumme> bekomme ich berechnet, und ich weiß auch das man die Daten vom nächsten> String "einfach" anhängt, aber wie verhalten sich dabei die Adresse?
So wie du es in "Gewandelte.txt" gemacht hast wäre es richtig.
Aber: In einer hex-Datei können auch Lücken entstehen, z.B. wenn man die
sections explizit positioniert. Das Format lässt sogar zu, dass
Fragmente in beliebiger Reihenfolge auftauchen oder Speicher sogar
zweimal geschrieben wird - das wird in der Praxis aber wohl eher nicht
auftauchen.
Also entweder so wie von Georg vorgeschlagen den Flash-Speicher im
Terminalprogramm nachbilden, die hex-Datei komplett einlesen, und dann
den Speicher wieder als hex-Datei rausschreiben.
Oder aber, besser, wie von Karl-Heinz empfohlen den Bootloader so
erweitern dass er beiebige Längenbytes und Adressen verarbeiten kann und
Fragmente sauber in den seitenweisen Flash programmiert.
Marius Dege schrieb:> Klappt das auch so dann noch bei 256kb AVRs?
Bei denen enthält die hex-Datei immer nach 64kB Typ 02 Einträge. Siehe
http://de.wikipedia.org/wiki/Intel_HEX.
LG, Sebastian
Sebastian Wangnick schrieb:> Oder aber, besser, wie von Karl-Heinz empfohlen den Bootloader so> erweitern dass er beiebige Längenbytes und Adressen verarbeiten kann und> Fragmente sauber in den seitenweisen Flash programmiert.
Na ja. Ob das 'besser' ist, lass ich mal dahin gestellt. Besser ist es
sicherlich im allgemeinen Fall nicht, weil ja, wie du richtig sagst, im
Prinzip es keine Garantie gibt, dass die Records in aufeinanderfolgende
Adressen zu liegen kommen.
Aber: Im speziellen Fall hat man es meistens nicht mit dem allgemeinen
Fall zu tun. Man kennt seine Tools und wie sie das Hex-File generieren
und das ändert sich normalerweise nicht. Solange man damit leben kann,
einen kleineren Subset von Hex-Files per Bootloader zum AVR zu
übertragen, müsste das eigentlich möglich sein (Ohne jetzt den Aufbau
seines Bootloaders zu kennen), den soweit zu pimpen, dass er wenigstens
mit unterschiedlichen Längen im Data-Record klar kommt.
Frickellösung ist es - zweifellos. Ob sie akzeptabel ist, dass muss der
TO entscheiden. Zumal auch das Erstellen eines übertragbaren Files (muss
ja kein HEx-File sein) aus einem Hex-File auf dem PC für einen
Programmierer keine große Herausforderung ist. Georg G. hat ja schon
angesprochen wie man das macht: Speicher bereitstellen und dann einfach
das Hex-File Zeile für Zeile lesen und das was man dort vorfindet als
Befehl auffassend auf diesen Speicher anwenden. Zum Schluss hat man ein
'Speicherimage' aus dem man sich dann das zu übertragende File
generiert, egal welches Format dieses dann hat.
Hallo Jungs,
ich habe keine Mails bekommen, dass jmd. geantwortet hat, deswegen kommt
jetzt erst meine Antwort. Dachte schon, es würde niemand schreiben.
Mein Bootloader ist recht einfach aufgebaut:
Ich sende immer eine ganze Zeile/Line der Hex-File welche ich im
VB-Terminal einzeln zerlege (damit ich auch Processbar usw. verwenden
kann).
Die gesendete Line wird dann im BL zu HEX convertiert und es wird dort
Checksum, Data, Rekord, Adresse gebildet. Damit hat man erstmal alles um
via boot_fill_page eine Seite zu füllen. Danach wird dann (wenn die
Seite voll ist), diese geschrieben. Blöd nur oben genanntes Problem. Wie
kann der BL denn mit unterschiedlichen Längen klar kommen - ich stehe
da echt auf dem Schlauch, wie man das dann auf eine Länge zusammenführen
kann.
Ich habe leider z.Zt. keine Ahnung wie ich das Problem im Bootloader
oder im Terminal (Terminal wäre mir lieber, BL würde aber auch gehen
wenn es einfacher ist) lösen kann, weil ich nicht so wirklich weiß, wie
dieses Programm die "Gewandelte.txt" erstellt hat (außer das die Daten
von der nächsten Line an die vorherige angehängt werden, und dann die
Checksum neu berechnet wird; Datenlänge wird natürlich auch angepasst).
Aber wie das tolle Programm da die Adressen berechnet - ?!
Wie Sebastian Wangnick bereits gesagt hat: Die Adressen können in
beliebiger Reihenfolge auftauchen, das tuen Sie dort auch, und deswegen
bin ich dort mit der Adressenberechnung nicht durchgestiegen. Hast du
evtl. eine Ahnung wie das "Gewandelte.txt" entstanden ist?!
Ich kann euch gerne auch den Bootloader hochladen wenn gewünscht.
Karl Heinz schrieb:> Dann machst du aber etwas grundlegend falsch beim Einlesen der Datei.> Hier>
1
> :1000000014C026C025C024C023C022C021C020C0E7
2
> **
3
>
> steht die Länge der Daten in Bytes. Brauchst du nur lesen und auswerten> bzw. im Programm berücksichtigen. Wenn du natürlich in deinen Programmen> (Bootloader) davon ausgehst, dass das immer 16 Bytes wären, dann musst> du eben mal ein wenig universeller und mit weniger Annahmen> programmieren.
Ich versuche eigentlich universell zu programmieren - hier hat es mich
voll erwischt; habe ich ehrlich gesagt auch gar nicht dran gedacht an
sowas.
Weißt du denn, wie der BL auch mit unterschiedlich langen Lines klar
kommen kann, bzw wie er diese handhabt?
>> steht die Länge der Daten in Bytes. Brauchst du nur lesen und auswerten>> bzw. im Programm berücksichtigen. Wenn du natürlich in deinen Programmen>> (Bootloader) davon ausgehst, dass das immer 16 Bytes wären, dann musst>> du eben mal ein wenig universeller und mit weniger Annahmen>> programmieren.>>> Ich versuche eigentlich universell zu programmieren - hier hat es mich> voll erwischt; habe ich ehrlich gesagt auch gar nicht dran gedacht an> sowas.> Weißt du denn, wie der BL auch mit unterschiedlich langen Lines klar> kommen kann, bzw wie er diese handhabt?
?
Du schickst doch, wenn ich das richtig verstanden habe, die Zeile so wie
sie ist zum Bootloader. Oder nicht.
Der holt sich aus den ersten beiden Zeichen nach dem ':' die Anzahl der
Datenbytes raus und weiß daher, was und wieviel nach der
Datensatzkennung kommen muss. Wo ist da jetzt das große Problem?
Marius Dege schrieb:> wenn es einfacher ist) lösen kann, weil ich nicht so wirklich weiß, wie> dieses Programm die "Gewandelte.txt" erstellt hat (außer das die Daten> von der nächsten Line an die vorherige angehängt werden, und dann die> Checksum neu berechnet wird; Datenlänge wird natürlich auch angepasst).
Man kann das natürlich so machen, wenn man davon ausgeht, dass die
Datenbytes grundsätzlich aufsteigend im Speicher angeordnet sind.
> Aber wie das tolle Programm da die Adressen berechnet - ?!
Na komm.
Das kannst du selbst auf Papier auch.
Wenn du eine Startadresse von 10 hast, ich dir 7 Datenbytes gebe, danach
9 und dann nochmal 4, an welche Adresse kommt dann das nächste Byte?
> bin ich dort mit der Adressenberechnung nicht durchgestiegen. Hast du> evtl. eine Ahnung wie das "Gewandelte.txt" entstanden ist?!
Höchst wahrscheinlich (zumindest würde ich das so machen), genau so wie
das beschrieben wurde:
Datenrecord vom original lesen. Den dadurch codierten 'Befehl' (schreibe
8 Datenbytes beginnend ab Adresse xyz) in einem Array ausführen und wenn
das File komplett gelesen wurde, dann schreib ich ein neues File
basierend auf dem was ich an Daten im Array vorfinde.
Das ist nicht wirklich schwer. Das sollte eigentlich jeder
C-Programmierer in längstens 2 Stunden hinkriegen. Zumal das File-Format
eines HEX-Files nicht sehr komplex ist.
Hallo Marius,
Marius Dege schrieb:> Mein Bootloader ist recht einfach aufgebaut: [...]> Die gesendete Line wird dann im BL zu HEX convertiert und es wird dort> Checksum, Data, Rekord, Adresse gebildet. Damit hat man erstmal alles um> via boot_fill_page eine Seite zu füllen. [...]> Ich kann euch gerne auch den Bootloader hochladen wenn gewünscht.
Tu das mal. Ich versteh nämlich nicht mehr was du nicht verstehst :)
LG, Sebastian
PS: Ich bastele gerade an einem Internet-Bootloader (für mein Board mit
Atmega1284P und W5500) und benutze dabei auch das hex-Format. Ich lade
keine ganzen Zeilen sondern liefere alle einlaufenden Zeichen in einen
hex-Zustandsautomaten, und von dort die Adressen und Datenbytes in einen
Flash-Zustandsautomaten. Ich bin allerdings schon bei >4K UND es fehlt
noch DHCP ...
LG, Sebastian
Sebastian Wangnick schrieb:> Marius Dege schrieb:>> Mein Bootloader ist recht einfach aufgebaut: [...]>> Die gesendete Line wird dann im BL zu HEX convertiert und es wird dort>> Checksum, Data, Rekord, Adresse gebildet. Damit hat man erstmal alles um>> via boot_fill_page eine Seite zu füllen. [...]>> Ich kann euch gerne auch den Bootloader hochladen wenn gewünscht.>> Tu das mal. Ich versteh nämlich nicht mehr was du nicht verstehst :)
Willst du mit mir eine Wette eingehen, was das EIGENTLICHE Problem ist
:-)
Das Primitivste wäre wohl ein kleines Batchfile, das das Hexfile
aufbereitet.
hexbin %1.hex %1.bin
binhex %1.bin %1.neu 0
Tunixe können das auch per Pipe zu einer Zeile zusammenfassen.
Quältexte für hexbin und binhex gibt es auf Anfrage auch (einmal
Turbopascal, einmal C).
Mit Längen- und Adressauswertung im Controller kannst du das Hexfile
auch mit Hyperterminal oder sonstwas rüberschaufeln. Hauptsache der
Knabe versteht XON/XOFF und müllt den Controller während er ins Flash
brennt nicht zu.
mfg.
Hi,
ich habe das für meinen ersten Bootloader (PIC24) alles am PC gemacht.
Der PC wertet den Record aus, konvertiert das in Binärdaten und sendet
das an den µC, mit den richtigen Adressen. Der Bootloader muss das nur
ins Flash pinseln.
Die Idee ist, dass der PC mit seinen schnellen Prozessor und großen
Speicher die ganze Arbeit machen soll. Hat sich bewährt, weil man am PC
besser debuggen kann und der Bootloader sehr dumm sein darf. Können muss
er:
- sicher kommunizieren (bei mir über Funk mit CRC)
- Flash löschen
- Flash schreiben / lesen
- seine Version ausspucken
- die Applikation starten
Der Wikipedia-Artikel ist brauchbar:
http://de.wikipedia.org/wiki/Intel_HEX
Implementieren muss man nur die paar nrecord-typen die im
Programmierfile vorkommen. Ich kann es wirklich empfehlen das selber zu
machen, mir hats viel Spass gemacht.
Anbei eine kleine Funktion zum decodieren. Ob es ohne Dokumentation
hilft, weiß ich nicht. Sie dekodiert nur einen Record, nachfüttern
(Pointer setzen) und Daten laden muss man selber.
> Na komm.> Das kannst du selbst auf Papier auch.>> Wenn du eine Startadresse von 10 hast, ich dir 7 Datenbytes gebe, danach> 9 und dann nochmal 4, an welche Adresse kommt dann das nächste Byte?> Das ist nicht wirklich schwer. Das sollte eigentlich jeder> C-Programmierer in längstens 2 Stunden hinkriegen. Zumal das File-Format> eines HEX-Files nicht sehr komplex ist.
Warte mal: Ich starte bei Adresse 000, dann bekomme ich 8 Datenbytes ==>
die nächste Adresse für die nächste Line ist dann 008? Das jetzt nicht
dein ernst das das so einfach ist, oder? Wenn das so ist, war ich wohl
irgendwie blind - dann ist das ja einfach mit der Adressmittelung.
Sebastian Wangnick schrieb:> PS: Ich bastele gerade an einem Internet-Bootloader (für mein Board mit> Atmega1284P und W5500) und benutze dabei auch das hex-Format. Ich lade> keine ganzen Zeilen sondern liefere alle einlaufenden Zeichen in einen> hex-Zustandsautomaten, und von dort die Adressen und Datenbytes in einen> Flash-Zustandsautomaten. Ich bin allerdings schon bei >4K UND es fehlt> noch DHCP ...>> LG, Sebastian
Das hört sich krass an - leider ist keiner meiner Controller am Netz.
Aber ich benötige noch einen Bootloader, der (sofern es nicht seine
Firmware ist), die Daten via I²C an einen weiteren Controller schickt,
welcher kein Bluetooth hat. Das wird auch noch interessant - aber ich
kann dort auch nur bis 4k gehen (ATMega1284P). Dort wollte ich den alten
erweitern.
Karl Heinz schrieb:> Sebastian Wangnick schrieb:>>> Marius Dege schrieb:>>> Mein Bootloader ist recht einfach aufgebaut: [...]>>> Die gesendete Line wird dann im BL zu HEX convertiert und es wird dort>>> Checksum, Data, Rekord, Adresse gebildet. Damit hat man erstmal alles um>>> via boot_fill_page eine Seite zu füllen. [...]>>> Ich kann euch gerne auch den Bootloader hochladen wenn gewünscht.>>>> Tu das mal. Ich versteh nämlich nicht mehr was du nicht verstehst :)>> Willst du mit mir eine Wette eingehen, was das EIGENTLICHE Problem ist> :-)
Was ist denn das eigentliche Problem - Ich kann es euch aber gerne
sagen:
Ich habe den Adressaufbau beim .hex nicht wirklich verstanden. Aber
jetzt ist es klar. Aktuelle Adresse + Datenbytes = Nächste Adresse.
Danke für den Denkanstoß.
Marius Dege schrieb:> Warte mal: Ich starte bei Adresse 000, dann bekomme ich 8 Datenbytes ==>> die nächste Adresse für die nächste Line ist dann 008?Marius Dege schrieb:> Ich habe den Adressaufbau beim .hex nicht wirklich verstanden. Aber> jetzt ist es klar. Aktuelle Adresse + Datenbytes = Nächste Adresse.
Nicht ganz. Die Adresse der nächsten Zeile steht immer in dem Header
der Zeile.
Nehmen wir mal eine Ausschnitt aus Normale.txt und streuen Leerzeichen
und Zeilennummern ein:
len addr typ data cksum
Z1 : 10 00B0 00 E1F700C00000D9DF882389F3CE35D105 F0
Z2 : 10 00C0 00 31F4E0916000F09161000995E8CF83E8 98
Z3 : 0A 00D0 00 90E0D4DFE4CFF894FFCF F6
Z4 : 10 00DA 00 B004256900252E32660048616C6C6F2C CD
Z5 : 10 00EA 00 20776965206765687420657320646972 82
typ ist bei allen reinen Datenzeilen 00.
len gibt die Anzahl der Datenbytes in data. Oft ist len=0x10, also 16
Bytes an Daten.
addr gibt die Adresse des ersten Datenbytes.
data sind die Datenbytes. Das erste Datenbyte kommt an Adresse addr, das
zweite and addr+1, das dritte an addr+2 und so weiter. Das letzte, also
sozusagen das len'te, kommt an addr+len-1.
Nur wenn ein grösserer zusammenhängender Datenbereich hex-kodiert ist
(was aber fast immer der Fall ist), folgt in der nächsten Zeile dann
addr(Z2) = addr(Z1)+len(Z1).
In deinem Fall gilt dass auch für den Übergang von Z3 auf Z4. Z3 beginnt
bei 0x00D0 und ist 0x0A lang. Z4 beginnt dann bei 0x00DA.
Jetzt wird dir wohl auch klar, wie Gewandelte.txt entstanden ist. Die
Datenbytes von 0xDA-0xDF aus Z4, also 0xB00425690025, wurden an die
Datenbytes aus Z3 angehängt, um die Länge auf 16 zu erweitern. Die
restlichen Datenbytes (0x2E32660048616C6C6F2C) beginnen eine neue Zeile
mit Adresse 0x00E0, an die dann wieder Datenbytes aus Z5 angehängt
werden um die Länge auf 16 zu bringen, und so weiter.
Du fragst dich vielleicht: Warum aber ist in Normale.txt dieser blöde
Bruch bei Z3. Das hat mit den Loader-Segmenten zu tun. Alles bis Z3
inklusive gehört zum .text-Segment, alles ab Z4 gehört (glaube ich) zum
.bss-Segment (also zu den im Flash gespeicherten Daten die benötigt
werden, vor dem Programmstart die Variablen im SRAM zu initialisieren).
Wenn du das genau wissen willst, brauchst du die zur hex-Datei gehörende
elf-Datei. Die kannst du mit avr-objdump -h -S dekodieren und dir die
vom Loader generierten Segmente anschauen.
Bei uC mit >64kB Flash gibt es dann noch, wie oben erwähnt, die typ 02
Zeilen. Dabei ist len 02, addr 0000, typ 02, und es gibt zwei Bytes
data. Das unterste Nibble ist immer 0, siehe Wikipedia. data wird um ein
Nibble linksgeshiftet und fortan noch zu addr dazugerechnet.
Also, wenn die folgende Zeile erscheint,
1
:020000021000EC
dann wird data (0x1000) um ein Nibble linksgeshiftet (=0x10000), und
danach immer zu addr hinzugerechnet. Also aus addr 0x0010 in irgend
einer Folgezeile wird dann tatsächlich die Flash-Adresse 0x10010.
LG, Sebastian