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