Forum: Mikrocontroller und Digitale Elektronik Auslesen einer AtMega Flash-Page im Bootloader


von Florian V. (floyer)


Lesenswert?

Hallo liebe Leute,

ich schreibe zur Zeit einen Bootloader, mit welchem es möglich ist per 
RS485 den Flash eines AVR-AtMega 88 page-weise zu beschreiben.

Um die geschriebene Page zu verifizieren möchte ich diese nach dem 
Schreiben auslesen und mit meinem Daten-Puffer vergleichen, welcher als 
Pointer vorliegt. Dies soll eventuelle Schreibfehler erkennen.
1
uint8_t *written_data = message;  // To avoid undeclaration
2
uint8_t *flash_data = message +3;
3
4
program_page(write_page, flash_data);
5
6
for(uint8_t word = 0; word < (SPM_PAGESIZE/2); word++){
7
  written_data[0+word*2] = pgm_read_word(write_page + (word*2));
8
}
9
10
if(written_data == flash_data){
11
  response[0] = CORRECT_SIZE;
12
}
13
else response[0] = FAIL_SIZE;

Ich habe nun schon mehrere Stunden damit verbracht den Code zum laufen 
zu bekommen, leider erfolglos.
Über eine übergeordnete Ausgabestruktur wird mir immer "FAIL_SIZE" 
zurückgegeben.

Ich würde mich freuen, wenn sich jemand den Code anschauen und meine 
Fehler finden könnte.

Liebe Grüße

von holger (Gast)


Lesenswert?

>Ich habe nun schon mehrere Stunden damit verbracht den Code zum laufen
>zu bekommen, leider erfolglos.

Wurde die Page beschrieben? Gib die mal per Uart aus.

von Florian V. (floyer)


Lesenswert?

Ja, die Page wurde definitiv geschrieben und müsste auch funktionieren, 
da das per Bootloader aufgespielte Programm (48Pages lang) ohne Probleme 
funktioniert.

von Daniel A. (daniel-a)


Lesenswert?

Florian V. schrieb:
>
> uint8_t *written_data = message;  // To avoid undeclaration

Der kommentar ist hier etwas verwirrend, was ist damit gemeint?

> for(uint8_t word = 0; word < (SPM_PAGESIZE/2); word++){
>   written_data[0+word*2] = pgm_read_word(write_page + (word*2));

uint16_t hat in uint8_t nicht platz. Jedes zweite element von 
written_dat zu überschreiben macht keinen sinn.

Ist write_page vom type uint8_t* oder unsigned char*?
War hier soetwas gemeint? ((uint16_t*)written_data)[word] = 
pgm_read_word(write_page + (word*2));

> if(written_data == flash_data){
Du vergleichst nur Adressen, was zur überprüfung vollkomes sinlos ist.
Ausserdem wird der Pointer written_data nie verändert, der vergleich 
muss false ergeben.

Mach den vergleich in der  Schleife. z. B. so:
1
uint8_t word;
2
for(word = 0; word < (SPM_PAGESIZE/2); word++)
3
  if((uint16_t*)flash_data)[word] != pgm_read_word(write_page + word*2)) 
4
    break;
5
6
if(word == (SPM_PAGESIZE/2))
7
  response[0] = CORRECT_SIZE;
8
else
9
  response[0] = FAIL_SIZE;

von Florian V. (floyer)


Lesenswert?

Daniel A. schrieb:
> Mach den vergleich in der  Schleife. z. B. so:
>
1
> uint8_t word;
2
> for(word = 0; word < (SPM_PAGESIZE/2); word++)
3
>   if((uint16_t*)flash_data)[word] != pgm_read_word(write_page + word*2))
4
>     break;
5
> 
6
> if(word == (SPM_PAGESIZE/2))
7
>   response[0] = CORRECT_SIZE;
8
> else
9
>   response[0] = FAIL_SIZE;
10
> 
11
>

Vielen Dank für die Idee.
Es hat nach ein paar Anpassungen wunderbar funktioniert.

Da mein flash_data ein uint8_t* Pointer ist, habe ich pgm_read_word auf 
uint8_t gecastet und nur um "word" erhöht. Werde es in Byte umbenennen.
1
if(flash_data[word] != (uint8_t)pgm_read_word(write_page + word))

Vielen Dank noch einmal für eure Hilfe.

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.