Forum: Mikrocontroller und Digitale Elektronik Checksumme von Bin/Hex-Datei berechnen und integrieren.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von heiha (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich möchte einen Mikrocontroller als erstes über den Inhalt des ROMs 
eine Checksumme bilden und das Programm nur dann ausführen, wenn alles 
in Ordnung ist. Ich denke, dass bekommt man hin. Jetzt ist nur die 
Frage, kennt jemand ein Programm, welches die Checksumme über die zu 
programmierende bin/hex-Datei berechnet und dann an den Schluss der 
bin/hex-Datei schreibt.
Ein Beispiel: Ein uC hat 8192 Byte Speicher. Die letzten zwei Byte 
werden so berechnet, dass die Summe (16bit) über alle Bytes 0x0000 
ergibt. Das Programm muss also die Checksumme über 8190 Byte berechnen 
0x0000 - 0x1FFD und dann an in die bin/hex-Datei an der Adresse 0x1FFE 
und 0x1FFF die Checksumme schreiben. Das ganze sollte noch über 
Befehlszeile programmierbar sein, dass heißt, die Software wird in den 
built Prozess mit eingebunden.
Ich weiß, dass es so etwas gibt und ich hatte auch mal so eine Software, 
aber wie es eben so ist, über die Jahre in denen ich mich privat nicht 
mit uCs beschäftigt habe, kam der Dateifresser (man muss ja nicht alles 
aufheben).
Viele Grüße heiha

von Eric B. (beric)


Bewertung
-1 lesenswert
nicht lesenswert
Google kaputt? "checksum calculator hex" gibt eine ganze Reihe von 
Resultate!

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
heiha schrieb:
> ich möchte einen Mikrocontroller als erstes über den Inhalt des ROMs
> eine Checksumme bilden und das Programm nur dann ausführen, wenn alles
> in Ordnung ist.

Wenn ich es richtig verstanden habe: Der µC soll die Checksum über sein 
Flash bilden? Und dann seinen Code ausführen, wenn diese Checksum in 
Ordnung ist?

> Ich denke, dass bekommt man hin.

Nicht so einfach. Das ist stark Prozessor-abhängig, ob und wie das geht. 
Von welchem µC sprichst Du denn?

Und das blödeste: Um festzustellen, ob der µC seinen Code ausführen 
darf, muss er seinen Code (zum Ermitteln der Checksum) ausführen! Was 
machst Du denn, wenn der vermutete Flash-Fehler genau in der 
Checksum-Ermittlungsroutine steckt? Dann kann alles mögliche passieren.

> Jetzt ist nur die
> Frage, kennt jemand ein Programm, welches die Checksumme über die zu
> programmierende bin/hex-Datei berechnet und dann an den Schluss der
> bin/hex-Datei schreibt.

Auch das ist nicht trivial: Die Bin- und Hex-Dateien haben einen 
komplett anderen Aufbau. Bei der Hex-Datei könnten zum Beispiel Daten 
für 0x0000 bis 0x1000 (Text-Section) drinstehen und dann nochmal 0x1A00 
bis 0x2000 (8192) für eine Data- oder eine zweite Text-Section.

Erstmal bekommst Du dann Deine zwei Bytes gar nicht mehr reingequetscht, 
zum zweiten hat die Hex-Datei eventuell ein "Loch", deren Inhalt nicht 
bekannt ist. Dann ist es eine ziemlich blöde Idee, eine Checksum einer 
Hex-Datei mit der Checksum eines Flash-Inhalts zu vergleichen.

Insgesamt: Vergiss es. Jedenfalls so allgemein formuliert, wie Du Dir 
das vorstellst.

: Bearbeitet durch Moderator
von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
Ok, es ist Freitag heute und ich habe gute Laune ;-)

Ein kleines Python3-Skript dass einfach die 16-bit Checksumme generiert 
und an eine Eingabedatei hinten dran kleckert:
1
#!/usr/bin/python3
2
import sys
3
4
def main(argv):
5
    with open(argv[1], "rb") as fp:
6
        data = fp.read()
7
8
    checksum = 65536 - sum(data) % 65536
9
10
    check_hi = checksum // 256
11
    check_lo = checksum % 256
12
13
    with open(argv[2], "wb") as fp:
14
        fp.write(data)
15
        fp.write(bytes([check_hi, check_lo]))
16
17
if __name__ == '__main__':
18
    if len(sys.argv) < 3:
19
        print("Use " + sys.argv[0] + "input_file output_file")
20
    else:
21
        main(sys.argv)

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Eric B. schrieb:
> Ein kleines Python3-Skript dass einfach die 16-bit Checksumme generiert
> und an eine Eingabedatei hinten dran kleckert:

Nett, aber hast Du Dir mal eine Hex-Datei angeschaut? Da stehen 
Adressen, Inhalte und Checksums drin. Du darfst laut Aufgabenstellung 
nur die Checksum der Inhalte bilden. Denn nur diese landen im Flash! 
Dann musst Du noch einen neuen Record vor dem End of File Record (Typ 
01) einfügen, die Checksum über die Checksum bilden und diese als 
Record-Checksum mitsamt dem kompletten Record wegschreiben.

Aber bloß nicht am Ende der Datei! Dann stehts nämlich hinter dem 
End-Of-File-Record und wird ignoriert!

Wenn Du diese Hürden überwunden hast, fehlt dann noch das µC-Programm: 
Bilden einer Checksum über den Flash-Speicher, obwohl der µC gar nicht 
weiß, welche Bereiche seines Flashs überhaupt mit der Hex-Datei 
beschrieben wurden. Aua!

Also insgesamt - egal wie schön Deine "Lösung" aussieht: Sie ist nicht 
anwendbar. Einfach, weil die Aufgabenstellung schon unsinnig ist.

EDIT: Auch bei einer Bin-Datei ist die "Lösung" nicht anwendbar. Denn 
das Klatschen von 2 zusätzlichen Bytes veranlasst das Brenner-Programm 
nicht, diese beiden im Flash an der geforderten Stelle 8192 (das Ende 
des Flashs) zu positionieren.

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Wenn Du diese Hürden überwunden hast, fehlt dann noch das µC-Programm:
> Bilden einer Checksum über den Flash-Speicher, obwohl der µC gar nicht
> weiß, welche Bereiche seines Flashs überhaupt mit der Hex-Datei
> beschrieben wurden. Aua!

 Naja, wenn sich dieser Checksum immer an der Adresse 8190 befindet,
 weiss der uC von wo bis wo gerechnet werden muss, das sollte also
 keinen allzugrossen Problem darstellen.

 PC kann die Hex-Datei Zeile für Zeile einlesen, die letzten 2 ASCII
 Zeichen sind Checksum, bis zum Record mit 01 (EOF) werden diese
 Byteweise addiert, dann wird die neue Zeile mit Adresse 8190 rein-
 geschrieben, danach EOF Zeile.

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
heiha schrieb:
> Ein Beispiel: Ein uC hat 8192 Byte Speicher. Die letzten zwei Byte
> werden so berechnet, dass die Summe (16bit) über alle Bytes 0x0000
> ergibt. Das Programm muss also die Checksumme über 8190 Byte berechnen
> 0x0000 - 0x1FFD und dann an in die bin/hex-Datei an der Adresse 0x1FFE
> und 0x1FFF die Checksumme schreiben.

Wie Frank M. schon gesagt hat, mit einer .hex Datei ist das keine Gute 
Idee (wegen der ausgelassenen Speicherbereiche, die dann im Flash einen 
unbekannten Inhalt haben).

Wenn dann geht das nur über ein .bin File.
Da du ja den Algorithmus der Checksummen-Bildung für den uC eh 
programmieren musst verstehe ich allerdings nicht so ganz, worin das 
Problem besteht, diesen Algorithmus in ein kleines Programm einzubauen, 
der dir das .bin File patched.

bin_file_einlesen();
checksumme_bilden();
letzte_bytes_patches();
bin_file_wegschreiben();

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> Naja, wenn sich dieser Checksum immer an der Adresse 8190 befindet,
>  weiss der uC von wo bis wo gerechnet werden muss, das sollte also
>  keinen allzugrossen Problem darstellen.

Ich sage ja nicht, dass es prinzipiell für einen konkreten µC unlösbar 
ist. Der TO formulierte seine Aufgabenstellung jedoch sehr allgemein. 
Allgemein ist das nicht lösbar. Deshalb schrieb ich:

> Nicht so einfach. Das ist stark Prozessor-abhängig, ob und wie das geht.
> Von welchem µC sprichst Du denn?

Marc V. schrieb:

>  PC kann die Hex-Datei Zeile für Zeile einlesen, die letzten 2 ASCII
>  Zeichen sind Checksum, bis zum Record mit 01 (EOF) werden diese
>  Byteweise addiert, dann wird die neue Zeile mit Adresse 8190 rein-
>  geschrieben, danach EOF Zeile.

Ja, natürlich geht das, aber nicht mit Erics Programm. Es müssen die 
Inhalte interpretiert und anschließend manipuliert werden. Das Dumme ist 
nur, dass in den wenigsten HEX-Dateien genau 8190 Bytes stehen, sondern 
weniger. Das einzige, was Du vielleicht voraussetzen kannst, dass an den 
nicht-beschriebenen Flash-Speicherstellen 0xFF stehen. Wenn Du diese mit 
in die Checksum einbeziehst, kann es vielleicht funktionieren.

Deshalb schrieb ich:

> Auch das ist nicht trivial: ...

Fazit: Der TO macht es sich viel zu einfach. Man kann eine Lösung für 
einen  speziellen µC entwickeln... und hoffen, dass das Flash vor dem 
Brennen auch  komplett mit 0xFF initialisiert wurde. Sonst kannst Du gar 
nichts aussagen über den Flash-Bereich, der nicht programmiert wird. 
Und damit wäre auch eine Checksum über den Flash nicht aussagekräftig.

: Bearbeitet durch Moderator
von dummschwaetzer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>einen Mikrocontroller

welchen?
Bei MSP430 und Elprotronic-Programmer kein Thema...

von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Nett, aber hast Du Dir mal eine Hex-Datei angeschaut?

Ja, zu oft würde ich sogar sagen. Frage war aber nach bin/hex:

heiha schrieb:
> ein Programm, welches die Checksumme über die zu
> programmierende bin/hex-Datei berechnet und dann an den Schluss der
> bin/hex-Datei schreibt.

Und für bin ist das Skript bestens geeignet; hex überlasse ich dir als 
Übung fürs WE ;-)

: Bearbeitet durch User
von Dietrich L. (dietrichl)


Bewertung
0 lesenswert
nicht lesenswert
Folgende Lösung finde ich recht übersichtlich und universell:

- ein Array der Größe des Flashs anlegen
- das Array mit dem Reset-Wert des Flashs initialisieren
- die Hex-Datei in das Array einlesen
- über das Array die Checksum bilden und in die letzten Bytes schreiben
- aus dem kompletten Array eine Hex- oder Bin-Datei erzeugen.

In dem Fall ist es egal, wie die Hex-Datei aufgebaut ist bzgl. 
Reihenfolge und Lücken, und ob das Flash gelöscht wurde. Die 
Ergebnis-Datei enthält ja das komplette Flash - egal wie groß das 
Programm vorher war.

von Steffen R. (steffen_rose)


Bewertung
0 lesenswert
nicht lesenswert
Ich werfe mal srec_cat zum Manipulieren der Dateien in den Raum. Geht 
auch für intel hex und binaries. Einfache Checksummen gehen wohl auch.

Frank M. schrieb:
> Das Dumme ist
> nur, dass in den wenigsten HEX-Dateien genau 8190 Bytes stehen, sondern
> weniger. Das einzige, was Du vielleicht voraussetzen kannst, dass an den
> nicht-beschriebenen Flash-Speicherstellen 0xFF stehen.

Nicht nur dort, sondern bei den Programmen, die ich so kenne, gibt man 
den Inhalt der Löcher an. Ist ja ein übliches "Problem".
Da der TO seinen Prozessor kennt, sollte er auch seinen 
Flasher/Bootloader kennen. Es ist zumindest unüblich, dass die Löcher 
einen zufälligen Wert bekommen.

von Kaj (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Eric B. schrieb:
> Ein kleines Python3-Skript dass einfach die 16-bit Checksumme generiert
Leider ist die Checksumme nicht brauchbar.
Fuer deine Checksumme ist es egal ob da die Bytes in der Reihenfolge
1
0x01 0x02 0x03
stehen, oder
1
0x03 0x01 0x02
Das ist aber fuer das Programm/den Controller nicht egal. Damit bietet 
die Checksumme keine Sicherheit.

Hier mal eine crc16_ccitt:
1
uint16_t crc16_ccitt(uint32_t len, uint8_t* p_input, uint16_t seed) {
2
  static const uint16_t crc_ccitt_table[] = {
3
    /*          0      1      2      3      4      5      6      7   */
4
    /*          8      9      a      b      c      d      e      f   */
5
    /* 00 */  0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
6
              0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
7
    /* 10 */  0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
8
              0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
9
    /* 20 */  0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
10
              0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
11
    /* 30 */  0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
12
              0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
13
    /* 40 */  0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
14
              0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
15
    /* 50 */  0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
16
              0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
17
    /* 60 */  0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
18
              0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
19
    /* 70 */  0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
20
              0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
21
    /* 80 */  0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
22
              0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
23
    /* 90 */  0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
24
              0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
25
    /* a0 */  0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
26
              0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
27
    /* b0 */  0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
28
              0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
29
    /* c0 */  0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
30
              0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
31
    /* d0 */  0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
32
              0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
33
    /* e0 */  0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
34
              0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
35
    /* f0 */  0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
36
              0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0,
37
  };
38
39
  uint16_t crc = seed;
40
41
  if (len > 0) {
42
    for( uint32_t i = 0; i < len; i++ ) {
43
      crc = (uint16_t) ( (crc << 8) ^ crc_ccitt_table[ (crc >> 8) ^ p_input[i] ]);
44
    }
45
  }
46
47
  return crc;
48
}

Test:
1
int main(void) {
2
    uint8_t x[2] = {0x01, 0x02};
3
    uint8_t y[2] = {0x02, 0x01};
4
5
    printf("Checksumme fuer x: 0x%x\n", crc16_ccitt(2, x, 0));
6
    printf("Checksumme fuer y: 0x%x\n", crc16_ccitt(2, y, 0));
7
8
    return 0;
9
}

Ausgabe:
1
Checksumme fuer x: 0x1373
2
Checksumme fuer y: 0x7643

Die gleichen Eingabewerte, andere Reihenfolge -> andere Checksumme.
Eine Checksumme, bei der ein vordefinierter Wert rauskommen soll 
(0x0000) macht fuer mich nur wenig sinn.
Ist ja aber am Ende nicht mein Bier.
Da ist jetzt schon mal ne CRC die Positionsabhaengig ist, und ob das 
ganze dann noch auf 0 gerechnet wird oder nicht, kann ja jeder machen 
wie er lustig ist.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Deutlich einfacher ist, wenn der µC beim ersten Start die Checksumme 
seines Flash Speichers bildet und im EEprom ablegt. Bei allen folgenden 
Starts vergleicht er die Checksummen.

von Darth Moan (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moi,

Dazu muss er aber auch ein EEPROM oder vergleichbares haben.
In manchem Compiler/Linker ist ein solches Feature schon fest eingebaut.
Hatte zb. mal IAR compiler fuer 78K0R am wickel. Da schreibt man ins 
Linker
cmd File rein, ueber welchen Bereich was fuer eine Checksumme berechnet
werden soll und wo sie abgelegt werden soll.
Vorteil ist da, dass der Compiler/Linker ja schon wusste, ob der µC 
little
oder big endian sehen will (beim speichern der CRC).
Kann man natuerlich auch einfach vorher festlegen, und die Routine im µC
muss die CRC aus dem vereinbarten Speicher so herauslesen.

Man kann natuerlich hingehen, und der routine eine Kofigurationstabelle
mitgeben. Dann kann man beliebige Bereiche berechnen oder auslassen.
Das externe Tool muss dann natuerlich diese Tabelle ebenfalls 
extrahieren
und die CRCs berechnen und einpatchen. Natuerlich duerfen die CRCs nicht 
in einem Bereich liegen ueber den eine CRC berechnet wird. Es sei denn 
eine eigene CRC nur ueber die CRCs. Diese CRC darf dann aber in keinem 
anderen
Bereich liegen ueber den eine CRC gebildet wird.

Aber das Speicherlayout muss ja sowieso irgendwann mal festgelegt 
werden.
Wenn man einen Bootloader hat, kann es guenstig sein, den nicht mit zu
pruefen. Der ist oft ein eigenes Projekt und kann auch in verschiedenen 
Versionen vorliegen. Die aber alle akzeptabel sein koennen.

von Natter (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Deutlich einfacher ist, wenn der µC beim ersten Start die Checksumme
> seines Flash Speichers bildet und im EEprom ablegt. Bei allen folgenden
> Starts vergleicht er die Checksummen.

Was soll der Quatsch? Das ist Unfug, da beim ersten Start bereits ein 
Fehler vorliegen könnte.

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Deutlich einfacher ist, wenn der µC beim ersten Start die Checksumme
> seines Flash Speichers bildet und im EEprom ablegt.

Das schützt vor alterndem Flash, aber nicht vor defekt geflashter 
Firmware.

Zudem will man in der Regel nur bestimmte Sections prüfen (.text, .data 
und vllt .startup). Der Rest vom Flash kann ja von z.B. einer 
EEPROM-Emulation genutzt werden.

Nur der Linker weiß, welche Sections wo im Flash liegen, in einer 
Hex/Bin steht das nicht mehr drin. Also geht sowas nicht sauber.

> Bei allen folgenden Starts vergleicht er die Checksummen.

Das heißt, wenn die Checksumme im EEPROM nicht mehr stimmt, dann wird 
sie aktualisiert? Sehr gute Idee. :-)

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
> Das ist Unfug, da beim ersten Start bereits ein
> Fehler vorliegen könnte.

Um dies auszusch.ießen macht man in meinen Kreisen ohnehin immer eine 
Funktionskontrolle, bevor man das Produkt an den Kunden übergibt.

Ein Gerät ungetestet zu übergeben, wo man lediglich doppelt sicher ist, 
dass die Firmware erfolgreich "gebrannt" wurde, halte ich für 
fragwürdig.

> Das heißt, wenn die Checksumme im EEPROM nicht mehr stimmt,
> dann wird  sie aktualisiert?

Das habe ich nicht gemeint. Ich wiederhole nochmal:

> beim ersten Start die Checksumme seines Flash Speichers bildet
       ^^^^^^
damit meine ich im Werk im Rahmen der Funktionskontrolle.

> Bei allen folgenden Starts vergleicht er die Checksummen.

Das passiert beim Kunden. Von "aktualisieren" habe ich nichts 
geschrieben.

: Bearbeitet durch User
von Georg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
heiha schrieb:
> Die letzten zwei Byte
> werden so berechnet, dass die Summe (16bit) über alle Bytes 0x0000
> ergibt

Das ist antürlich die einfachste Möglichkeit, braucht nur ein paar Byte 
Programm, aber auch die unsicherste, CRC ist erheblich sicherer.

Bei einem PC werden Zusatz-ROMs so geprüft, aber da gibt es einen 
laufenden PC, der eine Meldung ausgibt, dass auf der Karte xx ein Fehler 
vorliegt. Ein Embedded System, dessen Software korrupt ist, kann das 
nicht, es erhebt sich also die Frage, was tun im Fehlerfall. Nichts tun 
ist eine schlechte Option, schon weil ein Prozessor niemals nichts tut. 
Das Mindeste wäre, die Peripherie in einen sicheren Zustand zu versetzen 
bzw. nicht anzufassen, denn nach einem Reset sollte/muss sie in einem 
solchen Zustand sein. Dazu würde ich mindestens eine LED zur 
Fehlermeldung einschalten.

Die Software von Programmern kann meistens die Prüfsumme bilden, die hat 
man früher auf einen kleinen Zettel geschrieben und auf die Eproms 
geklebt, für den Kundendienst.

Georg

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:
> Das ist antürlich die einfachste Möglichkeit, braucht nur ein paar Byte
> Programm, aber auch die unsicherste, CRC ist erheblich sicherer.

CRC gut, wenn einem die Recourcen dafür nicht kümmern.
Für einen simplen Check des Applikationscodes z.B. durch einen 
Bootloader, ist m.E. CRC aber Overkill. Ein Bootloader soll kompakt sein 
und muss in einen bestimmten Speicherbereich passen, u.U. zählt da jedes 
Byte.
Und dann muss der Bootloader ja im Wesentlichen nur feststellen, ob 
überhaupt ein gültiges Applikationsprogramm im Speicher steht, damit er
nicht ins "Nirwana" bootet.
Die typischen Fehlerszenarien kann eine CRC nicht besser handlen, als 
eine simple Summe:
- Applikation noch gar nicht geladen:
  kein Problem für CRC oder Summe
- Applikation nur teilweise geladen (z.B. Abbruch beim Ladevorgang):
  gibt einen Zufallswert, sowohl bei CRC, als auch bei der Summe.
  Damit stehen sowohl bei 16-Bit CRC, als auch 16-Bit Summe die Chancen
  1:65535, daß ein "false Positive" herauskommt.
- einzelne Bitfehler durch Flash-Alterung:
  da dürften eher einzelne Bits umkippen (von 0 nach 1), was eine
  Prüfsumme mit ziemlicher Sicherheit auch merkt. Daß sich im Speicher
  plötzlich zwei Bytes vertauschen, was eine CRC merkt, aber eine Summe
  nicht, tritt wohl eher nicht ein.

Nachteil einer CRC wäre noch, daß der Bootvorgang ein paar ms länger 
dauert, als mit der Summe.

Freilich, wenn es um Sicherheit gegen Code-Manipulation z.B. durch 
Hacker/Raubkopierer o.ä. geht, bietet eine simple Summe keinen Schutz.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:

> CRC gut, wenn einem die Recourcen dafür nicht kümmern.

CRC braucht nicht viel. Man kann natürlich die ganz schnelle Lösung 
nehmen mit ein Byte pro Iteration, dazu braucht man dann eine 
256-Tabelle. Oder die ganz langsame Lösung ohne Tabelle und 1 Bit pro 
Iteration. Dazwischen gibt's als feinen Kompromiß auch noch 1 Nibble pro 
Iteration, dazu braucht man nur eine Tabelle der Länge 16.

Benchmarks (auch auf µC!) und diversen Code, alles sehr schön 
aufbereitet, gibt es hier:

http://create.stephan-brumme.com/crc32/

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:

> Nur der Linker weiß, welche Sections wo im Flash liegen, in einer
> Hex/Bin steht das nicht mehr drin. Also geht sowas nicht sauber.

Ich kenne das ganz einfach so:

- Binfile einlesen.
- Auffüllen mit 0xFF bis zu einer gewissen Grenze (also wenn die 
Firmware z.B. 180K ist, dann bis 200K auffüllen).
- Das ist natürlich auch in der Firmware so konfiguriert, so daß sie 
weiß, wo die Checksumme liegen wird.
- Dann eine CRC über den Bereich berechnen abzüglich der letzten zwei 
bzw. vier Bytes (CRC-16 bzw. CRC-32).
- Das byteweise in die letzten Bytes schreiben (um Endianess-Probleme 
auszuschließen).
- Das zusammen mit der konfigurierten Startadresse im Flash als Hexfile 
ausspucken.

Das ist völlig normal in Systemem, die industrielle 
Zuverlässigkeitsanforderungen erfüllen sollen.

Natürlich kann man einen Teil des EEPROMs auch noch für Daten verwenden, 
wenn man die nur selten schreibt (Abnutzung). Das geht dann aber auch im 
Linkerscript, und dementsprechend weiß man, wo was liegt. Man muß die 
Sektionen nicht hintereinander starten, sondern man kann im Linkerfile 
auch eine Sektion an einer sauberen Blockadresse starten lassen.

Für die Daten nimmt man dann eine eigene CRC im Datenbereich, das ist 
Teil der Definition des Datenformates.

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> CRC braucht nicht viel.

Aber eine Summierung braucht eben noch weniger (keine Tabellen, keine 
Schiebe-Loops für jedes Wort, nur eine(!) Operation pro Wort bzw. grad 
mal eine zusätzliche Addition auf einem 8-Bitter für den Übertrag. Wenn 
man von der CRC keine nennenswerten Vorteile für die geforderte Aufgabe 
hat, wozu sollte man es dann komplizierter, als nötig, machen?

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:

> man von der CRC keine nennenswerten Vorteile für die geforderte Aufgabe
> hat, wozu sollte man es dann komplizierter, als nötig, machen?

Das Nichtbenutzen einer Checksumme hat sogar noch weniger Aufwand, 
allerdings auch eine noch geringere Entdeckungswahrscheinlichkeit. Es 
kommt halt drauf an, welchen Grad an Zuverlässigkeit man will bzw. was 
von entsprechenden Normen vorgegeben ist.

Bei entsprechend langer Betriebsdauer sind übrigens mehrfache Bitfehler 
durchaus wahrscheinlich, weil das gesamte Flash seine Daten ja relativ 
einheitlich verliert.

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Bei entsprechend langer Betriebsdauer sind übrigens mehrfache Bitfehler
> durchaus wahrscheinlich, weil das gesamte Flash seine Daten ja relativ
> einheitlich verliert.

Ja, wie hoch ist wohl die Wahrscheinlichkeit, daß z.B. genau bei 512 
Bytes die MSBs von 0 nach 1 wechseln, damit bei einer 16-Bit Prüfsumme 
zufällig das Gleiche 'rauskommt? Technisch spricht m.E. nichts für eine 
nennenswerte Wahrscheinlichkeit, daß sich zufällige Bitfehler in der 
Summe gegenseitig aufheben. Es ist ja nun auch nicht so, daß in der 
Praxis Flashspeicher ständig an Alzheimer leiden.
Wenn man professionell programmiert und sich durch Vorgaben an 
irgendwelche Normen halten muss, ist es vielleicht etwas Anderes - der 
TO hat aber nichts von ISO-Zertifikation o.ä. geschrieben.

Nop schrieb:
> Das Nichtbenutzen einer Checksumme hat sogar noch weniger Aufwand,
> allerdings auch eine noch geringere Entdeckungswahrscheinlichkeit.

Reine Rethorik - da kann man auch sagen, wenn man sich als Fussgänger 
die Ampel sparen will, kommt man noch schneller über die Straße, wenn 
man sich auch noch spart, nach dem Verkehr zu schauen.
Ein Erzieher mit 'ner Horde Kinder im Schlepptau sollte sich natürlich 
an die Norm halten und den Weg über die Ampel nehmen...

: Bearbeitet durch User
von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:

> Ja, wie hoch ist wohl die Wahrscheinlichkeit, daß z.B. genau bei 256
> Bytes die MSBs von 0 nach 1 wechseln

Muß es auch nicht. Es kann z.B. auch sein, daß zwei verschiedenartige 
Bits in selber Bitposition entgegengesetzt kippen, und da 1+0=0+1, ist 
das schon nicht mehr detektierbar.

Deswegen ist die Hamming-Distanz der arithmetischen Summe eben nur zwei, 
egal wieviel Bit die Checksumme hat. Eine CRC-k hingegen sinkt erst ab 
einer Datenbitmenge von 2^k auf eine Hammingdistanz von 2. Eine CRC-16 
wird also ab 8kbyte sinnfrei, da nimmt man sinnigerweise CRC-32.

Die Berechnungskosten einer CRC werden übrigens auch maßlos übertrieben, 
die sind bei gescheiter Implementation eher sowas wie das Vierfache 
einer arithmetischen Checksumme. Als Kompromiß gäbe es dazwischen 
natürlich auch noch Fletcher und Adler.

Ansonsten empfehle ich mal z.B. das hier:
https://users.ece.cmu.edu/~koopman/thesis/maxino_ms.pdf

Das Einzige, was man niemals verwenden sollte, ist die Xor-Checksumme. 
Ist genauso teuer wie Addieren, aber nur halb so gut.

Zudem ist es auch falsch, daß CRC die Bootzeit zwingend verlängern 
würde. Man kann die Checksumme beim Booten abprüfen, man kann derlei 
aber auch in Idle-Zeiten machen, etwa in Delay-Routinen oder im 
Idle-Task. Dann muß eben 10 Sekunden nach dem Booten ein grünes Lämpchen 
angehen, wenn alles OK ist.

Das ist technisch geradezu trivial machbar, indem man den Zähler und die 
Zwischen-CRC in der Prüfroutine als static markiert und immer nur so und 
soviel Bytes pro Aufruf gescannt werden.

von Avantasia (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ist Euch schon aufgefallen, dass der TO sich nach seinem Posting nicht 
mehr in die Diskussion eingeklinkt hat... Ihr könnt natürlich weiter 
diskutieren... aber ich glaube hier war nur ein Troll unterwegs.

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Es kann z.B. auch sein, daß zwei verschiedenartige
> Bits in selber Bitposition entgegengesetzt kippen

Kann es? Das ist halt die Frage: was passiert mit den Floating Gates der 
Flash Speicherzellen über die Jahre, wenn der Flash-Speicher altert? 
Laden oder entladen sich die Gates möglicherweise? Löschen oder 
Programmieren sich die Bits über die Jahre eher? Oder übertägt ein 
Transistor seine Gate-Ladung vielleicht sogar auf einen anderen? Nur im 
letzen Fall scheint es mir plausibel, daß zwei verschiedene 
Speicherzellen gleichzeitig in genau entgegengesetzte Richtung kippen - 
scheint mir doch eher unwahrscheinlich.
Ich tippe eher darauf, daß sich Fehler, wenn sie auftreten, eher in der 
gleichen Richtung zeigen.

Im Übrigen schreiben wir hier offenbar von verschiedenen 
Ziel-Applikationen:

Nop schrieb:
> man kann derlei
> aber auch in Idle-Zeiten machen

Deine scheint nicht die des Themenstarters zu sein:

heiha schrieb:
> ich möchte einen Mikrocontroller als erstes über den Inhalt des ROMs
> eine Checksumme bilden und das Programm nur dann ausführen, wenn alles
> in Ordnung ist.

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Ein Gerät ungetestet zu übergeben, wo man lediglich doppelt sicher ist,
> dass die Firmware erfolgreich "gebrannt" wurde, halte ich für
> fragwürdig.

Fehler in der Firmware kann man durch testen ausschließen.
Fehler durch Alterung kann man durch dein Verfahren ausschließen.

Fehler durch falsch (v.a. unvollständig) gebrannte Firmware halte ich 
für das größere Problem, wenn die Geräte öfter mal mit Updates versorgt 
werden - und dagegen schützt dein Ansatz nicht (bzw. nur dann, wenn der 
EEPROM-Inhalt erhalten bleibt, was nicht immer wünschenswert ist).

Nop schrieb:
>> Nur der Linker weiß, welche Sections wo im Flash liegen, in einer
>> Hex/Bin steht das nicht mehr drin. Also geht sowas nicht sauber.
>
> Ich kenne das ganz einfach so:

Ja klar, in der Firmware den zu prüfenden Bereich und den Ort der 
Prüfsumme hart codieren geht natürlich. Ist aber nicht besonders 
flexibel und schon garnicht universell. Wenn es das nicht sein muss, 
okay.

> Natürlich kann man einen Teil des [Flashs] auch noch für Daten verwenden,
> wenn man die nur selten schreibt (Abnutzung). Das geht dann aber auch im
> Linkerscript, und dementsprechend weiß man, wo was liegt.

Das sieht man dem Hexfile aber auch nicht mehr an. Der Linker weiß das, 
aber der weiß auch, wo Code und Daten im Flash liegen...

> Man muß die Sektionen nicht hintereinander starten,
> sondern man kann im Linkerfile auch eine Sektion an
> einer sauberen Blockadresse starten lassen.

Und wenn man die wieder im Voraus festlegt, wie du das oben mit der 
Größe des zu prüfenden Bereichs gemacht hat, dann ist das wieder etwas 
anderes, als wenn man (im allgemeinen Fall) davon ausgeht, dass die 
Daten auf dem nächsten Block starten.

Nur der Linker kennt die genauen Adressen, es sei denn, du zwingst ihn 
(und die Firmware) dazu, dir bereits vorher bekannte Adressen zu 
benutzen. Dann - und auch nur dann - kannst du einfach auf dem Hexfile 
rumspielen.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
> Fehler durch falsch (v.a. unvollständig) gebrannte Firmware halte ich
> für das größere Problem, wenn die Geräte öfter mal mit Updates versorgt
> werden ... und dagegen schützt dein Ansatz nicht

Richtig. Aber dann kommt ein Bootloader mit ins Spiel. Ich dene, dem TO 
ging es nicht um dieses Szenario.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:

> Kann es? Das ist halt die Frage: was passiert mit den Floating Gates der
> Flash Speicherzellen über die Jahre, wenn der Flash-Speicher altert?

Weiß ich jetzt nicht, aber plausibel wäre es natürlich, daß sie von 
selber früher oder später einen Zustand mit minimaler Energie einnehmen 
wollen, was dann je nach Aufbau logisch 0 oder logisch 1 wäre.

Es ist aber nicht das einzige Fehlermuster. Die Software wird ja nicht 
in den Controller gebeamt, sondern typisch von einem PC in den 
Controller gespielt. Da hat man dann noch viel mehr Fehlermöglichkeiten. 
RAM-Bits können etwa kippen, wenn die Datei im Arbeitsspeicher ist, und 
die meisten Leute kaufen ja keine ECC-Boards.

> Im Übrigen schreiben wir hier offenbar von verschiedenen
> Ziel-Applikationen:

Nein, denn dem TO schwebte eine bestimmte Implementierung vor - aber wie 
so oft in diesem Forum kann es durchaus sein, daß das nur daher kommt, 
daß er auf die Alternative nicht kam, obwohl sie ggf. durchaus auch 
einsetzbar wäre.

Man kann natürlich auch beide Ansätze kombinieren.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:

> Nur der Linker kennt die genauen Adressen, es sei denn, du zwingst ihn
> (und die Firmware) dazu, dir bereits vorher bekannte Adressen zu
> benutzen.

Auch nicht. Man kann ja auch in der Firmware Variablen benutzen, die 
überhaupt erst vom Linker erzeugt werden. Bei der Init-Kopierschleife 
für die DATA-Sektion macht man das normalerweise so.

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Richtig, aber diese Adressen siehst du dem Hexfile dann nicht mehr an, 
kannst also das Hexfile nicht mehr zuverlässig nachträglich manipulieren 
(um z.B. eine Checksumme einzutragen). Das war ja der Punkt.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
> Richtig, aber diese Adressen siehst du dem Hexfile dann nicht mehr an

Ja das wird schwieriger. Andererseits werden diese Variablen ja im 
Linkerscript ermittelt, und man kann damit in ebendiesem Script sogar 
rechnen, um etwa Bereichsüberläufe beim Linken anzuwarnen.

Also müßte man sie doch auch ausgeben können? Im simpelsten Fall in eine 
Datei, welche dann das CRC-Buildscript einlesen könnte.

Zugegeben, das wird aufwendiger, weswegen die Methode mit dem Auffüllen 
und der festen Adresse auch die ist, welche ich in der Praxis als 
einzige wiederholt angetroffen habe (und auch selber verwende).

von eagle user (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Was übersehe ich hier? Ich wollte einfach eine struct für die ersten 
Bytes des Hexfiles definieren. Ein Element darin wäre das CRC-Wort, ein 
anderes die höchste Adresse im Flash. Damit muss ich nichts auffüllen, 
das Hexfile wird 1:1 so gebrannt.

Der Bootloader und das Anwendungsprogramm auf dem uC und das 
CRC-Generator-Programm könnten alle diese struct  benutzen. Damit dürfte 
es keine Missverständnisse geben, auch wenn im Hexfile keinerlei 
Metadaten drin sind (die struct enthält ja alles, was man braucht). Ich 
muss nur dafür sorgen, dass dieser Header auch ganz am Anfang landet. 
Aber irgendetwas muss ja immer auf eine feste Adresse gelinkt werden.

Aber wodurch könnten Lücken im Hexfile entstehen? Warum sollte der 
Linker Code und Daten nicht lückenlos packen? Na gut, ich mag manche 
Sachen auf 16 Byte Grenzen aligned haben, aber diese kleinen Löcher 
können doch leicht vom Linker, bei der Hexfile-Erzeugung oder vom 
CRC-Generator-Programm aufgefüllt werden?

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
eagle user schrieb:
> Ich wollte einfach eine struct für die ersten Bytes des Hexfiles
> definieren. Ein Element darin wäre das CRC-Wort, ein anderes
> die höchste Adresse im Flash.

Die ersten Bytes im Hexfile gehen prinzipiell nicht, weil der Adressraum 
reserviert ist (Vektortabelle u.ä.). Außerdem musst du dann die Adresse 
der Struct im Linkerscript genau festlegen, sonst kann der Linker sie 
beliebig irgendwo im Flash speichern.

Aber ob du nun die Adresse einer Struct festlegst, oder die beiden Werte 
anderweitig festlegst, spielt keine Rolle.

eagle user schrieb:
> Aber wodurch könnten Lücken im Hexfile entstehen? Warum sollte der
> Linker Code und Daten nicht lückenlos packen?

Weil er vielleicht im Linkerscript dazu aufgefordert wurde, Löcher zu 
lassen.

Wir sind uns alle einig, dass dein Ansatz funktioniert, wenn du 
irgendetwas (in deinem Fall: Die Adresse der Struct.) vorher 
festlegst. Kein Problem.

von eagle user (Gast)


Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
> eagle user schrieb:
>> Ich wollte einfach eine struct für die ersten Bytes des Hexfiles
>> definieren. Ein Element darin wäre das CRC-Wort, ein anderes
>> die höchste Adresse im Flash.
>
> Die ersten Bytes im Hexfile gehen prinzipiell nicht, weil der Adressraum
> reserviert ist (Vektortabelle u.ä.).

Ja, z.B. 0 bis 0x3F, dann würde die struct bei 0 beginnen und meine 
Daten bei 0x40.

> Außerdem musst du dann die Adresse der Struct im Linkerscript
> genau festlegen

Na klar, das muss ich ja für den reservierten Adressraum sowieso immer. 
Beim STM32 kann ich meine Daten sogar in den unbenutzten Plätzen der 
Vektortabelle unterbringen:
1
typedef struct vector_struct {
2
  uint32_t  *top_of_stack;         //  0  initial SP
3
  isr       *crt0;                 //  1  initial PC
4
  isr       *css_nmi;              //  2  Clock security
5
  isr       *hard_fault;           //  3
6
  isr       *mem_fault;            //  4
7
  isr       *bus_fault;            //  5
8
  uint32_t   magic;                //  6 = Usage Fault, do not enable!
9
  uint32_t   crc;                  //  7
10
  uint32_t  *image_end;            //  8
11
  char      *name;                 //  9
12
  uint32_t   image_build;          // 10
13
  isr       *svc;                  // 11
14
  isr       *debug;                // 12
15
  char      *syslog_text;          // 13
16
  isr       *pendsv;               // 14
17
  isr       *systick;              // 15
18
  isr       *interrupts[128-16];
19
} vector_struct;
20
_Static_assert (sizeof(vector_struct) == 512, " Bad struct size");


> eagle user schrieb:
>> Aber wodurch könnten Lücken im Hexfile entstehen? Warum sollte der
>> Linker Code und Daten nicht lückenlos packen?
>
> Weil er vielleicht im Linkerscript dazu aufgefordert wurde, Löcher zu
> lassen.

Aber warum sollte man das tun?

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
eagle user schrieb:
> Beim STM32 kann ich meine Daten sogar in den unbenutzten Plätzen der
> Vektortabelle unterbringen

Klar kannst du das. Aber das ist keine saubere, überall funktionierende 
Lösung, sondern ein "ugly hack". Wird aber funktionieren.

eagle user schrieb:
>> Weil er vielleicht im Linkerscript dazu aufgefordert wurde, Löcher zu
>> lassen.
> Aber warum sollte man das tun?

Der TO hat nicht spezifiziert, dass er es nicht tun wollte...

von heiha (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
Ja ich war wirklich "off", das soll aber nicht heißen, dass ich den 
Treat nicht verfolgt habe.
38 Antworten, da haut es einen ja um. Vielen, vielen Dank für die ganzen 
Zeilen.
Ja, ich weiß, dass eine CRC besser ist als eine Checksumme die einfach 
daraus besteht, die Bytes zusammen zu zählen. Ich weiß aber auch dass 
das Tool, dass ich damals verwendet habe, beides konnte. Wollte es aber 
nicht komplizierter machen als nötig.
Ja, ich weiß auch, dass eine hex-Datei nicht vollständig beschrieben 
ist, aber die Lücken füllt man mit 0xFF auf. Dann erhält man eine 
bin-Datei. Oder es gibt compiler, bei denen man angibt, wie groß die 
Datei sein soll, und dann schreibt er die hex-Datei vollständig.
Ja, ich weiß, dass man ein kleines Programm schreiben kann, welches die 
Aufgabe löst. Aber auch ganz ehrlich, dass ist Jahre her, dass ich so 
ein Programm geschrieben habe, welches sich mit Kommandozeile 
"fernsteuern" lässt. Das muss ich mir nicht antun. Ich habe nicht einmal 
eine Entwicklugnsumgebung auf dem Rechner und werde hier sicher jetzt 
auch nicht damit anfangen.
Das war aber nicht die Frage, sondern:
Kennt jemand so ein Programm.
Da ich jetzt alle eträge durchgelesen habe, war bisher nur ein Vorschlag 
dabei. Der IAR compiler für einen 74kxx Controller brachte so etwas mit. 
Dann gehe ich davon aus, dass dieses Tool auch bei anderen Compilern von 
IAR integriert war.
Noch weitere Vorschläge, hat jemand mal so ein Progrämmchen geschrieben?
Viele Grüße heiha

P.S.: Nochmal, ich bi überwältigt von der Resonanz. Tolle Truppe hier!

von heiha (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Eric B. schrieb:
> Google kaputt? "checksum calculator hex" gibt eine ganze Reihe von
> Resultate!

Hallo Eric B.,
ja ich kann die Suchmaschine google bedienen. Deine Frage ist nur doof 
und provokant. Nein, ich werde Dich jetzt nicht fragen, ob Du nicht 
lesen kannst. Ich glaube, Du hast meine Frage technisch nicht 
verstanden. Ist nicht schlimm, niemand muss alles wissen, aber frag' 
mich das nächste mal einfach, bevor Du so etwas schreibst.
Viele Grüße heiha

von heiha (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Insgesamt: Vergiss es. Jedenfalls so allgemein formuliert, wie Du Dir
> das vorstellst.

Hallo Frank M.,
wer wird den die Flinte gleich ins Korn werfen. Ich hatte doch 
geschrieben, dass die uC Sache die einfachste auf der Welt ist. Jeder 
der einen uC halbwegs verstanden hat, bekommt das hin. Das ist nicht 
mehr als eine for-Schleife die 8192 mal durchlaufen wird und jeweils das 
Byte mit dem Zeiger der Schleifenkonstante in einer 16-bit Summe 
zusammen zählt. Am Ende vergleiche ich die Summe mit 0, das war's.
Der Fokus lag auf dem Programm auf dem PC, es muss die hex-Datei 
einlesen, in eine binäre Array mit 8192 byte umwandeln (Lücken mit 0xFF 
füllen) die Checksumme bilden und dann an die letzten zwei Stellen des 
Arrays schreiben. Als Resultat bekommt man eine hex-Datei die 
vollständig ist und wenn man die Bytes alle zusammen zählt kommt 0 raus.
Das Tool, dass ich damals hatte, konnte man über Kommandozeile 
fernsteuern. Beispiel "tool.exe test1.hex 0x2000 Checksumme 16 0x1FFE". 
Das wurde dann in die "Toolchain" des compilers eingebunden und man 
musste sich da kein Kopp mehr drum machen.
Das hat vor 13 Jahren so funktioniert. Jeden Abend, an dem ich 
programmiert habe 100 mal. Und jetzt bin ich auf der suche nach so einem 
Programm.
Viele Grüße heiha

von heiha (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Steffen R. schrieb:
> Ich werfe mal srec_cat zum Manipulieren der Dateien in den Raum. Geht
> auch für intel hex und binaries. Einfache Checksummen gehen wohl auch.

Ich korrigiere meine Aussage von vorhin. Hier ist noch mal ein 
Vorschlag, den ich mir gleich anschauen werde.
Viele Grüße heiha

von Heiko H. (heiha)


Bewertung
0 lesenswert
nicht lesenswert
Bin jetzt auch registriert. Bei dieser Resonanz eine Wertschätzung 
dieses Forums.
Grüße heiha

von Daniel H. (Firma: keine) (commander)


Bewertung
0 lesenswert
nicht lesenswert
heiha schrieb:
> Noch weitere Vorschläge, hat jemand mal so ein Progrämmchen geschrieben?

1. Im Linker-File eine Section am Ende deines Flashs definieren, welche 
die Referenz-Checksumme beinhalten soll

2. Im Linker-File eine Section definieren welche den gesamten Flash (bis 
auf die vorige Section) umfasst und den Linker anweisen ungenutzte 
Speicherbereiche mit einem Wert deiner Wahl zu füllen (siehe z.B. 
https://mcuoneclipse.com/2014/06/23/filling-unused-memory-with-the-gnu-linker/)

3. Im Code den Referenzwert über die Section referenzieren und den Check 
wunschgemäß implementieren (siehe z.B. 
https://mcuoneclipse.com/2012/11/01/defining-variables-at-absolute-addresses-with-gcc/)

4. Firmware kompilieren und linken

5. Script (o.ä.) schreiben, welches die Checksumme über die Nutzdaten 
des HEX-Files (exklusive der unter 1. definierten Section) bildet und 
diese im HEX-File an die in 1. definierte Section patched

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.