Forum: Compiler & IDEs pgm_read_word im Bootloader: Falsches Ergebnis


von Robert S. (razer) Benutzerseite


Lesenswert?

Hallo an alle,

Ich schreibe gerade einen Bootloader für einen Atmega1281. Das Schreiben 
des Flashs funktioniert bereits. Nach dem Flashalgorithmus prüfe ich im 
FLash die Adresse 0 (Resetvektor) und schaue ob sie ungleich 0xFFFF 
(unprogrammiert) ist.

Nun zum Problem: Das Auslesen des Flashs funktioniert jedoch beim ersten 
mal nicht. Obwohl im Flash 0x0C94 steht (geprüft mit avrdude) wird 
0xFFFF ausgelesen.

Erst nach einem Power-On Reset wird erkannt, dass 0x0C94 an Adresse 0 
steht und zur Applikation gesprungen.

Weiß jemand woran das liegen kann?

Ist das ein Fehler im Controller?

Danke im  Voraus
lg Robert

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

pgm_read_word_long?

von Robert S. (razer) Benutzerseite


Lesenswert?

Meinst du pgm_read_word_far??

Die funktioniert leider auch nicht.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

boot_rww_enable ?

von Robert S. (razer) Benutzerseite


Lesenswert?

Hallo Martin,

Das habe ich auch schon gedacht. Jedoch mache ich vor dem Flashzugriff 
explizit ein boot_rww_enable()

lg Robert

von Peter D. (peda)


Lesenswert?

Versuch mal:
1
  RAMPZ = 0;
vor dem Lesen.


Peter

von Robert S. (razer) Benutzerseite


Lesenswert?

Danke für den Tipp, hat leider auch nicht geholfen :(

von Robert S. (razer) Benutzerseite


Lesenswert?

Weiß jemand eine Lösung oder weitere Tipps?

von Werner B. (Gast)


Lesenswert?

Die Frage ist "Was willst du lesen?"
Das hier ist ein typische "Glaskugel" Frage.
MAn weiss nichts genaueres aber der Kunde drängt auf Antwort ohne 
detailierte Hintergrundinformationen zu liefern.

Eine weitere mögliche Antwort eines Hellsehers ist:

RAMPZ häng natürlich von der Position der gesuchten Speicherstelle im 
Flash ab.

Üblicherweise würde ich sagen
1
 RAMPZ=1;

da sich (bei eine ATMegas1281) Bootloader ja jenseits der 64KB Grenze 
befindet.

von Peter (Gast)


Lesenswert?

Um die Adresse 0x0000 zu lesen braucht es kein pgm_read_word_far()!

Poste mal den Codeabschnitt, mal schauen wie Du die Adresse liesst und 
auswertest...

Bei mir funktionierts folgendermassen:
1
 unsigned int temp;
2
 temp=pgm_read_word(0x0000);
3
 if (temp!=0xFFFF)      
4
 {
5
   cli();
6
   asm("jmp 0x0000");
7
 }

von Robert S. (razer) Benutzerseite


Lesenswert?

Hallo,

Ich prüfe nach dem programmieren im Bootloader die Adresse 0x0000 im 
Flash, und schaue ob die Applikation programmiert wurde.

Das programmieren funktioniert, nur das Auslesen liefert ein falsches 
Ergebnis (0xFFFF), obwohl der Flash programmiert ist.

Mach ich nun einen Reset, gelange ich wieder in den Bootloader und somit 
wieder in die Statemachine. Wenn ich die durchlaufe, komm ich wieder 
beim Auslesen der Adresse 0x0000 an. Nur wird diesmal der richtige Wert 
aus dem Flash ausgelesen.

So lese ich den Flash aus:
1
        uint16_t flash = pgm_read_word(0);
2
        
3
        if(flash == 0xFFFF)
4
        {
5
          j=0;
6
          PORTG ^= (1 << PG5);
7
          
8
        }
9
        else
10
        {
11
            // Statusbyte ist already set to 0, so we don't need to do this anymore
12
            // Now Reset AVR with Watchdog
13
            wdt_enable(WDTO_15MS);  // 15 ms Timeout  
14
  
15
            while(1);  // Wait until Reset is generated
16
        }

Irgendwo muss noch der Hund begraben sein.

lg Robert

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Und das passiert auch dann noch, wenn du pgm_read_word_far() benutzt?

Kann ich nicht recht glauben.

von Robert S. (razer) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Und das passiert auch dann noch, wenn du pgm_read_word_far() benutzt?
>
> Kann ich nicht recht glauben.

Ja genau. Erzeuge ich einen Reset (es reicht ein normaler über den 
Reset-Pin), und laufe die Bootloader State-Machine einmal durch, 
funktioniert das auslesen.

Langsam bin ich echt ratlos.

Ich habe den Bootloader vom Mega128 auf den Mega1281 angepasst. Dort 
habe kann ich das Problem nicht reproduzieren.

Kann vielleicht jemand das Programm auf einen Mega1281 auspielen? Das 
Programmieren erfolgt über den UART.

lg Robert

von Peter D. (peda)


Lesenswert?

Ich glaub, da gabs für irgendnen AVR nen Bugreport, daß das 1.Lesen nach 
dem Programmieren nicht funktioniert. Den Workaround weiß ich aber nicht 
mehr.

Versuch mal ein 2.Lesen von 0x0000.


Peter

von Robert S. (razer) Benutzerseite


Lesenswert?

Hallo Peter,

das mache ich bereits. Ich lese die Speicherstelle 0 in einer Schleife 
aus
1
while(!newDataAvailable())
2
{
3
  if(j++>20000)
4
  {
5
     uint16_t flash = pgm_read_word(0);
6
7
     if(flash == 0xFFFF)
8
     {
9
       j=0;
10
       PORTG ^= (1 << PG5);
11
     }
12
     else
13
     {
14
       wdt_enable(WDTO_15MS);   
15
       while(1);
16
     }
17
   }
18
   
19
  for(uint8_t i=0;i<50;i++) asm volatile("nop");
20
}

Nachdem ich den Flash programmiert habe, blinkt nur die Led an PG5. 
Sprich das auslesen funktioniert nicht. Leider habe ich bis jetzt keinen 
Workaround gefunden. Auch das Errata Sheet des Mega1281 schweigt 
darüber.

Vielleciht kann mir jemand helfen.

Danke!
lg Robert

von Peter D. (peda)


Lesenswert?

Du kannst ja mal meinen Bootloader probieren.

Ich hatte ihn auf dem ATmega2561 getestet und da lief er.
D.h. da das Verify nach dem Programmieren geklappt hat, muß er ja von 
Adresse 0x00000 das richtige gelesen haben ohne ein Reset dazwischen.

Wenn er bei Dir funktioniert, mußt Du mal ein Minmalprogramm schreiben, 
welches die erste Page programmiert und zurückliest und dann davon das 
Assemblerlistung erzeugen. Dann kann man nachsehen, ob was falsch 
compiliert wurde.


Peter

von Robert S. (razer) Benutzerseite



Lesenswert?

Hallo Peter,

Nach mehreren Tests bin ich drauf gekommen, dass das Programm mit der 
ausgeschalteter Optimierung und Optimierung -O1 funktioniert. Mit -O2 
und -Os habe ich obiges Verhalten.

Im Anhang habe ich den Source Code, sowie alle generierten Assembler 
Listings. Interessant ist, dass bei -Os und -O2 das Auslesen des Flashs 
(LPM Befehle) am Anfang, und nicht in der Endlosschleife sind.

Das blicke ich nun nicht mehr durch. Generiert der Optimizer einen 
falschen Code?

lg Robert

von Mario H. (captorg)


Lesenswert?

Hallo Robert S.,

gibt es eigentlich eine Lösung für das beschriebene Problem? Ich habe 
ein vergleichbares Verhalten mit einem AT90CAN128 - der Schreibvorgang 
funktioniert (verifiziert durch Zurücklesen), der Lesevorgang klappt 
erst nach einem Reset. Den Optimizer kann ich aber leider nicht 
ausschalten, da ich CAN+UART+TWI im Bootloader benutze.

Gruß,
captorg

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.