Auslesen einer AtMega Flash-Page im Bootloader

OP #3653362
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
#3653466
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;
OP #3654307
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren