Beispiel Timer-Interrupt (PI4): Unterschied zwischen den Versionen
Aus C und Assembler mit Raspberry
KKeine Bearbeitungszusammenfassung |
KKeine Bearbeitungszusammenfassung |
||
| Zeile 47: | Zeile 47: | ||
b hang | b hang | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Im Anschluss müssen wir beschreiben, was passieren soll, wenn der Interrupt ausgelöst wurde: | Im Anschluss müssen wir beschreiben, was passieren soll, wenn der Interrupt ausgelöst wurde: | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
| Zeile 90: | Zeile 91: | ||
Dies speichern wir als vecotor.s in unser Projekt ab. | Dies speichern wir als vecotor.s in unser Projekt ab. | ||
Als nächstes müssen wir noch Interrupts Initialisieren. Dazu erstellen wir C- | Wir verwenden den GIC-400 Kontroller. | ||
Als nächstes müssen wir noch Interrupts Initialisieren. Dazu erstellen wir eine C-Funktion und legen diese in interrupt.c ab: | |||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
void Interrupt_Initialize (void) | void Interrupt_Initialize (void) | ||
Version vom 25. Juli 2025, 11:07 Uhr
Nun versuchen wir, einen Timer-Interrupt zu erstellen und verwenden eine Vector-Tabelle, wie diese zuvor beschrieben wurde. Wir verzichten zunächst auf die Gleitkomma-Unterstützung.
Wir verwenden die Vectortabelle aus der vorigen Beschreibung. Unterstützen allerdings nur "IRQs". Andere Ausnahmen werden in eine Dauerschleife versetzt:
.align 11
.globl VectorTable
VectorTable:
// Vektoren für EL1t (Current Exception Level SP_el0)
.align 7
b hang // Synchronous Exception
.align 7
b IRQStub // IRQ - Normal Interrupt
.align 7
b hang // FIQ - Fast Interrupt
.align 7
b hang // SError - System Error
// Vektoren für EL1h (Current Exception Level SP_el1)
.align 7
b hang // Synchronous Exception
.align 7
b IRQStub // IRQ - Normal Interrupt
.align 7
b hang // FIQ - Fast Interrupt
.align 7
b hang // SError - System Error
// Vektoren für EL0 64-bit Modus
.align 7
b hang // Synchronous EL0 (64-bit)
.align 7
b hang // IRQ EL0 (64-bit)
.align 7
b hang // FIQ EL0 (64-bit)
.align 7
b hang // Error EL0 (64-bit)
// Vektoren für EL0 32-bit Modus
.align 7
b hang // Synchronous EL0 (32-bit)
.align 7
b hang // IRQ EL0 (32-bit)
.align 7
b hang // FIQ EL0 (32-bit)
.align 7
b hang // Error EL0 (32-bit)
hang:
wfe // spare CPU cycles
b hang
Im Anschluss müssen wir beschreiben, was passieren soll, wenn der Interrupt ausgelöst wurde:
.globl IRQStub
IRQStub:
stp x29, x30, [sp, #-16]!
stp x27, x28, [sp, #-16]!
stp x25, x26, [sp, #-16]!
stp x23, x24, [sp, #-16]!
stp x21, x22, [sp, #-16]!
stp x19, x20, [sp, #-16]!
stp x17, x18, [sp, #-16]!
stp x15, x16, [sp, #-16]!
stp x13, x14, [sp, #-16]!
stp x11, x12, [sp, #-16]!
stp x9, x10, [sp, #-16]!
stp x7, x8, [sp, #-16]!
stp x5, x6, [sp, #-16]!
stp x3, x4, [sp, #-16]!
stp x1, x2, [sp, #-16]!
str x0, [sp, #-16]!
bl irq_dispatch //Springe zur Auswertung
ldr x0, [sp], #16
ldp x1, x2, [sp], #16
ldp x3, x4, [sp], #16
ldp x5, x6, [sp], #16
ldp x7, x8, [sp], #16
ldp x9, x10, [sp], #16
ldp x11, x12, [sp], #16
ldp x13, x14, [sp], #16
ldp x15, x16, [sp], #16
ldp x17, x18, [sp], #16
ldp x19, x20, [sp], #16
ldp x21, x22, [sp], #16
ldp x23, x24, [sp], #16
ldp x25, x26, [sp], #16
ldp x27, x28, [sp], #16
ldp x29, x30, [sp], #16
eret
Dies speichern wir als vecotor.s in unser Projekt ab.
Wir verwenden den GIC-400 Kontroller. Als nächstes müssen wir noch Interrupts Initialisieren. Dazu erstellen wir eine C-Funktion und legen diese in interrupt.c ab:
void Interrupt_Initialize (void)
{
write32(0,GICD_CTLR);
// Enable interrupt 30 (falls < 32, dann ISENABLER0)
write32 ((1 << TIMER_IRQ_ID),GICD_ISENABLER0);
write32 (0xA0A0A0A0,GICD_IPRIORITYR7); // Priority
write32 (0x01010101,GICD_ITARGETSR7); // CPU0
write32(1,GICD_CTLR);
write32(0xff,GICC_PMR);
write32(1,GICC_CTLR);
}