Hallo zusammen
ich schreibe gerade einen Bootloader für einen AT91SAM7S256, der es mir
(fast) immer erlauben soll eine funktionierende Applikation aus einem
externen Flash zu lesen und ins interne Flash zu kopieren.
Dafür habe ich den Bootloader auf 0x0 gesetzt und die Applikation auf
0x4000 gelinkt. Der Bootloader funktioniert unterdessen eigentlich
einwandfrei, nur der wichtigste Schritt fehlt jetzt noch: der Sprung zur
Applikation.
Ich habe den Sprung folgendermassen in C programmiert:
1 | void (*application)(void) = (void (*)())0x00004000;
|
2 | (*application)();
|
Das klappt auch wunderbar. Das Programm springt nach 0x4000, wo der
Reset-Vektor der Applikation liegt.
Da ich im Bootloader keine Interrupts brauche und damit ich an der
Applikation (abgesehen von der Start-Adresse im Linker) nichts ändern
muss, linke ich die Interrupt-Vektoren einfach an den Anfang der
Applikation. Die Interrupt-Vektoren des Bootloaders habe ich
folgendermassen definiert:
1 | B _bootloader_start
|
2 | B 0x00004004 /* Undefined Instruction */
|
3 | B 0x00004008 /* Software Interrupt */
|
4 | B 0x0000400C /* Prefetch Abort */
|
5 | B 0x00004010 /* Data Abort */
|
6 | B 0x00004014 /* RESERVED */
|
7 | B 0x00004018 /* IRQ */
|
8 | B 0x0000401C /* FIQ */
|
Falls also in der Applikation ein Interrupt ausgelöst wird, sollte der
zum Interrupt-Vektor ab der Adresse 0x0 springen und von dort wird dann
zum entsprechenden Interrupt-Vektor der Applikation gesprungen.
Nur irgendwie funktioniert das nicht. Es kommen nie irgendwelche
Interrupts in der Applikation an.
Deshalb zweifle ich langsam daran, dass meine Idee/Umsetzung überhaupt
funktionieren kann. Kann mir jemand sagen, ob ich einen
Überlegungs-Fehler gemacht habe oder ob das so doch funktionieren
könnte?
Perfekt wäre es, wenn ich an der Applikation nicht wirklich was anpassen
muss, damit ich die auch problemlos nach 0x0 linken kann, wenn ich mal
keinen Bootloader verwenden möchte. Deshalb hab ich mir das mit der
Interrupt-Weiterleitung ausgedacht.
Ich habe auch noch ausprobiert, ob es überhaupt funktioniert, wenn die
Interrupt-Vektoren der Applikation bei 0x0 und die Applikation selber
bei 0x4020 (0x4000 + 32 Bytes, die normalerweise ja durch die
Interrupt-Vektoren besetzt sind) platziert sind und das funktioniert
problemlos.
Wäre froh, wenn mir jemand einen Tipp in die richtige Richtung geben
könnte.
Danke