Forum: Mikrocontroller und Digitale Elektronik Bootloader -> Verständnisproblem Intel-Hexfile


von Alexander H. (ill_son)


Lesenswert?

Hallo,

ich bin gerade dabei, für ein Projekt den Atmel-Boatloader mit einer 
eigenen Software zu versehen, da mir die Consolenanwendung nicht 
ausreicht.

Link:
www.atmel.com/images/Atmel-8242-XMEGA-Boot-Loader-Quick-Start-Guide_Appl 
icationNote_AVR1605.pdf

Beim Erzeugen der zu schreibeneden Blöcke für die einzelnen Flash-Pages 
aus dem Hex-File habe ich noch ein Verständnisproblem.

1. Mir ist aufgefallen, dass in einem Hex-File auch zwischendrin ein 
Record Typ 0 mit ener Länge < 16 auftauchen kann. Wie wie behandelt man 
den? Schreibt man die Flash-Page mit dem nächsten Record weiter, sodass 
es dann Überschneidungen zwischen Records und Flash-Pages gibt oder 
schließt man die Page ab und fängt die neue mit dem nächsten Record an?

2. Berechnet man grundsätzlich die Adresse der zu schreibenden Page aus 
der Adresse des Records, gegebenenfalls auch unter Berücksichtigung 
eines Records vom Typ 2 im Hex-File oder kann man die Page-Adresse 
einfach hochzählen? Im hier verwendeten Bootloader ist die Page-Adresse 
immer der halbe Wert des ersten Records in der Page aber eben auch 
fortlaufend, zumindest soweit ich das mit dem Portsniffer analysieren 
konnte.


Grüße, Alex

von Thomas E. (thomase)


Lesenswert?

Maßgebend ist immer die Adresse des Records. Daraus werden die Page und 
die Adresse innerhalb der Page errechnet.

Normalerweise werden die Records fortlaufend angelegt, sodaß man einfach 
nur durchzählen muß. Das ist aber keine Bedingung. Die Records können 
auch wild gemischt sein.

Das einfachste ist es, das Hexfile zuerst komplett in ein Array zu 
entpacken. Daraus kann dann fortlaufend auf den Controller gesendet 
werden. Egal, wie lang das Hexfile ist, wird es einen PC vor keine 
Probleme stellen.

: Bearbeitet durch User
von Alexander H. (ill_son)


Lesenswert?

Hallo Thomas,

danke für deine Antwort. Was mache ich denn mit dem halbvollen Record 
zwischen drin?

von Thomas E. (thomase)


Lesenswert?

Alexander H. schrieb:
> danke für deine Antwort. Was mache ich denn mit dem halbvollen Record
> zwischen drin?

Ich hatte noch etwas zu meinem Beitrag ergänzt.

Du legst auf dem PC ein Array an, das schreibst du mit FFs voll. Dann 
packst du die Records nach und nach da rein. Der Arrayindex errechnet 
sich aus der Adresse im Record. Wenn der nur 13 Bytes lang ist, dann 
stehen im Array an den Adressen 13-15 weiterhin FFs drin. Das ist genau 
das, was der Controller braucht, wenn kein weiterer Record da etwas 
reingeschrieben haben möchte.

: Bearbeitet durch User
von Alexander H. (ill_son)


Lesenswert?

Ich muss dazusagen, dass der Bootloader, der auf dem uC läuft, der von 
Atmel ist (siehe Link oben) und der möchte die Daten schön vorgekaut 
bekommen, sodass ich die Datenblöcke für die Pages schon im PC erzeugen 
muss um diese dann, einem bestimmten Protokoll folgend, an den 
Controller zu senden. Wie gesagt, habe ich festgestellt, dass mitten im 
Hexfile ein kleiner Record vom Typ 0 aufgetaucht ist, allerding in der 
Originalsoftware von Atmel weiter volle Blöcke erzeugt wurden und erst 
am Ende der Block für die letzte Page nicht voll war. Controller ist 
übrigens ein ATxmega128A1.

von Cyblord -. (cyblord)


Lesenswert?

Warum eigentlich das Rad neu erfinden? hex2bin.exe macht genau das.

von Alexander H. (ill_son)


Lesenswert?

Cyblord -. schrieb:
> Warum eigentlich das Rad neu erfinden? hex2bin.exe macht genau das.

Weil ich den Bootloader zum Gerät gern in die dazugehörige Software 
integrieren möchte. Mal davon abgesehen, würde ich gern verstehen, wie's 
geht.

Allerdings muss ich gestehen, dass ich hex2bin noch nicht kannte, werd 
mir das mal anschauen.

Thomas E. schrieb:
> Der Arrayindex errechnet
> sich aus der Adresse im Record

Ich glaube, bei der Berechnungsvorschrift bräuchte ich mal den 
entscheidenden Hinweis.

: Bearbeitet durch User
von Manfred K. (mkch)


Angehängte Dateien:

Lesenswert?

Hallo,
Intel Hex-Format siehe Anlage.
Das haben wir bereits 1986 zum Programmieren unserer E-Proms benutzt. 
Weil die Hex-Datei eine reine ASC-Datei ist, kann man sie auch mit jedem 
Text-Editor öffnen.
Viele Grüße
Manfred

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Alexander H. schrieb:
> Ich glaube, bei der Berechnungsvorschrift bräuchte ich mal den
> entscheidenden Hinweis.
1
MARK  LEN  OFFSET  TYP   DATA  ChkSum
2
:      02   0000    00   17C0   27
3
...
4
...
5
:      10   002C    00   09...  D6
6
:      10   003C    00   0E...  3F
7
...
8
...
9
:      10   064C    00   E0...  06
10
:      02   065C    00   0895   FF
11
:      00   0000    01          FF

 Wenn die zu berechnende Zeile links anfängt [mit Offset 0], dann ist:
 Länge   = Zeile{1..2]
 Adresse = Zeile[3..6]
 Typ     = Zeile[7..8]              // 00 = Data / 01 = EOF
 Data    = Zeile[9..len(Zeile)-11]
 Chksum  = die letzten 2 Zeichen

 Man legt sich ein Array an, z.B. FlashArr[DeviceFlashSize] und füllt
 es mit 0xFF.
 Aus der aktuellen Zeile nimmst du die OffsetAdresse und Länge.
 Dann einfach in einem for..next loop die Daten lesen und in
 FlashArr[OffsetAdr+loopcnt] reinschreiben.

 Auf diese Weise werden nur die tatsächlich geänderten Bytes rein-
 geschrieben, egal wie die Adressen in HexFile stehen und ob Lücken
 da sind.

 Allerdings prüfe ich bei meinem Bootloader vor dem flashen ob
 mindestens ein Byte in der FlashPage <> 0xFF ist.
 Wenn das nicht der Fall ist, überspringe ich die Page einfach.

von Alexander H. (ill_son)


Lesenswert?

Prima, danke für die Posts und hilfreichen Links. Grundsätzlich habe ich 
das verstanden. Was mich verwirrt hat, war, dass trotz des kurzen 
Records Typ 0 kein Block mit lauter 0xFF aufgetaucht ist, sondern es für 
mich den Anschein hat, als würden alle weiteren Blocks nach vorn gerückt 
im Speicher. Im Artikel:

https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung

hat der Autor auch ein flash_page_flag eingeführt, mit dem signalisiert 
wird, ob eine neuer page beginnt und die Adresse wird irgendwie über 
eine Art Division mit Rest bestimmt.
1
if(flash_page_flag) 
2
{
3
  flash_page = hex_addr - hex_addr % SPM_PAGESIZE;
4
  flash_page_flag = 0;
5
}

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Alexander H. schrieb:
> Was mache ich denn mit dem halbvollen Record
> zwischen drin?

Es gibt keine halbvollen Records. Punkt.
Es gibt allerdings Datenblöcke unterschiedlicher Länge. Aber da man ja 
weiß, an welche Stelle des Ziel-Adressraumes die darin enthaltenen Daten 
gehören, ist es doch ein Leichtes, die Daten eben dorthin zu schreiben - 
oder?

Der Rest ist Geschmackssache. Traditionell wird der Puffer für die Daten 
zuvor mit FF gefüllt, weil das eben der Zustand ist, in dem sich ein 
frisch gelöschter EPROM befindet bzw. befand (als es noch EPROM's gab). 
Bei manchen Systemen hatte man man den Puffer zuvor mit 0 oder 90h oder 
C3h gefüllt, aber das scheint mir Schnee von vorgestern zu sein.

W.S.

von Alexander H. (ill_son)


Lesenswert?

Hallo,

ich habe den Weg mit der Flashmap als Array verfolgt und es 
funktioniert.
Vielen Dank nochmal für die viele hilfreichen Hinweise und Erklärungen.

Grüße, Alex

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.