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-Funktionen und legen diese in interrupt.c 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:
<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);
}