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
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:
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_tflash=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
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_tflash=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_ti=0;i<50;i++)asmvolatile("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
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.