Hi Ich bräuchte mal ne Erklärung zur Interrupt-Programmierung beim Microblaze Mikroprozessor von Xilinx. Aus den Beispielen werde ich nicht schlau, da meine Anwendung - verwendetet wird ein Xilinx Development Board mit 5 Push Buttons, 4 LED's und 4 DIP Switches - von der im Bsp. verwendeten, in der Interruptquelle abweicht. Der benutzte IP-Core (GPIO) zusammen mit dem Interruptcontroller INTTC zusammen mit dem vom Bsp. abgewandelten Code fkt. nicht. Allerdings glaube ich, besitzt die Funktion "XIntc-DeviceInterruptHandler" noch eine besondere Bedeutung. Sie wird aber selbst im Bsp. nicht beachtet. Da die Erklärung der gesamten Problematik jetzt zu weit greifen würde, würde es mir schon weiter helfen, wie die obengenannte Fkt. in den Code einzubringen ist, in Verbindung mit dem eigentlichen InterruptHandler meines Devices. MfG
Das Problem ist, man muss unterscheiden zwischen XPS_INTC und Interrupt Standalone BSP. Der XPS_Intc ist ein IP Block mit dessen Hilfe man 32 Interruptkanäle an den einen Mikroblazeport anbinden kann. Leider bringe ich den Interrupt auch nicht zum Laufen.
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.
Super, das werde ich morgen mal ausprobieren. Ehrlich gesagt ich bin eine GUI-Klicker. Aber langsam werde ich mit den Files auch firm. P.S. - Habe jetzt einen Accout (Helmut)
Moin Helmut, nun das MHS per Hand zu editieren ist bei mir aus der Not heraus geboren. Zur Zeit kann mir mein derzeitiger Kunde keinen Arbeitsplatzrechner mit befriedigender Rechenleistung stellen. Die Ports im XPS zuzuweisen ist dadurch ein sehr zeitintensives Unterfangen. Per Text-Editor geht das deutlich entspannter und schneller. Was ich noch vergessen habe:
1 | #include "xparameters.h" |
2 | #include "xintc.h" |
3 | #include "mb_interface.h" |
Bevor Du gross herumsuchst, hier die Header, welche Du inkludieren solltest.
Hallo, ich habe ein ähnliches Problem. Meine Aufgabe ist es, ein Interrupt-Routine bei ankommenden Daten über die RS232-Schnittstelle (UART) auszulösen. Das Spartan3A-Starter Kit wird von mir verwendet. Mein Code ist folgender: #include "xparameters.h" //parameters with all addresses of the system #include "xmpmc.h" //Multi-Port Memory Controller #include "xuartlite.h" //RS232 #include "stdio.h" #include "xbasic_types.h" #include "xintc.h" //Interrupt Controller #include "mb_interface.h" //needed for Interrups XUartLite UartLite; XIntc Intc; /* The instance of the UartLite Device */ void rs232_interrupt_handler(void*) { printf(" Interrupt Controller Interrrupt_handler aufgerufen " ); return; } void UartLite_RecvHandler (void*) { printf(" UartLite_RecvHandler aufgerufen " ); return; } void UartLite_SendHandler (void*) { printf(" UartLite_SendHandler aufgerufen " ); return; } int main (void) { printf(" Inizialisieng " ); // init interrupt handling device if (XIntc_Initialize(&Intc, XPAR_INTC_SINGLE_DEVICE_ID)!=XST_SUCCESS) return XST_FAILURE; //Verbinden der Interrupt-Servicerountine (InterruptHandler)- connect PIF interrupt handler if (XIntc_Connect(&Intc, XPAR_XPS_INTC_0_RS232_DCE_INTERRUPT_INTR, (XInterruptHandler)rs232_interrupt_handler, (void *)&UartLite)!=XST_SUCCESS) return XST_FAILURE; printf(" Inizialisieng_2 " ); // start XPS Interrupt Controller XIntc_Start(&Intc, XIN_REAL_MODE); //Die Interrupt-Behandlung im XPS_INTC für dieses Signal freischalten. //Wichtig: verwendet die #define Symbole und keine Zahlenwerte.// enable PIF interrupts in XIntc device XIntc_Enable(&Intc, XPAR_XPS_INTC_0_RS232_DCE_INTERRUPT_INTR); printf(" Inizialisieng_3 " ); //Die Interrupt-Generierung im eigenen Device anschalten// enable PIF interrupts in PIF device //PIF_EnableInterrupts(&strPIFHandle); //XUartLite_SetRecvHandler(&UartLite, UartLite_RecvHandler, NULL ); //XUartLite_SetSendHandler(&UartLite, UartLite_SendHandler, NULL ); XUartLite_Initialize(&UartLite, XPAR_RS232_DCE_DEVICE_ID); XUartLite_EnableInterrupt(&UartLite); printf(" Inizialisieng_4 " ); XIntc_mMasterEnable(XPAR_XPS_INTC_0_BASEADDR); //Zuletzt noch die Interrupt-Behandlung des MB aktivieren// enable MB interrupt reception microblaze_enable_interrupts(); printf(" Interrrupt Initialised " ); //loese Interrupt aus u32 *p_register; p_register= (u32*)XPAR_XPS_INTC_0_BASEADDR; //Interrupt Status Register 32 bit *p_register = 0xffffffff;//Überall Interrupts printf("%i", *p_register); return 0; } Weder durch einen ankommenden Datentransfer über RS-232 noch über den p_register zum SW-Interrupt auslösen bekomme ich keine Interrupt service routine aufgerufen (rs232_interrupt_handler). Für die Auskommentierten //XUartLite_SetRecvHandler(&UartLite, UartLite_RecvHandler, NULL ); //XUartLite_SetSendHandler(&UartLite, UartLite_SendHandler, NULL ); bekomme ich auch nicht zum laufen. Ich bedanke mich für eure Hilfe. Viele Grüße Michi
@Michi:
>ich habe ein ähnliches Problem.
1. Dann mach bitte einen neuen Thread raus und verlinke ggf. den alten.
1 | 2. Verwende [c] und [/c] um den Code lesbar darzustellen. |
3. Einen UART-Lite hast Du aber schon mit eingebaut, oder? Kannst Du testweise einen Interrupt per Tastendruck auslösen? Duke
Für aktuelle Versionen des SDK/der Libraries fehlt im obriger (sehr guter Anleitung) noch das einhängen der Service Routine in den Microblaze: > 5) Die Interrupt-Generierung im eigenen Device anschalten// enable PIF > interrupts in PIF device >
1 | PIF_EnableInterrupts(&strPIFHandle); |
* 6a) *
1 | microblaze_register_handler(XIntc_DeviceInterruptHandler, XPAR_XPS_INTC_0_DEVICE_ID) ; |
> 6) Zuletzt noch die Interrupt-Behandlung des MB aktivieren// enable > MB interrupt reception >
1 | microblaze_enable_interrupts(); |
Das mag für diejeningen interessant sein, die mit Hilfe dieses Threads versuchen Ihren IRQ zum laufen zu bringen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.