c't

c't-Projekte - Mailinglisten


[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

Re: [ct-bot] Probleme mit dem Bootloader

Absender: Thomas Kregelin
Datum: Mo, 22.10.2007 23:55:59
In-reply-to: <0D6C693E-3EAE-4201-9A19-6B321F17EF88@xxxxxxxxxxxxxxx>
References: <46F96285.8020005@xxxxxx> <2CD3D281-AE62-4FBB-8419-C3EBB7DAFCE9@xxxxxxxxxxxxxxx> <4717C8C2.2030701@xxxxxxx> <0D6C693E-3EAE-4201-9A19-6B321F17EF88@xxxxxxxxxxxxxxx>


Hallo Timo,

der Code kommt nicht von mir. Ich habe das Problem vor einiger Zeit im Forum gepostet und habe die Modifikation als Antwort bekommen.

Ich habe auch erst gedacht, dass dieser Code eigentlich nichts anderes tut als die Interrupts zu deaktivieren - doch genau diese Änderung hat das Problem bei mir behoben.

Man kann aber auch definitiv sagen, dass mit der Operation GICR=0x00 das IVSEL-Bit auf 0 gesetzt wird. Damit ist dann sichergestellt, dass die /Interrupt Vectors Start Address/ auf 0x0002 gesetzt wird. Ist das IVSEL-Bit im Register aus irgendwelchen Gründen auf 1 gesetzt, ruft sich der Bootloader nach einem Interrupt doch selbst auf, oder habe ich das falsch verstanden?


Viele Grüße
Thomas

Timo Sandmann schrieb:
Hallo,

Am 18.10.2007 um 22:57 schrieb Thomas Kregelin:
Hallo Werner.

ich kenne dieses Problem

Mir hat folgendes geholfen:

Suche die Funktion *jump_to_app* in *bootloader.c*

und ersetze diese Funktion durch:

*static void __attribute__ ((always_inline)) jump_to_app(void){
// setze Interrupt Vector Start address auf 0x0002
#ifdef __AVR_ATmega644__
MCUCR = 0x01;
MCUCR = 0x00;
#else
GICR = 0x01;
GICR = 0x00;
#endif

asm("jmp 0x0000"); // Run application code
}*

Mit dieser Modifikation wird sichergestellt, dass der Interruptvektor auf Adresse 0x0002 gesetzt wird.

das stimmt so aber nicht.
GICR = 0x01;
setzt das IVCE-Bit im GICR-Register, was nichts anderes tut, als für 4 CPU-Zyklen die Veränderung des IVSEL-Bits zu erlauben und außerdem Interrupts zu deaktivieren. Um die Vektor-Start-Adresse zu ändern, müsste man zunächst GICR auf 1 setzen und anschließen (innerhalb von 4 Zyklen) auf 2. Das Rücksetzen auf 0 ist außerdem eine No-Operation, weil das nach 4 Zyklen automatisch passiert. Abgesehen davon gibt es auch nichts im Code, das die Vektor-Start-Adresse verschiebt und per default liegt sie bei $0002, wie es sein muss. Das Einzige, was der o.a. Code bewirkt, ist das deaktivieren der Interrupts und ein leicht geändertes Timing (weil die Befehle noch ausgeführt werden).
Wie kommst du denn auf diesen Code?

Ich vermute, dass es sonst zu einer Endlosschleife kommen kann, in der sich der Bootloader ständig selbst aufruft.

Dass sich der Bootloader selbst aufruft, kann nicht sein, es wird ja explizit an Adresse 0 gesprungen, der Bootloader hingegen liegt ganz am Ende des Flash-Speichers. Vermutlich ist das eher ein Compiler-Problem, das so irgendwie umgangen wird. Oder das Int-Deaktivieren hat einen positiven Nebeneffekt, den ich gerade nicht sehe.

Viele Grüße,
Timo



_______________________________________________
ct-bot-entwickler Mailingliste
ct-bot-entwickler@xxxxxxxxxxxxxxxxx
http://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler