Forum: Compiler & IDEs Leon3 interrupts testen


von Dirk (Gast)


Lesenswert?

hi,

ich wollte die Leon3 Interrupts testen. Dazu habe ich das 
Beispielprogramm von Gaisler compiliert. Die Interrupt handler Methode 
wird aber nie aufgerufen. In einem anderen Forenbeitrag habe ich einige 
Hinweise zu den Interrupts gefunden: 
Beitrag "Re: C-Programmierung für LEON3-Prozessor (StdIO)"

Ich habe versucht das was 900ss geschrieben hat zu berücksichtigen und 
habe die Initialisierungen, auch die des globalen Interrupts in den Code 
einzufügen. Es hat sich nix getan.
Ich hab den Code mal im Original gepostet

Ich debugge im GRMON mit -u um die Uart Ausgabe umzuleiten. Also das ist 
schonmal nicht der Fehler.

Weiß da jemand mehr dazu? Wäre sehr dankbar :)

Gruß Dirk

c-irq.c:
1
/* test program to demonstrate use of interrupts */
2
/* Jiri Gaisler, Gaisler Research, 2001          */
3
4
extern void *catch_interrupt(void func(), int irq);
5
int *lreg = (int *) 0x80000000;
6
7
#ifdef LEON3
8
#define ICLEAR 0x20c
9
#define IMASK  0x240
10
#define IFORCE 0x208
11
#else
12
#define ICLEAR 0x9c
13
#define IMASK  0x90
14
#define IFORCE 0x98
15
#endif
16
enable_irq (int irq) 
17
{
18
19
  lreg[ICLEAR/4] = (1 << irq);  // clear any pending irq
20
  lreg[IMASK/4] |= (1 << irq);  // unmaks irq
21
}
22
23
disable_irq (int irq) { lreg[IMASK/4] &= ~(1 << irq); }  // mask irq
24
25
force_irq (int irq) { lreg[IFORCE/4] = (1 << irq); }  // force irq
26
27
/* NOTE: NEVER put printf() or other stdio routines in interrupt handlers,
28
   they are not re-entrant. This (bad) example is just a demo */
29
30
void irqhandler(int irq)
31
{
32
  printf("this is irq %d\n", irq);
33
}
34
35
36
main()
37
{
38
  catch_interrupt(irqhandler, 10);
39
  catch_interrupt(irqhandler, 11);
40
  catch_interrupt(irqhandler, 12);
41
  enable_irq(10);
42
  enable_irq(11);
43
  enable_irq(12);
44
  force_irq(10);
45
  force_irq(11);
46
  force_irq(12);
47
  force_irq(10);
48
  lreg[IFORCE/4] = (7 << 10); // force irq 10, 11 & 12 simultaneously
49
  
50
}

von 900ss (900ss)


Lesenswert?

Ich weiß nicht, ob es alles ist, aber es fehlt was. In dem von dir 
zitierten Beitrag steht noch:

Zitat:
Es ist noch eine wichtige Funktion im Anfang der Main aufzurufen.
leonbare_init_ticks();
Zitatende.

Sonst sind evtl. die IRQs global abgeschaltet (in der CPU).

In dem kurzen Beispielprogramm dort ist es auch in der main-Funktion 
drin.
Wieso läßt du es weg? Oder ist das Programm oben exakt eine Kopie von 
Jiris Testprogramm? Dann könnte sein, dass catch_interrupt() die IRQs 
auch global einschaltet (weis ich nicht aus dem Kopf).
Dann klemmen evtl. in deinem LEON3 ein paar Bits. Hast du ihn selber 
gehäkelt?

Um zu sehen, was z.B. catch_interrupt() genau macht, kannst du in die 
Sourcen sehen, die es bei Gaisler auf der Homepage gibt. Mußt nach den 
BCC Sourcen suchen, dort gibt es dann auch die Newlib-Sourcen. Da wirst 
du dann fündig.

900ss

von 900ss (900ss)


Lesenswert?

Moin,

ich lese gerade, dass du das enablen der globalen Interrupts gemacht 
hattest. Gestern war nicht viel Zeit, da hab ich das wohl übersehen.

Versuch es mal mit leonbare_init_ticks() falls du es nicht schon getan 
hast. Sonst könntest du noch ein einfaches printf() alleine in der 
main()-funktion probieren um zu testen, dass deine UART-Umleitung auch 
funktioniert.

Es ist für den nächsten auch immer interessant zu erfaren, was denn der 
Fehler war, wenn es funktioniert. :-)

900ss

von Dirk (Gast)


Lesenswert?

hi,

danke für die Antwort.

Den Code den ich gepostet habe ist Original von Gaisler.

Das mit dem leonbare_init_ticks() habe ich schon gemacht. Das hat keine 
Änderung gebracht.
Printf Ausgabe über den Uart funktioniert. Habe ich auch getestet.

Der Leon sollte an sich eigentlich funktionieren. Ich poste hier mal die 
Info sys die ich im Grmon bekomme.
Da ist mir aufgefallen das der Interruptcontroller bei 0x80000200 
anfängt.

02.01:00d   Gaisler Research  Multi-processor Interrupt Ctrl (ver 0x3)
             apb: 80000200 - 80000300

Habe das auch im Code angepasst. Funktioniert trotzdem nicht...:

Grmon> info sys
00.01:003   Gaisler Research  LEON3 SPARC V8 Processor (ver 0x0)
             ahb master 0
01.01:01c   Gaisler Research  AHB Debug JTAG TAP (ver 0x1)
             ahb master 1
02.01:01d   Gaisler Research  GR Ethernet MAC (ver 0x0)
             ahb master 2, irq 12
             apb: 80000f00 - 80001000
             Device index: dev0
             edcl ip 192.168.0.51, buffer 2 kbyte
01.01:006   Gaisler Research  AHB/APB Bridge (ver 0x0)
             ahb: 80000000 - 80100000
02.01:004   Gaisler Research  LEON3 Debug Support Unit (ver 0x1)
             ahb: 90000000 - a0000000
             AHB trace 256 lines, 32-bit bus, stack pointer 0x47fffff0
             CPU#0 win 8, hwbp 2, itrace 256, V8 mul/div, srmmu, lddel 1
                   icache 2 * 4 kbyte, 32 byte/line rnd
                   dcache 2 * 4 kbyte, 16 byte/line rnd
04.01:02e   Gaisler Research  DDR2 Controller (ver 0x0)
             ahb: 40000000 - 50000000
             ahb: fff00100 - fff00200
             32-bit DDR2 : 1 * 128 Mbyte @ 0x40000000, 4 internal banks
                          125 MHz, col 10, ref 7.8 us, trfc 136 ns
05.04:00f   European Space Agency  LEON2 Memory Controller (ver 0x1)
             ahb: 00000000 - 20000000
             ahb: 20000000 - 40000000
             apb: 80000000 - 80000100
             8-bit prom @ 0x00000000
01.01:00c   Gaisler Research  Generic APB UART (ver 0x1)
             irq 2
             apb: 80000100 - 80000200
             baud rate 38461, DSU mode (FIFO debug)
02.01:00d   Gaisler Research  Multi-processor Interrupt Ctrl (ver 0x3)
             apb: 80000200 - 80000300
03.01:011   Gaisler Research  Modular Timer Unit (ver 0x0)
             irq 8
             apb: 80000300 - 80000400
             8-bit scaler, 2 * 32-bit timers, divisor 40
0b.01:01a   Gaisler Research  General purpose I/O port (ver 0x1)
             apb: 80000b00 - 80000c00

von 900ss (900ss)


Lesenswert?

Jetzt sehe ich den Fehler.

Nimm den Original-Source von Jiri (so wie du ihn oben hast) und ergänze 
ihn wie folgt:
1
#define LEON3  // <----------------- hier diese Zeile einfügen
2
#ifdef LEON3

Dann sollte es funktionieren. Du mußt den Zeiger
int *lreg = (int *) 0x80000000;
so lassen.
Die defines geben dann den Offset auf die IRQ-Control-Register an.

900ss

von Dirk (Gast)


Lesenswert?

Vielen Vielen Dank :)

Das war der Fehler!

Seltsam das das niemandem von Gaisler aufgefallen ist!

Gruß Dirk

von 900ss (900ss)


Lesenswert?

Dirk schrieb:
> Seltsam das das niemandem von Gaisler aufgefallen ist!

Das ist nicht seltsam. Das ist so offensichtlich, dass man dort 
festlegen muß, welchen LEON man verwendet, dass sie das so gelassen 
haben.
Nur für LEON2 kann es so bleiben.

Ich habe anfangs auch nur mit der Sonnenbrille rübergeschaut und mir 
wenig Gedanken gemacht zu den defines. Dann fällt das nicht auf.

900ss

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.