Forum: Compiler & IDEs CRC über PROGMEM ASM<>C funktioniert nicht mehr?


von AVRli (Gast)


Lesenswert?

Moin moin,

ich habe ein mittelschweres Problem. Ich bekomme meine Firmware nicht 
mehr in den ATmega32... der Bootloader (in ASM geschrieben) errechnet 
eine andere CRC als meine Routine im C Programm.

Ich verstehe nicht, warum das plötzlich so ist, ich berechne mir vor dem 
erstellen der Firmware Datei 1x die CRC in C wie folgt und speichere 
diese an eine festgelegte Stelle am Ende des Programmmemory.
1
...
2
volatile uint16_t pgmcrc; //CRC für Ausgabe 
3
...
4
5
void calc_pgm_crc(uint16_t end) {
6
/*--- CRC berechnen ---------------------------------------------------------*/
7
  char pgmbyte;
8
  uint16_t i;
9
10
  pgmcrc=0xffff;
11
  for( i = 0; i < end; i++) {
12
    pgmbyte = pgm_read_byte(i);
13
        pgmcrc = _crc_ccitt_update(pgmcrc, pgmbyte);
14
  }
15
  pgmcrc ^= 0xffff;
16
}
17
18
...
19
  calc_pgm_crc((uint16_t)((uint16_t)BOOTSTART * 2)-2); //1x im Main am Anfang
20
...

Alles lief wie immer ich bin bei Version 2.1 also gut 20 Versionen hat 
es funktioniert jetzt klappt es nicht mehr. Die Ergebnisse sind 
unterschiedlich, doch wie kann das passieren, was hab ich nicht auf dem 
Schirm??? Die Routine in ASM im Bootloader sagt "nö ich komme auf was 
anderes"... hmmm

Ich vermute das irgendwas ignoriert wird oder "optimiert" wird, doch das 
muss man doch irgendwie unterbinden können oder?

Wie gesagt es lief alles bis jetzt...

Grüße AVRli...

von Thomas (Gast)


Lesenswert?

Nur um den Vorgang zu verstehen:
- Firmware erstellen
- CRC über das Bin File extern errechnen
- CRC an das Bin oder Hex File anhängen
- Flashen
- Bootloader rechnet beim Start die CRC vom Programmspeicher bis zur CRC 
und schaut ob das soweit passt, wenn nicht wird nicht gestartet.

Passt das?

was ist BOOTSTART in deinem Code?

von Karl H. (kbuchegg)


Lesenswert?

AVRli schrieb:

> Alles lief wie immer ich bin bei Version 2.1 also gut 20 Versionen hat
> es funktioniert jetzt klappt es nicht mehr. Die Ergebnisse sind
> unterschiedlich, doch wie kann das passieren, was hab ich nicht auf dem
> Schirm??? Die Routine in ASM im Bootloader sagt "nö ich komme auf was
> anderes"... hmmm

Wenn du die Frage stellst
"Was habe ich nicht auf dem Schirm?"
dann hast du damit ein wahres Wort getätigt.

Da wirst du wohl deinen Bootloader so umändern müssen, dass du genau das 
siehst: Was kriegt er in der CRC Berechnung raus und womit wird dieses 
Ergebnis verglichen?

Egal wie - aber diese Information wäre das erste, was ich mir beschaffen 
würde.

> Ich vermute

denn genau das muss aufhören. 'Ich vermute' muss zu 'Ich weiß' werden.

von AVRli (Gast)


Lesenswert?

Danke euch das ihr mir helfen wollt...!

Thomas schrieb:
> Nur um den Vorgang zu verstehen:

- Programm compelieren
- CRC einmal gleich zum Programmstart berechnen, da das in C geschrieben 
ist rufe ich einmal die Routine oben auf
- diese CRC lasse ich mir, wenn eine Taste gedrückt ist auf mein Display 
ausgeben damit ich weiß welchen Wert die hinterlegte CRC im Firmware 
file ist
- der Bootloader startet, berechnet wiederum die CRC bis zur gleichen 
Stelle wie der Code in meinem Hauptprogramm BOOTSTART-2
- stimmt sie mit der hinterlegten (die die ich auf dem Display habe im C 
file) auf BOOTSTART-2 überein dann startet das Main Programm, stimmt sie 
nicht, bleibt der Controller im Bootloader stehen

Und das macht er nun, eine ältere Firmware lässt sich problemlos 
einspielen, die letzte die ich erstellt habe, nicht mehr.


Karl Heinz Buchegger schrieb:
> Da wirst du wohl deinen Bootloader so umändern müssen, dass du genau das
> siehst: Was kriegt er in der CRC Berechnung raus und womit wird dieses
> Ergebnis verglichen?

Die CRC die im Bootloader errechnet wird, unterscheiden sich wirklich 
von der die hinterlegt wurde. Die hinterlegte wird richtig eingelesen.

Nun kann es sein das entweder wirklich was faul ist, doch warum kann man 
dann das vorherige File erfolgreich laden?

Kann man mit AVR Studio 4 irgendwie sehen wie die Sache aussieht wenn 
calc_pgm_crc aufgerufen wird?

Karl Heinz Buchegger schrieb:
> 'Ich vermute' muss zu 'Ich weiß' werden.

Ohh ja, da muss ich Dir Recht geben... ich gebe mir Mühe die Vorgänge zu 
verstehen. ;-)

von Helmut (Gast)


Lesenswert?

Hallo,
ein paar Dinge die Du nachprüfen könntest sind mir eingefallen:

Enthält das File über das der CRC berechnet wird den kompletten 
Codebereich der dann in den Speicher geschrieben wird (und anschließend 
vom bootloader geprüft wird) oder ist da nur der Code drin der auch von 
der Firmware benutzt wird?

Im CRC Programm oben kommt der Aufruf 'pgm_read_byte'. Der holt 
offensichtlich das angegebene byte aus der Datei mit den compilierten 
Daten. Was passiert dort falls das byte nicht in der datei enthalten 
ist?
Wird dann vielleicht 0xff zurückggeben unter der Annahme dass dann im 
eigentlichen codeflash an dieser Stelle noch der Wert von nach dem 
Löschen (also 0xff) steht?
Falls das der Fall ist gibt es die Gefahr dass das flash-tool nur die 
benutzten sektoren löscht und die FW dann dort draufspielt.
Der bootloader berechnet aber die CRC über alle Sektoren und in den 
nicht benutzten steht dann ggf. noch ein Rest eines älteren 
Programmcodes drin und nicht überall 0xff.

Ich hoffe das hilft dir etwas weiter bei der Fehlersuche.

von Thomas (Gast)


Lesenswert?

AVRli schrieb:
> - Programm compelieren
> - CRC einmal gleich zum Programmstart berechnen, da das in C geschrieben
> ist rufe ich einmal die Routine oben auf
> - diese CRC lasse ich mir, wenn eine Taste gedrückt ist auf mein Display
> ausgeben damit ich weiß welchen Wert die hinterlegte CRC im Firmware
> file ist

dh du flasht das Image und startest das Programm ohne Bootloader, dann 
wird die CRC berechnet und ausgegeben. Wie kommt die CRC dann in das 
Image, welches der Bootloader checken soll?
Schreibst du die CRC über ISP Funktionen in das Flash oder wird ein 
fertiges Image mit gültiger CRC am Ende geflasht?

von Karl H. (kbuchegg)


Lesenswert?

> Die CRC die im Bootloader errechnet wird, unterscheiden sich
> wirklich von der die hinterlegt wurde. Die hinterlegte wird
> richtig eingelesen.

Tja.
Aber eine von beiden muss falsch sein. Die vom Bootloader oder die vom 
Frontend-Patchprogramm.

Welche?

(Persönlich würde ich auf den Bootloader tippen. In Assembler macht man 
schneller mal einen Fehler als im C-Code).

Was ich tun würde.
Ich würde mir Hex-Files herrichten, mit unterschiedlichen Längen von 
Nutzbytes. Und dann erst mal feststellen, ob es eventuell einen 
Zusammenhang mit der Länge gibt. Irgendwas in der Richtung: bei 254 
Bytes stimmt noch alles, bei 255 auch noch, aber bei 256 gehts schief. 
Besonders anfällig sind da immer 2-er Potenzen (Behandlung des Carry 
vergessen) bzw. die Blockgröße, mit der zum Bootloader gesendet wird 
(falls es sowas gibt). Irgendwo hat man mal vergessen, eine "Variable" 
in der Behandlung auf 0 zu setzen, irgendwo wird ein Byte zu wenig 
eingerechnet, .... Solche, eigentlich ganz banale, Dinge.

von Oliver S. (oliverso)


Lesenswert?

Ab mit dem Code in den Simulator...

Oliver

von Peter D. (peda)


Lesenswert?

AVRli schrieb:
> Ich verstehe nicht, warum das plötzlich so ist

Weil Du irgendwas geändert hast.

Kannst Du denn alte Projekte, die schonmal gingen, laden?


Peter

von Bronco (Gast)


Lesenswert?

AVRli schrieb:
1
calc_pgm_crc((uint16_t)((uint16_t)BOOTSTART * 2)-2); //1x im Main am Anfang

Wenn ich das richtig deute, berechnest Du die CRC unabhängig von der 
Größe des Codes (Hexfile) immer von 0x0000 bis "(BOOTSTART*2)-2".
Bist Du sicher, daß der Speicherbereich zwischen Hexfile-Ende und 
"(BOOTSTART*2)-2" immer gelöscht (0xFF) ist?

Ich hatte mal einen ähnlichen Fehler, weil ich im Bootloader vergessen 
hatte, IMMER ALLE Flash-Pages (außer dem Bootloader natürlich) zu 
löschen, sondern nur die Pages gelöscht hab, die mein neuer 
Applikations-Code belegt hat.
Wenn das alte Programm mehr Flash-Pages belegt hatte als das neue, stand 
dort noch alter Code im Flash und die CRC war zwangsläufig falsch.

von AVRli (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

etwas ausgeschlafener, ich habe erst mal etwas gepennt, das nimmt mich 
richtig mit. Jetzt hab ich aber erst mal ein Cut gemacht nachdem ich 
mich 6h die letzte Nacht damit rum geärgert habe. Um es vorweg zu 
nehmen, ich bin noch nicht weiter...

Im Anhang mal etwas Code... die CRC Routinen...


Peter Dannegger schrieb:
> Kannst Du denn alte Projekte, die schonmal gingen, laden?

Ja das ist ja das kuriose, selbst Projekte die größere Firmwaren haben, 
die laufen mit den gleichen Routinen. 86% Progmem Ausnutzung...

Das was hier "zuckt"" hat nun 64%

Ichhabe die Möglichkeit mit einem JTAG "in den Chip" zu schauen. Da 
sieht man das der Bootloader das file schon überträgt und auch am 
gleichen Ende endet wie es ein direktes flashen auch macht.

Es wird die CRC über alle Bytes berechnet, immer von 0 bis 2 Byte VOR 
dem Begin des Bootloaders. Die zwei Bytes enthalten eben die CRC.

Ich nehme immer das HEX File und schicke das in den Bootloader (UART), 
dort wird das Intel Hex Format eingelesen und dann in den flash 
geschrieben, es wird auch überprüft ob die Zeile die übertragen wurde, 
richtig ist. (das Hex Format hat ja auch nochmal pro Zeile eine CRC.

Da stimmt alles, es kommt kein Abbruch.

Schau ich mit dem JTAG dann in den Chip, sieht man das das File drin 
ist...

Aufruf im BOOTLOADER wo verglichen wird...
1
...
2
  call CALC_PM_CRC16        ;Rückgabe: r20 = CRCH / r21 = CRCL
3
  ldi   ZL,Byte1(FIRMCRC*2)    ;CRC aus dem Programmemory laden
4
  ldi   ZH,Byte2(FIRMCRC*2)
5
  lpm wrT0,Z+
6
  lpm wrT1,Z+
7
8
  cp  r21,wrT1
9
  cpc r20,wrT0
10
11
  breq BL_INITIAL_OUT_MSG
12
  sbr fPRG,(1<<fBLActive)      ;beim nächsten Neustart Bootloader aktivieren
13
  sbr fPRG,(1<<fBLPmCrcError)    ;beim nächsten Neustart CRC Error bekannt
14
  jmp BL_RE_INITIAL
15
...



Gruß AVRli...

von Thomas (Gast)


Lesenswert?

AVRli schrieb:
> Ichhabe die Möglichkeit mit einem JTAG "in den Chip" zu schauen. Da
> sieht man das der Bootloader das file schon überträgt und auch am
> gleichen Ende endet wie es ein direktes flashen auch macht.

und wie schon oben erwähnt, was passiert mit den Sektoren zwischen 
Programmende und CRC, werden die zwischen der intialen CRC Berechnung 
und der Berechnung durch den Bootloader verändert?

von AVRli (Gast)


Lesenswert?

Sorry hab ich vergessen zu beantworten.
Das kann ausgeschlossen werden, da die Page die übertragen wird immer 
komplett mit 0xFF initialisiert wird.

Ich gehe jetzt nochmal den Bootloader durch....

Grüße AVRli...

von Karl H. (kbuchegg)


Lesenswert?

AVRli schrieb:
> Sorry hab ich vergessen zu beantworten.
> Das kann ausgeschlossen werden, da die Page die übertragen wird immer
> komplett mit 0xFF initialisiert wird.

Ja, die Page die übertragen wird.
Aber was ist mit den Pages, die nicht übertragen werden, weil sie keiner 
braucht, weil da kein Code drinnen ist?

von AVRli (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Aber was ist mit den Pages, die nicht übertragen werden...

ja die werden gelöscht, der Programmspeicher wird bei einem UPDATE immer 
komplett beschrieben. Das INTEL HEX Format hat dafür ein Kommando wo zu 
einer Adresse gesprungen wird, wo neue Daten, in meinem Fall die letzten 
beiden Bytes, geschrieben werden müssen. Alles was dazwischen liegt also 
zwischen Programm Ende und diesen letzten Bytes wird mit 0xFF 
beschrieben.

Das stimmt auch soweit mein Auge das erfassen kann... also Daten am 
Anfang und am Ende gleich, egal ob direkt geflasht oder über Bootloader 
eingespielt.

Suche weiter...

Gruß AVRli...

von Thomas (Gast)


Lesenswert?

Ich würd mal das image nach dem Flashen über bootloader und jtag 
auslesen und und ein diff drüber laufen lassen.

von AVRli (Gast)


Lesenswert?

GELÖST

Hallo zusammen,

dank Euch hab ich wohl doch den Fehler gefunden! Ich habe im C Quelltext 
einige Variablen abgelegt, die eigentlich erst im Bootloader stehen. 
Fand ich toll um zu sehen ob ich auf die bestimmten Bereiche zugreifen 
kann.

Das ging alles, nun habe ich diese VAR beim erstellen der Firmware NICHT 
auskommentiert und da bin ich drüber gestolpert. Der Bootloader kam mit 
der Info nicht klar, in einem Bereich zu schreiben, wo er nichts zu 
suchen hat und hat sich wohl daran gestört.

Habe die VAR nun auskommentiert und siehe da... es geht wieder!!!

Puhh bin ich froh!!! Danke an alle die mir hier hilfreich zur Seite 
standen!

Gruß AVRli...
...-.-

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.