Die Vector Table in der ARMv7-A Architektur beginnt bei der Speicheradresse 0 und ordnet verschiedene Speicheradressen den unterschiedlichen Exception-Typen zu:
Jede dieser Adressen ist einem spezifischen Exception-Typ zugeordnet und verweist auf die entsprechenden Routinen zur Verarbeitung der Exceptions. Die Einträge in der Tabelle enthalten Verzweigungen zu den jeweiligen Interrupthandlern. Da die Exception Vector Table jedoch nur eine begrenzte Anzahl von Einträgen umfasst, verweist jeder Eintrag auf eine generische Interrupt-Handler-Routine für den entsprechenden Interrupt-Typ. Diese generische Routine muss dann feststellen, welcher spezifische Interrupt tatsächlich aufgetreten ist. Das bedeutet, dass die Vektortabelle selbst lediglich anzeigt, dass ein Interrupt einer bestimmten Art eingetreten ist, jedoch nicht, welcher spezifische Interrupt es genau war.
Es muss eine weitere Quelldatei namens vector.s
erstellt werden, und die entsprechenden Kommandos zum Assemblieren und Linken müssen anschließend in die build.sh
-Datei eingefügt werden.
Die Vektor-Tabelle definiert die Adressen der Handler für verschiedene Ausnahmen. Jeder Eintrag lädt die Adresse des entsprechenden Handlers in das Programmzähler-Register (pc), was einen Sprung zur Handler-Funktion bewirkt:
.section .text
vector:
ldr pc, reset_handler
ldr pc, undefined_handler
ldr pc, swi_handler
ldr pc, prefetch_handler
ldr pc, data_handler
ldr pc, unused_handler
ldr pc, irq_handler
ldr pc, fiq_handler
Jeder Handler wird als ein Wort definiert, das auf die entsprechende Funktion zeigt:
reset_handler: .word reset
undefined_handler: .word hang
swi_handler: .word hang
prefetch_handler: .word hang
data_handler: .word hang
unused_handler: .word hang
irq_handler: .word irq
fiq_handler: .word hang
Die reset-Funktion ist der Einstiegspunkt nach einem System-Reset:
reset:
b start
Reset
führt einen unbedingten Sprung (b) zur start-Funktion aus, die den eigentlichen Initialisierungsprozess übernimmt.
Die irq-Funktion behandelt IRQ-Interrupts, in unserem Fall werden wir nur einen Timerinterrupt implementieren:
@ Timerinterrupt
irq:
cpsid i @ interrupts ausmaskieren
push {r0-r3, r12, lr} @ speichere Prozessorstatus
bl irq_handler_ext @ springe zu Extended Interrupt Handler
pop {r0-r3, r12, lr} @ prozessorstatus wiederherstellen
sub pc, lr, #4 @ returnadresse anpassen
r0
bis r3
, r12
und das Link-Register
(lr) auf dem Stack, um den aktuellen Zustand zu bewahren.irq_handler_ext
auf, welche die spezifische Interrupt-Verarbeitung (des Timer-Interrupts) übernimmt.Die hang
-Funktion wird für nicht implementierte oder unerwartete Ausnahmen verwendet. Sie sorgt dafür, dass das System in einer Endlosschleife verbleibt:
@ Dauerschleife bei nicht implementierten Interrupts
hang:
wfi
b hang
zurück | Hauptmenü | weiter |