ATmega 168, Flash-Endmarke ?

Gast #1697835
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 ?
Gast
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.
Gast
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
Gast
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 ?
Gast
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.
Gast
@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
extern char _etext;  // Das Flashbyte nach Programmende
gehen, und Du rechnest den CRC dann bis &_etext.

EDIT: Natürlich bis 1 vor &_etext.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.