Forum: FPGA, VHDL & Co. Frage zu Nios2 Interrupts


von Ole (Gast)


Lesenswert?

Hallo,
ich bin gerade am Grübeln wozu der Übergabeparameter void*context im 
Funktionsaufruf einer Nios II ISR dient.

In der Doku steht folgendes:

•context is a pointer used to pass context-specific information to the 
ISR, and can point to any ISR-specific information.

Soweit so gut. Jetzt verwundert mich jedoch die eigentliche Nutzung 
dieses Pointers in den von Altera zur Verfügung gestellten Beispielen. 
Hier mal ein Beispiel für einen Button Interrupt:
1
static void handle_button_interrupts(void* context, alt_u32 id)
2
{
3
/* cast the context pointer to an integer pointer. */
4
volatile int* edge_capture_ptr = (volatile int*) context;
5
/*
6
* Read the edge capture register on the button PIO.
7
* Store value.
8
*/
9
*edge_capture_ptr= IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_BASE);
10
11
/* Write to the edge capture register to reset it. */
12
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_BASE, 0);
13
14
/* reset interrupt capability for the Button PIO. */
15
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTONS_BASE, 0xf);
16
17
if ( *edge_capture_ptr == 1)
18
  printf("hello world\n");
19
if ( *edge_capture_ptr == 4)
20
{
21
     IOWR(LEDS_BASE,0, (1 & 0xF));
22
     usleep(1000000);
23
     IOWR(LEDS_BASE,0, (0 & 0xF));
24
}
25
}

Welchen Sinn macht den in diesem Beispiel die folgende Codezeile ???
1
 volatile int* edge_capture_ptr = (volatile int*) context;

Vielen Dank,
Ole

von Harald F. (hfl)


Lesenswert?

Hallo Ole,

ISRs haben ganz allgemein mit dem Problemchen zu tun, dass sie die 
Variablen des Hauptprogramms nicht überschreiben dürfen. In der NIOS HAL 
ist das so gelöst, dass jede ISR zur Laufzeit beim Interrupt-Handler 
registriert werden muss. Für  diese Registrierung definiert man eine 
Struktur mit allen für die ISR benötigten Elementen und legt eine 
Variable davon an. Manchen ISR reicht auch eine einzelne int Variable. 
Den Zeiger auf die Variable gibt man beim Registrieren mit.

Wenn nun der Interrupt eintritt, dass übernimmt zunächst der 
Interrupt-Handler die Kontrolle, der dann die ISR aufruft und ihr den 
Zeiger auf "ihre" Variable übergibt. Im Beispiel ist das nur eine int 
Variable. Und die Zeile

volatile int* edge_capture_ptr = (volatile int*) context;

ist nichts anderes als eine Variablendefinition mit Initialisierung und 
type cast um zu sagen: Die Adresse der volatile int Variablen 
edge_capture_ptr ist gleich dem ersten Aufrufparameter.

Grüße,
Harald

von Ole (Gast)


Lesenswert?

Hallo Harald,
vielen Dank für die super Erklärung! Gruss,
Ole

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.