Forum: Mikrocontroller und Digitale Elektronik boot_page_write funktioniert nicht


von Nu langt mir dat aber (Gast)


Lesenswert?

Hallo Forum,

Hänge seit Tagen fest.

Ich versuche einen Bootloader zu schreiben aufgrund einiger Beispiele.

Die Daten-Blöcke werden korrekt übertragen, auch die Adressen, und 
jeweils vom Zielsystem korrekt bestätigt mit '\r'.

Der ganze Schreibvorgang läuft reibungslos durch, aber wenn ich den 
AVR-Flash hernach mit AVR-Studio und AVRISP auslese, stehen im ganzen 
Speicherbereich ab Adresse 0 bis zum Beginn des Bootloaders nur 'FF'en.

boot_page_write schreibt die Daten nicht in den Speicher.

Kennt jemand das Problem?

Ach ja, ich verwede die 2010er-WINAVR-Version (hab aber auch die 2006er 
getestet, gleiches Ergebnis), und einen ATMega168.

Hier mal meine Blockloader-Routine:
1
unsigned char BlockLoad(unsigned int size, ADDR_T *address)
2
{
3
    unsigned int data;
4
    ADDR_T tempaddress;
5
6
    (*address) <<= 1; // Convert address to bytes temporarily.
7
    tempaddress = (*address);  // Store address in page.
8
9
    do
10
  {
11
        data = recchar();
12
        data |= (recchar() << 8);
13
      
14
        boot_page_fill(*address,data);
15
        (*address)+=2; // Select next word in memory.
16
        size -= 2; // Reduce number of bytes to write by two.
17
  } 
18
  while(size); // Loop until all bytes written.
19
20
  boot_page_write(tempaddress);
21
  boot_spm_busy_wait();
22
  boot_rww_enable();
23
24
    (*address) >>= 1; // Convert address back to Flash words again.
25
    return '\r'; // Report programming OK
26
}
Danke für Eure Hilfe.

spätnächtliche Grüsse Dirk

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Da die Funktion immer ein '\r' zeichen zurück gibt, sagt das nichts 
darüber aus, ob irgendetwas funktioniert hat. Vermutlich ist dass 
Problem eher in recchar.

Prüfe mal ob immer 0xff ankommt:
1
unsigned char BlockLoad(unsigned int size, ADDR_T *address)
2
{
3
unsigned int data,check=0xffff;
4
ADDR_T tempaddress;
5
(*address) <<= 1; // Convert address to bytes temporarily.
6
tempaddress = (*address); // Store address in page.
7
do
8
{
9
data = recchar();
10
data |= (recchar() << 8);
11
check &= data;
12
boot_page_fill(*address,data);
13
(*address)+=2; // Select next word in memory.
14
size -= 2; // Reduce number of bytes to write by two.
15
} while(size); // Loop until all bytes written.
16
boot_page_write(tempaddress);
17
boot_spm_busy_wait();
18
boot_rww_enable();
19
(*address) >>= 1; // Convert address back to Flash words again.
20
return check==0xffff?0:'\r';

Wenn der rückgabewert jetzt 0 ist, hat recchar immer 0xff zurückgegeben.

von Nu langt mir dat aber (Gast)


Lesenswert?

Danke Daniel für die Antwort, hab das gecheckt, es liegt nicht am 
recchar.

Auch die Adress-Hi- bzw. Lo-Bytes habe ich per return gecheckt.

Ich kann auch direkt data einen Wert zuweisen oder den Adressen, es wird 
nichts geschrieben.

von Michael N. (betonmicha)


Lesenswert?

Die Funktion boot_page_write(tempaddress); wird doch bestimmt einen 
Rückgabewert haben. Schreibt die Funktion überhaupt oder kommt ein Error 
zurück, den du ignorierst?

von Sepp (Gast)


Lesenswert?

Löscht Du auch irgendwo die Page?
1
      boot_page_erase(Addresse);
2
      while(boot_rww_busy()) boot_rww_enable(); 
3
4
  
5
      for(fc8 = 0; fc8 < SPM_PAGESIZE; fc8 += 2) 
6
        {
7
        boot_page_fill(fc8+BlockStartAddr, *(uint *)(Data_0_PtrTX + fc8));
8
        }  
9
        
10
      // Write page.
11
      boot_page_write(Addresse);
12
      while(boot_rww_busy()) boot_rww_enable();

von Nu langt mir dat aber (Gast)


Lesenswert?

Das mit dem Rückgabewert muss ich mir anschauen.

Zum Testen habe ich ganz minimalistisch direkt ins main geschrieben:

  unsigned int size=256;
  unsigned int adr=0;

  boot_page_erase(adr);
  boot_spm_busy();
  boot_rww_enable();

  do
  {

        boot_page_fill(adr,0xEEEE);

    adr+=2; // Select next word in memory.
        size -= 2; // Reduce number of bytes to write by two.

  }
  while(size); // Loop until all bytes written.

  boot_page_write(0);
  boot_spm_busy();
  boot_rww_enable();

  sendchar('Y');
  for(;;);

Das müsste doch in den ersten Block ab Adresse 0 EE's schreiben. Macht 
es aber leider nicht.

Das Y kommt an.

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.