Hallo,
ich habe eine Frage zum Flash-Speicher.
Das Problem ist folgendes: Ich will den Flash-Speicher bei jedem
Einschalten Überprüfen (ob auch noch jedes Byte so ist wie es sein
soll). Dafür habe ich eine CRC-Funktion geschrieben die auch gut
funktioniert. Die berechnete Checksumme kann ich mir über RS232 auf
Anfrage ausgeben lassen, geht alles prima.
Parallel dazu hab ich ein Konsolen-Programm in C++ das den CRC über das
HEX-File berechnet. Geht auch super. Nun ist es aber so, dass das
HEX-File vom GCC dort endet, wo auch die Daten enden ... am Ende sieht
es z.B. so aus:
1
:1035C0000895F999FECF92BD81BDF89A992780B5EB
2
:1035D0000895262FF999FECF1FBA92BD81BD20BD57
3
:1035E0000FB6F894FA9AF99A0FBE01960895F894D6
4
:0235F000FFCF0B
5
:0635F200FFFFFF010000D5
6
:00000001F
Das Program im Flash geht hinterher noch weiter mit diversen FFFF... :
1
:1035C0000895F999FECF92BD81BDF89A992780B5EB
2
:1035D0000895262FF999FECF1FBA92BD81BD20BD57
3
:1035E0000FB6F894FA9AF99A0FBE01960895F894D6
4
:1035F000FFCFFFFFFF010000FFFFFFFFFFFFFFFF07
5
:10360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
6
:10361000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
^ so liest es sich aus wenn ich das Flash in eine Datei lese.
Ich hoffe soweit stimmt das alles.
Mein Problem ist nun, das ich dem CRC der im ATmega168 läuft beibringen
muss, an welcher Stelle er aufhören muss zu berechnen damit der gleiche
CRC wie aus dem HEX-File mit meinem Konsolenprogramm berechnet wird.
Oder ich muss dem GCC beibringen, die HEX-Files mit FFFF... aufzufüllen.
Gibt es ein ENDE-Zeichen das sowohl im HEX-File als auch im
Flash-Speicher steht, so dass ich beide CRC-Berechnungen anhand dessen
synchronisieren kann ?
PS: Wenn ich 2 aufeinander folgende FFs im Flash als ENDE hernehme kommt
bei beiden Berechnungen (im Atmel und im Konsolenprogramm über das
HEX-File) die gleiche Checksumme raus. Aber FFFF ist doch sicher kein
ENDE-Zeichen (?) und hier nur zufällig richtig ?
Es gibt nichts, was das Ende des Flash kennzeichnet. Nicht mal die FF
kannst Du als Ende nehmen, denn es kann ja sein, dass am Ende des
initialisierten Datenbereichs FFs stehen.
Die beste Möglichkeit wäre, dem PC-Programm das Flashende beizubringen.
Es steht z.B. nach dem Compilieren in der Linker-Map. Es ist nicht mal
nötig, das dort nachzusehen, denn es reicht aus, das aus dem Elf- oder
Hex-File, das zum Programmieren verwendet wurde, zu ermitteln.
Um ... ich sehe gerade, Du rechnest den CRC über das Hex-File und nicht
über die tatsächlichen Flashdaten. Das würde ich nicht machen, da
dieselben Binärdaten durchaus unterschiedlich im .hex-File aussehen
dürfen, es ist z.B. nur Konvention, aber nicht Vorschrift, dass alle
Records 0x10 lang sind und es gibt optionale Felder wie die
Segmentadresse.
Es gibt fertigen Code genügend im Netz, der Dir eine .hex in binär
wandelt, und es gibt objcopy, das Du nur aufzurufen brauchst (system()).
Dann bekommst Du eine CRC-Summe, die unabhängig davon ist, wie das .hex
erzeugt wurde.
OK, Danke Dir.
Das muss ich erst mal verdauen. Das die HEX-Files eine andere
Formatierung haben kann bei Verwendung eines anderen Compilers/Linkers
passieren ?
Rechne doch die Prüfsumme über das komplette Flash.
Dazu malloc'st Du Dir eben 16k, füllst die mit FF (das ist der
Standardwert für gelöschte Zellen), und liest dann das Hex-File ein,
parst es und schreibst den Inhalt passend in die 16k Speicher.
Eine Zeile des HEX-Files sieht so aus:
:NNAAAATT........SS
N= Anzahl der Bytes in dieser Zeile
A= Startadresse, d.h. wo kommen die N Bytes in Dein Array rein
T= Typ, 00=Daten 01=Endekennung, mehr brauchst Du erstmal nicht
Dann die Datenbytes
und am Ende S=Prüfsumme
Wenn Du das ganze Hex-File Zeile für Zeile eingelesen hast, sieht Dein
Speicher genauso aus wie das Flash. Und da kannst Du jetzt die Prüfsumme
drüber berechnen.
fchk
Ja, aber das ist kein Beinbruch. Das .hex-Format ist einfach aufgebaut,
also leicht zu wandeln. Und es gibt fertige Utilities, die alle
möglichen Objektformate ineinander wandeln, z.B. avr-objcopy, das Teil
von WinAVR ist.
Hc Zimmerer schrieb:> Um ... ich sehe gerade, Du rechnest den CRC über das Hex-File und nicht> über die tatsächlichen Flashdaten.
Hier hörts dann mit meinem bescheidenen Verständnis auf :( ... den CRC
den ich im Atmel berechne hole ich doch aus dem Flash ?! Ich habe nur
das ausgelesene Flash-File (in HEX-Datei gelesen mit AVR-Studio)
geposted zur Veranschaulichung dachte ich.
Im PC-Programm berechne ich den CRC über die Datenbytes im HEX-File dass
AVR-Studio/GCC ausgibt, lasse aber den CRC der am Ende jeder Zeile steht
raus sowie die speziellen Angaben im HEX-File (Segmentangaben und was da
evtl noch so stehen kann ?). Ich glaube das ist das Motorola
Hex-File-Format ?
Ah, OK ... die letzten beiden Antworten von Euch hatte ich nicht mehr
gelesen und war selber dabei den eben geposteten Unsinn zu schreiben :)
... wertvolle neue Infos, besten Dank.
@Sash
Ich würde es nicht "Formatierung" nennen, denn der Aufbau
des Intel-HEX ist immer gleich.
Aber es kann und wird! vorkommen daß unterschiedliche Compiler
Linker unterschiedliche HEX-Files produzieren.
Z.B. durch anderes Optimieren vom Compiler, Unterschiedliche
Reihenfolge der einzelnen Module beim Linker.
Das fertige Programm verhält sich gleich (kleine Laufzeitunter-
schiede ausgenommen)
Kenne das aus Leidvoller Erfahrung bei 8051-Programmen.
Ich würde die CRC über die echten Flash-Daten bilden, in den
letzten Speicherstellen ablegen (beim allerersten Programmstart)
Anschließend würde ich nur noch eine Checksumme über die Flashdaten
(Ohne die gespeicherte Checksumme) bilden, vergleichen und
entsprechend Reagieren. Sollte ausreichend sein.
> Hier hörts dann mit meinem bescheidenen Verständnis auf :( ... den CRC> den ich im Atmel berechne hole ich doch aus dem Flash ?!
Ja, das weißt Du ... ich habe das bisher nicht gewusst, denn Du
schriebst von
> Parallel dazu hab ich ein Konsolen-Programm in C++ das den CRC über das> HEX-File berechnet.
und ich nahm an, Du hast beide Seiten in Form eines .hex vorliegen.
Ja nö, dann isses einfach: Das AVR-Programm kann herausbringen, wo das
Ende des beschriebenen Bereichs ist. Das sollte in C mit
1
externchar_etext;// Das Flashbyte nach Programmende
gehen, und Du rechnest den CRC dann bis &_etext.
EDIT: Natürlich bis 1 vor &_etext.