Forum: FPGA, VHDL & Co. Interrupt mit Xilinx EDK/SDK 10.1 und VirtexII/Pro


von Gast (Gast)


Lesenswert?

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

von helmut (Gast)


Lesenswert?

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.

von Jannulis T. (tembridis)


Lesenswert?

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.

von Helmut L. (somo)


Lesenswert?

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)

von Jannulis T. (tembridis)


Lesenswert?

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.

von Michi (Gast)


Lesenswert?

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

von Duke Scarring (Gast)


Lesenswert?

@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

von Chris (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.