Also warum bei Xilinx die Unterbrechungsgenerierung und -behandlung im
Vergleich zu Altera zu kompliziert gestaltet ist, verstehe ich auch
nicht, aber mit einen bischen Herumprobieren habe ich es geschafft den
XPS_INTC zu laufen zu bekommen.
Zunächst sollten Ihr sicherstellen, dass Ihr den XPS_INTC im XPS richtig
eingebaut habt und die externen Signal im MHS auch als Interrupts
gekennzeichned sind. Z.B.:
1 | PORT External_IRQ_0 = External_IRQ_0, DIR = I, SIGIS = INTERRUPT, SENSITIVITY = EDGE_RISING
|
Ausserdem, dass die Signal in der Liste des XPS_INTC eingetragen sind:
1 | PORT Intr = External_IRQ_0&External_IRQ_1&External_IRQ_2&External_IRQ_3&External_IRQ_4
|
Sowie der IRQ Port des XPS_INTC mit dem MB verbunden ist:
1 | PORT INTERRUPT = xps_intc_0_Irq
|
In Software muss man ein paar Schritte durchführen, damit die
Interrupt-Behandlung überhaupt erst aktiviert wird. Ich hoffe das hilft
euch.
1) Initialisierung des XPS_INTC
1 | // init interrupt handling device
|
2 | if (XIntc_Initialize(&strInterruptDevice, XPAR_INTC_SINGLE_DEVICE_ID)!=XST_SUCCESS) return XST_FAILURE;
|
2) Verbinden der Interrupt-Servicerountine (InterruptHandler)
1 | // connect PIF interrupt handler
|
2 | if (XIntc_Connect(&strInterruptDevice, XPAR_XPS_INTC_0_MICROBLAZE_EXTERNAL_IRQ_0_INTR,
|
3 | (XInterruptHandler)PIF_InterruptHandler,
|
4 | (void *)&strPIFHandle)!=XST_SUCCESS) return XST_FAILURE;
|
3) Den XPS_INTC starten
1 | // start interrupt device
|
2 | XIntc_Start(&strInterruptDevice, XIN_REAL_MODE);
|
4) Die Interrupt-Behandlung im XPS_INTC für dieses Signal freischalten.
Wichtig: verwendet die #define Symbole und keine Zahlenwerte.
1 | // enable PIF interrupts in XIntc device
|
2 | XIntc_Enable(&strInterruptDevice, XPAR_XPS_INTC_0_MICROBLAZE_EXTERNAL_IRQ_0_INTR);
|
5) Die Interrupt-Generierung im eigenen Device anschalten
1 | // enable PIF interrupts in PIF device
|
2 | PIF_EnableInterrupts(&strPIFHandle);
|
6) Zuletzt noch die Interrupt-Behandlung des MB aktivieren
1 | // enable MB interrupt reception
|
2 | microblaze_enable_interrupts();
|
Nachdem ich all diese Schritte durchgeführt hatte, wurde endlich meine
Service-Routine bei Unterbrechung ausgeführt.