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
Meinst du pgm_read_word_far?? Die funktioniert leider auch nicht.
Hallo Martin, Das habe ich auch schon gedacht. Jedoch mache ich vor dem Flashzugriff explizit ein boot_rww_enable() lg Robert
Danke für den Tipp, hat leider auch nicht geholfen :(
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.
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 | }
|
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
Und das passiert auch dann noch, wenn du pgm_read_word_far() benutzt? Kann ich nicht recht glauben.
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.