Forum: Compiler & IDEs AT91SAM7S256 Bootloader: Interrupt Probleme


von Sascha M. (siddhartha)


Lesenswert?

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

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Datenblatt nach "Remap" absuchen. Prinzip: Applikation enthält den Code 
für die Exception Vectors im Flash-Image und kopiert diese beim Startup 
in 0x0 im RAM und "remappt" im Anschluss (zumindest vor Aktivierung IRQ 
etc.).

von Mark .. (mork)


Lesenswert?

Ich denke das hängt damit zusammen, dass der Startup-Code der 
Application davon ausgeht, dass er bei 0x00 anfängt. Beim IRQ versucht 
dieser wahrscheinlich, die Adresse, zu der er springen soll, aus dem VIC 
zu laden. Die Adresse des entsprechenden VIC-Registers errechnet er mit 
dem aktuellen PC-Wert (0x18 für IRQ) und einem Displacement (-0xFF0). 
Jetzt wo der Code aber um 0x4000 verschoben ist, wird die VIC-Adresse 
falsch berechnet und deshalb irgendein Wert aus dem Boodloaderberech 
geladen. Also im Bootloader den alten Code für den IRQ-Vector lassen und 
dann sollte es klappen.

MfG Mark

---------------------------- EDIT ----------------------------
Oh hab gerade bemerkt dass es ein AT91SAM7S ist, das oben gesagte gilt 
aber nur für die LPC2xxx ... Ja, wer lesen kann ist klar im Vorteil ;)

von Sascha M. (siddhartha)


Lesenswert?

Habe den Fehler gefunden :-)

Ich hatte in der C Startup die Zuweisung des FIQ-Handlers ins Source 
Vector Register (SVR) des AIC auskommentiert, da ich am Anfang der 
Entwicklung sicher gehen wollte, dass keine Interrupts ankommen.
Nachdem ich diese Zeile wieder einkommentiert habe, läuft alles genau so 
wie ich mir das Vorstelle.

@Martin Thomas: Das Verschieben der Interrupt-Vektoren ins RAM hatte ich 
mir auch überlegt und werde ich vielleicht auch noch machen. Möchte mal 
sehen, was das für einen Unterschied auf die Interrupt-Behandlungs-Zeit 
macht.

Danke für eure Vorschläge und Hilfe.

von Wur S. (wurschtl)


Lesenswert?

hallo sascha m.,
würde es dir etwas ausmachen, wenn du mir deinen quellcode von deinem 
bootloader zukommen lassen könntest, stehe jetzt vor der großen aufgabe 
einen bootloader für den at91sam7256 zu machen, habe deinen beitrag 
gelesen und bin der meinung du bist schon deutlich weiter als ich,
wäre super wenn du das machen könntest
viele grüße

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.