Forum: Mikrocontroller und Digitale Elektronik Embedded Linux Interrupt Handling


von Michael S. (alteraonlinux)


Lesenswert?

Hallo Zusammen,

ich nutze ein Altera Evaluation Board mit einem Cyclone V SoC FPGA.
Auf dem intergrierten ARM-Cortex läuft ein YOCTO-Linux, Kernel Version 
3.8.0.

Folgende Situation:
Ich möchte in meinem Linux System eine Interrupt-Service-Routine 
schreiben, die auf GPIO Interrupts reagiert.

Verstehe ich das richtig, dass der einzige Weg über ein Kernel Modul 
führt?
Also ich ein Kernel Modul schreibe und dann meine Interrupt Routine auf 
Anwendungsebene laufen lasse?

Ich freue mich über jeden Tipp.

Viele Grüße

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Michael Schäfer schrieb:
> Verstehe ich das richtig, dass der einzige Weg über ein Kernel Modul
> führt?

Normalerweise ja. Userland Programme können dann über /dev, /udev und 
/proc mit dem Modul kommunizieren.

von Michael S. (alteraonlinux)


Lesenswert?

Vielen Dank für die schnelle Antwort.
Dann ist das also wirklich der "richtige" Weg.

Eine Frage habe ich noch,
Im Moment kann ich mit Hilfe von "polling" auftretende Interrupts an 
festen Speicheradressen abfragen.

Linux verwendet ja gpio Nummern. Wie finde ich die zu einer 
Speicheradresse z.B. 0xff200000 dazugehörige gpio nummer heraus?

von Klaus W. (mfgkw)


Lesenswert?

Das würde ich im Datenblatt des Prozessors suchen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Noch ein Tipp: Wenn dir die Hardware noch unbekannt ist, sind /proc und 
/dev dein Freund (sonst auch, aber hier besonders). Dadrin sind 
vielerlei Hinweise auf die Hardware wie z.B. die derzeit benutzten 
Busse, Devices, Interrupts usw. zu finden. Einfach mal mit cat ein paar 
der Nodes anschauen und wenn möglich auch mit deiner 'grossen' Linux Box 
vergleichen.

von Michael S. (alteraonlinux)


Lesenswert?

Dann bedanke ich mich erstmal für die vielen gute Tipps.

Ich bin bei meiner Recherche noch auf UIO-Treiber aufmerksam geworden. 
Das sind vereinfacht gesagt "Kernel-Module" im User Space. Allerdings 
weiß ich nicht so recht, was ich davon halten soll.

@KLaus Wachtler:
Aus meiner Dokumentation werde ich nicht so richtig schlau. Der Bereich 
der mich interessiert liegt bei 0xff70a050 (GPIO2), davon allerdings nur 
bit 13 bis 26.

Im Datenblatt steht für GPIO2 --> gpio nr. 198
gpio nr. 199 ist schon wieder etwas anderem zugeordnet.

Das verstehe ich nicht.

von Konrad (Gast)


Lesenswert?

Je nach Latenzanforderungen kannst Du auch in einem Thread Deiner 
Applikation mit z.B. select darauf warten, dass das sysfs-Device Deines 
Pins lesbar wird. Dann sparst Du das Kernelmodul.

Weiterlesen hier:
https://www.kernel.org/doc/Documentation/gpio/

HTH
Konrad

von Hans Ulli K. (Gast)


Lesenswert?

Michael Schäfer schrieb:
> Dann bedanke ich mich erstmal für die vielen gute Tipps.
>
> Ich bin bei meiner Recherche noch auf UIO-Treiber aufmerksam geworden.
> Das sind vereinfacht gesagt "Kernel-Module" im User Space. Allerdings
> weiß ich nicht so recht, was ich davon halten soll.
>
> @KLaus Wachtler:
> Aus meiner Dokumentation werde ich nicht so richtig schlau. Der Bereich
> der mich interessiert liegt bei 0xff70a050 (GPIO2), davon allerdings nur
> bit 13 bis 26.
>
> Im Datenblatt steht für GPIO2 --> gpio nr. 198
> gpio nr. 199 ist schon wieder etwas anderem zugeordnet.
>
> Das verstehe ich nicht.

GPIO2 kannst du dir als Bank vorstellen.

Habe gerade mal in meinen lokalen linux-master pre. 3.15-rc1 
nachgesehen.
1
find arch/arm/boot/dts/ -name '*cyc*'
2
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
3
arch/arm/boot/dts/socfpga_cyclone5.dtsi
4
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
da sind aber keine GPIOs dabei

Das mit Bits 13-26 ist auch schon seltsam. Kenne jetzt nur 32Bit Breite 
GPIO Bänke..
Und GPIO 198 ??

von Tux (Gast)


Lesenswert?

GPIO198 geht.

Beim Beaglebone Black gibts auch so hohe..

Das liegt daran, dass da irgendwas mit 32 multipliziertz wird und dann 
der normale Offset drauf kommt. Such ma nach BeagleBone und GPIO da 
findeste bestimmt was..

von Michael S. (alteraonlinux)


Lesenswert?

Meine Latenzanforderungen sind hoch, es geht um Echtzeit-Verarbeitung 
:-D

Das mit dem Beaglebone Black war ein sehr guter Hinweis.

Das Signal, welches mich interessiert lautet "GPI6", die physikalische 
Adresse liegt bei 0xff70a050.
Laut Datenblatt liegt der GPIO PIN bei 198 (für die komplette GPIO2 
Bank).

6 * 32 = 192 (geht in die Richtige Richtung)

Mit
# echo 198 > /sys/class/gpio/export
# cd gpio198
# cat value

erthalte ich aber immer '1'. Beim drücken meines Push Buttons sollte da 
aber eine '0' erscheinen.

Wenn ich rausfinde woran es liegt, verrate ich es :-D

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Michael Schäfer schrieb:
> Meine Latenzanforderungen sind hoch, es geht um Echtzeit-Verarbeitung
> :-D

Das ist nicht gut - Linux liefert im Normalfall kein vorhersagbares 
Antwortverhalten auf Interrupts. Allerdings gibt es Mods, die probieren, 
das zu verbessern, wie z.B. RTLinux. Obs noch gepflegt wird? KA, schaus 
dir mal an.
Evtl. hat Altera aber so etwas schon implementiert.

Michael Schäfer schrieb:
> Mit
> # echo 198 > /sys/class/gpio/export
> # cd gpio198
> # cat value

Das ist mir jetzt nicht ganz klar - gibt es denn schon einen gpio 
Treiber in deiner Distri? Wenn ja, solltest du auch ohne touch oder echo 
schon einen Eintrag in /proc zum lesen der gpio haben.

von Michael S. (alteraonlinux)


Lesenswert?

Mein YOCTO-Linux hat einen GPIO-Treiber im Kernel:
1
root@socrates:/lib/modules/3.8.0-00074-g68c58e0/kernel/drivers/gpio# ls
2
gpio-dw.ko  gpio-generic.ko

Die sind auch beide eingebunden via "insmod", aber die scheinen 
Interrupts von einem Push-Button nicht zu interessieren. Da kann ich 
drauf rum drücken wie ich will, es erhöht sich kein Wert. Davon 
abgesehen, kann ich auch keinen der Einträge (siehe unten) meinem 
Push-Button zuordnen.

Ich hatte gehofft, mit dem On-Board interrupt-treiber von Linux arbeiten 
zu können.

1
root@socrates:/# cat /proc/interrupts 
2
           CPU0       CPU1       
3
525:      42650      42598       GIC  twd
4
653:          0          0       GIC  dwc_otg, dwc_otg_hcd:usb1
5
656:          1          0       GIC  dwc_otg, dwc_otg_hcd:usb2
6
667:      47619          0       GIC  dw-mci
7
679:          0          0       GIC  ff705000.spi
8
682:          0          0       GIC  dw_spi0
9
684:          0          0       GIC  dw_spi1
10
686:          4          0       GIC  ffc04000.i2c
11
687:          0          0       GIC  ffc05000.i2c
12
690:       2732          0       GIC  serial
13
697:          9          0       GIC  timer2
14
IPI0:          0          0  CPU wakeup interrupts
15
IPI1:          0          0  Timer broadcast interrupts
16
IPI2:       1340       1498  Rescheduling interrupts
17
IPI3:          0          0  Function call interrupts
18
IPI4:          1          2  Single function call interrupts
19
IPI5:          0          0  CPU stop interrupts
20
Err:          0
21
root@socrates:/#

Weitere Ausgaben:
1
root@socrates:/sys/class/gpio# ls
2
export  gpiochip171  gpiochip198  gpiochip227  unexport
3
root@socrates:/sys/class/gpio#

Device-Tree:
1
root@socrates:/proc/device-tree/soc# ls -l
2
total 0
3
-r--r--r-- 1 root root  4 Jun 28 16:26 #address-cells
4
-r--r--r-- 1 root root  4 Jun 28 16:26 #size-cells
5
dr-xr-xr-x 3 root root  0 Jun 28 16:26 amba
6
dr-xr-xr-x 3 root root  0 Jun 28 16:26 clkmgr@ffd04000
7
-r--r--r-- 1 root root 11 Jun 28 16:26 compatible
8
-r--r--r-- 1 root root  4 Jun 28 16:26 device_type
9
dr-xr-xr-x 3 root root  0 Jun 28 16:26 dwmmc0@ff704000
10
dr-xr-xr-x 2 root root  0 Jun 28 16:26 ethernet@ff700000
11
dr-xr-xr-x 2 root root  0 Jun 28 16:26 ethernet@ff702000
12
dr-xr-xr-x 2 root root  0 Jun 28 16:26 gpio@0xc0000000
13
dr-xr-xr-x 2 root root  0 Jun 28 16:26 gpio@ff708000
14
dr-xr-xr-x 2 root root  0 Jun 28 16:26 gpio@ff709000
15
dr-xr-xr-x 2 root root  0 Jun 28 16:26 gpio@ff70a000
16
dr-xr-xr-x 4 root root  0 Jun 28 16:26 i2c@ffc04000
17
dr-xr-xr-x 2 root root  0 Jun 28 16:26 i2c@ffc05000
18
-r--r--r-- 1 root root  4 Jun 28 16:26 interrupt-parent
19
dr-xr-xr-x 2 root root  0 Jun 28 16:26 l2-cache@fffef000
20
-r--r--r-- 1 root root  4 Jun 28 16:26 name
21
dr-xr-xr-x 2 root root  0 Jun 28 16:26 nand@ff900000
22
-r--r--r-- 1 root root  0 Jun 28 16:26 ranges
23
dr-xr-xr-x 2 root root  0 Jun 28 16:26 rstmgr@ffd05000
24
dr-xr-xr-x 2 root root  0 Jun 28 16:26 serial0@ffc02000
25
dr-xr-xr-x 2 root root  0 Jun 28 16:26 serial1@ffc03000
26
dr-xr-xr-x 3 root root  0 Jun 28 16:26 spi@ff705000
27
dr-xr-xr-x 3 root root  0 Jun 28 16:26 spi@fff00000
28
dr-xr-xr-x 3 root root  0 Jun 28 16:26 spi@fff01000
29
dr-xr-xr-x 2 root root  0 Jun 28 16:26 sysmgr@ffd08000
30
dr-xr-xr-x 2 root root  0 Jun 28 16:26 timer0@ffc08000
31
dr-xr-xr-x 2 root root  0 Jun 28 16:26 timer1@ffc09000
32
dr-xr-xr-x 2 root root  0 Jun 28 16:26 timer2@ffd00000
33
dr-xr-xr-x 2 root root  0 Jun 28 16:26 timer3@ffd01000
34
dr-xr-xr-x 2 root root  0 Jun 28 16:26 timer@fffec600
35
dr-xr-xr-x 2 root root  0 Jun 28 16:26 uio-gpio@ff2000000
36
dr-xr-xr-x 2 root root  0 Jun 28 16:26 usb@ffb00000
37
dr-xr-xr-x 2 root root  0 Jun 28 16:26 usb@ffb40000

So langsam gehen mir die Ideen aus...

von Max G. (l0wside) Benutzerseite


Lesenswert?

Michael Schäfer schrieb:
> Meine Latenzanforderungen sind hoch, es geht um Echtzeit-Verarbeitung
> :-D
>
> Das mit dem Beaglebone Black war ein sehr guter Hinweis.

Der BBB hätte den Vorteil, dass der darauf verbaute AM3358 noch die PRUs 
an Bord hat. Das sind unabhängige µCs auf dem gleichen Die, die 
Echtzeitanwendungen ohne das Betriebssystem behandeln können. Das 
Betriebssystem macht dann wohl nur noch die Parametrierung dieser 
Funktionen.

Wenn du auf das Altera-Board festgelegt bist, hilft dir diese Erkenntnis 
leider auch nicht viel. Wäre ein Softcore im FPGA ggf. eine Option, um 
die harten Echtzeitanforderungen abzuarbeiten?

Max

von Michael S. (alteraonlinux)


Lesenswert?

Ich hab jetzt mal mit Kanonen auf Spatzen geschossen und ein kleines 
Shell-SKript geschrieben, was mit alle GPIO exportiert und deren Wert 
abfragt:
1
#!/bin/bash
2
echo 198 > /sys/class/gpio/export
3
echo 199 > /sys/class/gpio/export
4
echo 200 > /sys/class/gpio/export
5
echo 201 > /sys/class/gpio/export
6
echo 202 > /sys/class/gpio/export
7
echo 203 > /sys/class/gpio/export
8
echo 204 > /sys/class/gpio/export
9
echo 205 > /sys/class/gpio/export
10
echo 206 > /sys/class/gpio/export
11
echo 207 > /sys/class/gpio/export
12
echo 208 > /sys/class/gpio/export
13
echo 209 > /sys/class/gpio/export
14
echo 210 > /sys/class/gpio/export
15
echo 211 > /sys/class/gpio/export
16
echo 212 > /sys/class/gpio/export
17
echo 213 > /sys/class/gpio/export
18
echo 214 > /sys/class/gpio/export
19
echo 215 > /sys/class/gpio/export
20
echo 216 > /sys/class/gpio/export
21
echo 217 > /sys/class/gpio/export
22
echo 218 > /sys/class/gpio/export
23
echo 219 > /sys/class/gpio/export
24
echo 220 > /sys/class/gpio/export
25
echo 221 > /sys/class/gpio/export
26
echo 222 > /sys/class/gpio/export
27
echo 223 > /sys/class/gpio/export
28
echo 224 > /sys/class/gpio/export
29
echo 225 > /sys/class/gpio/export
30
echo 226 > /sys/class/gpio/export
31
cd /sys/class/gpio/gpio198/
32
cat value
33
cd /sys/class/gpio/gpio199/
34
cat value
35
cd /sys/class/gpio/gpio200/
36
cat value
37
cd /sys/class/gpio/gpio201/
38
cat value
39
cd /sys/class/gpio/gpio202/
40
cat value
41
cd /sys/class/gpio/gpio203/
42
cat value
43
cd /sys/class/gpio/gpio204/
44
cat value
45
cd /sys/class/gpio/gpio205/
46
cat value
47
cd /sys/class/gpio/gpio206/
48
cat value
49
cd /sys/class/gpio/gpio207/
50
cat value
51
cd /sys/class/gpio/gpio208/
52
cat value
53
cd /sys/class/gpio/gpio209/
54
cat value
55
cd /sys/class/gpio/gpio210/
56
cat value
57
cd /sys/class/gpio/gpio211/
58
cat value
59
cd /sys/class/gpio/gpio212/
60
cat value
61
cd /sys/class/gpio/gpio213/
62
cat value
63
cd /sys/class/gpio/gpio214/
64
cat value
65
cd /sys/class/gpio/gpio215/
66
cat value
67
cd /sys/class/gpio/gpio216/
68
cat value
69
cd /sys/class/gpio/gpio217/
70
cat value
71
cd /sys/class/gpio/gpio218/
72
cat value
73
cd /sys/class/gpio/gpio219/
74
cat value
75
cd /sys/class/gpio/gpio220/
76
cat value
77
cd /sys/class/gpio/gpio221/
78
cat value
79
cd /sys/class/gpio/gpio222/
80
cat value
81
cd /sys/class/gpio/gpio223/
82
cat value
83
cd /sys/class/gpio/gpio224/
84
cat value
85
cd /sys/class/gpio/gpio225/
86
cat value
87
cd /sys/class/gpio/gpio226/
88
cat value
89
cd /sys/class/gpio/gpio227/
90
cat value

Bei der Ausgabe sehe ich immer lediglich '1'en, egal wie sehr ich auch 
meinen Button betätige.

Frage ich den Status der physikalischen Adresse ab (devmem2.c), sehe ich 
eine Änderung.

Mir scheint, als wäre da was nicht "aktiv" oder eingebunden.

Merkwürdig

von Michael S. (alteraonlinux)


Lesenswert?

Für all Jene, die ebenfalls das EBV SoCrates SoC Evaluation Board der 
Firma EBV haben und wissen wollen, auf welche gpio's der Navigation 
Switch gemappt ist, hier die Lösung:

Links : 195
Rechts: 194
Hoch  : 190
Runter: 191
Push  : 186

Wie man darauf rechnerisch kommt, bleibt mir weiterhin rätselhaft.

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.