Index of /elinux/RPi/RPi-Linux-Einfuehrung

[ICO]NameLast modifiedSizeDescription

[PARENTDIR]Parent Directory  -  
[DIR]802x/2024-04-22 08:47 -  
[TXT]README.html2024-04-22 09:25 957K 
[TXT]README.md2024-04-22 09:25 23K 
[DIR]examples/2024-04-22 08:47 -  
[DIR]images/2024-04-22 08:47 -  

README

1 Einführung in das Linux-Betriebssystem für Raspberry Pi Projekte

(von Björn Hauffe, 2016)

Es wird Vorausgesetzt, dass sich auf dem Host (Entwicklungssystem) eine Debian / Ubuntu / Mint Distribution befindet.

1.1 SSH über Authentifizierung per Public-Keys

Damit man sich nicht ständig mit dem Passwort per SSH Anmelden muss, kann ein Login auch über das Public-Key verfahren erfolgen. Um dies einzurichten muss man dem RPi seinen eigenen Public-Key bekanntmachen.

Die SSH Schlüssel dafür liegen auf dem Linux Entwicklungssystem im Homeverzeichnis in dem ~/.ssh/ (verstecktes) Verzeichnis. Hier liegt der Privat-Key (id_rsa) als auch der Public-Key (id_rsa.pub). Außerdem findet man hier auch die known_hosts Datei in der alle Maschinen eingetragen sind auf die man sich schonmal per SSH eingeloggt hat.

Sollte es hier noch kein Schlüsselpaar geben können diese mit folgendem Kommando erzeugt werden

ssh-keygen -t rsa -b 4096  

Um seinen Public-Key auf dem RPi einzutragen kopiert man den gesamten Inhalt der id_rsa.pub auf die Konsole aus und kopiert ihn anschließend in die Zwischenablage.

user@pc:~$ cat ~/.ssh/id_rsa.pub
....
....

Nun wird sich per SSH in den RPi eingeloggt und der Public-Key in die ~/.ssh/authorized_keys hinzugefügt.

user@pc:~$ ssh pi@pi2
pi@pi2:~$ vi .ssh/authorized_keys
pi@pi2:~$ exit

Wenn man sich jetzt wieder per ssh einloggt wird kein Passwort mehr abgefragt sonder die Authentifizierung automatisch über das Public-Key verfahren durchgeführt. Ebenso wird für das kopieren von Dateien per scp Befehl kein Passwort mehr benötigt.

Mehr über die Möglichkeiten von SSH (z.B. Portforwarding über ssh) findet man im sehr guten Wiki-Artikel von ubuntuusers.de

1.2 Git

Git ist eine moderne Versionsverwaltung um Software dezentral zu versionieren. Mit Git lässt sich außerdem die Zusammenarbeit an einem Softwareprojekt enorm vereinfachen. Es ist im opensource Umfeld mittlerweile zum Standart geworden und wird zum Beispiel für die Entwicklung des Linuxkernel verwendet, wofür es ursprünglich auch entwickelt wurde.

Auch diese Einführung ist mit Hilfe eines Git-Repository entstanden. Die größte Sammlung an opensource Git-Repositorys wird auf Github gehostet. Github stellt seinen Dienst Opensource Projekten kostenlos zur Verfügung.

Eine kleine Einführung und Zusammenfassung der wichtigsten Git-Kommandos findet man hier.

Ein sehr umfrangreiches Buch zu Git gibt es kostenlos unter https://git-scm.com/book/en/v2.

Falls die Git Tools nicht auf dem Entwicklungsrechner installiert sind, können diese mit der Paketverwaltung nachinstalliert werden

sudo apt update && apt install git

1.2.1 Anlegen eines Projektes auf dem Gitlab-Server der Hochschule

Den Server erreicht man zur Zeit unter der Folgenden URL https://r-n-d.informatik.hs-augsburg.de:8080. Hier kann man sich mit seiner RZ-Kennung einloggen. Im Gitlab erstellt man nun ein neues Repository. Dazu geht man auf die Gitlab Seite und klickt oben rechts auf new Project.

Gitlab

Bevor man jetzt das Projekt auf seinen lokalen Rechner klonen kann, muss man noch seine Public-Key in Gitlab hinzufügen. Wie man an den eigenen Public-Key kommt kann im Kapitel SSH über Authentifizierung per Public-Keys nachgesehen werden.

Der Public-Key wird unter den Profile Settings -> SSH Keys mittels Copy & Paste in das Key-Feld eingetragen.

Gitlab-key

Jetzt geht man wieder zurück auf die Startseite des Projektes und kann dort die angegebenen Befehle auf seinem Entwicklungsrechner ausführen um das leere Projekt zu klonen und eine erste Datei anzulegen und die Änderung anschließend wieder auf den Server zurück zu pushen.

Gitlab

1.3 Serielle Konsole des Raspberry Pi

Um sich auch ohne Netzwerkverbindung auf dem RPi remote einloggen zu können, kann man die Serielle-Konsole auf UART0 verwenden. Dazu ist ein USB-UART Adapter wie z.B. PL2303HX von Nöten.

Achtung: Die GPIO/UART Pins haben eine 3,3V Logik und können daher nicht direkt mit einer RS232 Schnittstelle oder Adapter verbunden werden!

Der UART0 liegt beim RPi auf dem Stecker J8 Pin 8 (TX) und Pin 10 (RX)

UART Pins
UART Pins

Mit einem seriell Kommunikations-Program wir z.B. miniterm kann nun auf die serielle Konsole zugegriffen werden.

user@pc:~$ miniterm.py /dev/ttyUSB0 115200

1.4 Netzwerkverbindungen innerhalb der Hochschule

Es gibt mehrere Vorgehensweisen um den RPi in das Hochschulnetzwerk zu bringen und somit dem RPi eine Verbindung ins Internet zu ermöglichen.

1.4.1 Variante 1: Ethernetschnittstelle mit 802.1X Authentifizierung

Der RPi kann mit einem Ethernetkabel an einer in der Hochschule aktiven Netzwerkdose angesteckt werden. Damit der Switch den Port für das Netzwerk freischaltet muss die 802.1X Authentifizierung auf dem RPi eingerichtet werden.

Dazu nimmt man die im Ordner 802x/ zur verfügung gestellte WPA_supplicant Konfigurationsdatei und trägt dort seine RZ-Kennung ein.

802x.conf

#802.x Example from https://help.ubuntu.com/community/Network802.1xAuthentication

# To test your credentials use: 
# wpa_supplicant -c /etc/wpa_supplicant/802x.conf -D wired -i eth0

# Where is the control interface located? This is the default path:
ctrl_interface=/var/run/wpa_supplicant

# Who can use the WPA frontend? Replace "0" with a group name if you
#   want other users besides root to control it.

# There should be no need to chance this value for a basic configuration:
ctrl_interface_group=0

# IEEE 802.1X works with EAPOL version 2, but the version is defaults 
#   to 1 because of compatibility problems with a number of wireless
#   access points. So we explicitly set it to version 2:
eapol_version=2

# When configuring WPA-Supplicant for use on a wired network, we don’t need to
#   scan for wireless access points. See the wpa-supplicant documentation if
#   you are authenticating through 802.1x on a wireless network:
ap_scan=0

network={
        key_mgmt=IEEE8021X
        eap=TTLS MD5
        #hier die RZ-Kennung eintragen 
        identity="RZKENNUNG@hs-augsburg.de"
        anonymous_identity="RZKENNUNG@hs-augsburg.de"
        #hier das RZ Passwort eintragen
        password="YOURPASSWORT"
        phase1="auth=MD5"
        phase2="auth=PAP password=YOURPASSWORT"
        eapol_flags=0
}

Um die Konfiguration nun zu testen ruft man sie mit dem wpa_supplicant Kommando direkt auf.

pi@pi2:~$ sudo wpa_supplicant -c /etc/wpa_supplicant/802x.conf -D wired -i eth0
Successfully initialized wpa_supplicant
eth0: Associated with 01:80:c2:00:00:03
eth0: CTRL-EVENT-EAP-STARTED EAP authentication started
eth0: CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=21
eth0: CTRL-EVENT-EAP-METHOD EAP vendor 0 method 21 (TTLS) selected
eth0: CTRL-EVENT-EAP-PEER-CERT depth=3 subject='/C=DE/O=Deutsche Telekom AG/OU=T-TeleSec Trust Center/CN=Deutsche Telekom Root CA 2'
eth0: CTRL-EVENT-EAP-PEER-CERT depth=3 subject='/C=DE/O=Deutsche Telekom AG/OU=T-TeleSec Trust Center/CN=Deutsche Telekom Root CA 2'
eth0: CTRL-EVENT-EAP-PEER-CERT depth=2 subject='/C=DE/O=DFN-Verein/OU=DFN-PKI/CN=DFN-Verein PCA Global - G01'
eth0: CTRL-EVENT-EAP-PEER-CERT depth=1 subject='/C=DE/O=Fachhochschule Augsburg/OU=Rechenzentrum/CN=FH Augsburg CA - G02/emailAddress=ca@fh-augsburg.de'
eth0: CTRL-EVENT-EAP-PEER-CERT depth=0 subject='/C=DE/O=Fachhochschule Augsburg/OU=Rechenzentrum/CN=HSA8021x.hs-augsburg.de'
eth0: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
eth0: CTRL-EVENT-CONNECTED - Connection to 01:80:c2:00:00:03 completed [id=0 id_str=]
eth0: CTRL-EVENT-EAP-STARTED EAP authentication started
eth0: CTRL-EVENT-CONNECTED - Connection to 01:80:c2:00:00:03 completed [id=0 id_str=]
eth0: CTRL-EVENT-EAP-STARTED EAP authentication started
eth0: CTRL-EVENT-EAP-STARTED EAP authentication started
eth0: CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=21
eth0: CTRL-EVENT-EAP-METHOD EAP vendor 0 method 21 (TTLS) selected
-TeleSec Trust Center/CN=Deutsche Telekom Root CA 2'
-TeleSec Trust Center/CN=Deutsche Telekom Root CA 2'
=DFN-Verein PCA Global - G01'
OU=Rechenzentrum/CN=FH Augsburg CA - G02/emailAddress=ca@fh-augsburg.de'
OU=Rechenzentrum/CN=HSA8021x.hs-augsburg.de'
eth0: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully=1

Wenn nach einiger Zeit EAP authentication completed zu lesen ist, war die 802.1X Authentifizierung erfolgreich.

Nun muss noch die Konfigurationsdatei des Netzwerkdienstes angepasst werden. Dazu geht man in das /etc/network/ Verzeichnis und passt dort die interfaces Datei entsprechend an.

pi@pi2:~$ cd /etc/network/
pi@pi2:~$ sudo cp interfaces interfaces.old
pi@pi2:~$ sudo vi interfaces

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

#iface eth0 inet manual

auto eth0
iface eth0 inet dhcp
wpa-driver wired
wpa-conf /etc/wpa_supplicant/802x.conf

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

allow-hotplug wlan1
iface wlan1 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Die fertig editierte Konfiguration kann man auch in diesem Git-Repo im 802x/ Ordner finden.

Den Netzwerkdienst startet man mit folgendem Befehl neu

pi@pi2:~$ sudo systemctl restart networking

Durch aufrufen des ip Kommandos kann man jetzt überprüfen welche IPv4 & IPv6 Adresse der RPi vom DHCP Server zugewiesen bekommen hat.

pi@pi2:~$ sudo ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:7e:fa:46 brd ff:ff:ff:ff:ff:ff
    inet 141.82.166.61/20 brd 141.82.175.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 141.82.163.232/20 brd 141.82.175.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet6 2001:638:102:26:5dbe:b83d:1692:bc60/64 scope global noprefixroute dynamic 
       valid_lft 2591999sec preferred_lft 604799sec
    inet6 fe80::11cf:67fd:39df:5a38/64 scope link 
       valid_lft forever preferred_lft forever

1.4.2 Variante 2: WLAN Eduroam

TBD

Achtung: Da der RPi jetzt direkt aus dem Internet erreichbar ist, sollte sichergestellt werden das die Standardpasswörter geändert wurden !

Dies kann man mit dem Kommando passwd erledigen.

pi@pi2:~$ sudo passwd pi

1.5 Crosscompiling unter Linux

Unter Crosscompiling versteht man das Übersetzen von Quellcode (C/C++, ect.) für eine andere Prozessor Architektur bzw. für ein anderes Betriebssystem. Das zu übersetzende Programm wird dabei auf dem Entwicklungsrechner (Host) kompiliert mit dem Ziel auf einer anderen Platform (target) gestartet zu werden.

Dieses Vorgehen hat den Vorteil das die Übersetzung von aufwendigen Programmen wesentlich schneller auf einem PC stattfindet als auf einem RPi.

Da das Einrichten einer Cross-Compiling-Toolchain keine Triviale Angelegenheit ist, soll hier kurz gezeigt werden wie man das für sein eigenes Projekt macht.

1.5.1 Einrichten des Entwicklungssystems

Es gibt viele Möglichkeiten die Toolchain zum crosscompiling unter Linux einzurichten. Die einfachste Variante ist mit Sicherheit die gesamte offizielle Toolchain der Raspberry Pi Foundation zu klonen.

Dazu holt man per Git-Kommando das Tools Repository von Github.

user@pc:~$ git clone https://github.com/raspberrypi/tools.git --depth=1

Die Option --depth=1 bewirkt dabei das nicht die gesamte Commit-History geklont wird.

Zum testen der Toolchain wird nun das Einführungs-Repository geklont

user@pc:~$ git clone https://r-n-d.informatik.hs-augsburg.de:8080/bjoern.hauffe/RPi-Linux-Einfuehrung.git

In dem nun neu angelegten Ordner gibt es unter examples eine hello_world.c Programm mit der ein erster Kompiliervorgang versucht werden kann. Dazu wird folgenden Befehl genutzt

user@pc:~ $ gcc RPi-Linux-Einfuehrung/examples/helloworld.c -o helloworld_x86

Das nun übersetzte Programm kann wie folgt ausgeführt werden

user@pc:~$ ./helloworld_x86

Das Programm wird als nächstes per SCP auf den RPi kopiert und sich anschließend per ssh auf dem RPi eingelogt und anschließend ausgeführt

user@pc:~$ scp helloworld_x86 pi@pi2
user@pc:~$ ssh pi@pi2
pi@pi2:~$ ./helloworld_x86

Wie man nun an der Fehlermeldung sieht, funktioniert das Programm auf dem RPi nicht.

Mit dem Kommando file kann untersucht werden um welche art vom Programm es sich handelt.

user@pc:~$ file helloworld_x86
helloworld_x86: ELF 64-bit LSB  executable, 
x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24,
BuildID[sha1]=1f23bd7975b8e53c4df0f65cc297c538928a2d51, not stripped

Das Programm ist im ELF Format für die Architektur x86-64 übersetzt und die Bibliotheken die verwendet werden wurden dynamisch gelinkt.

Mit dem Kommando readelf kann der Header der ELF File angezeigt werden.

user@pc:~$ readelf -h  helloworld_x86
ELF-Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klasse:                            ELF64
Daten:                             2er-Komplement, Little-Endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI-Version:                       0
Typ:                               EXEC (ausführbare Datei)
Maschine:                          Advanced Micro Devices X86-64
Version:                           0x1
Einstiegspunktadresse:               0x400440
Beginn der Programm-Header:          64 (Bytes in Datei)
Beginn der Sektions-header:          4504 (Bytes in Datei)
Flags:                             0x0
Größe dieses Headers:              64 (Byte)
Größe der Programm-Header:         56 (Byte)
Number of program headers:         9
Größe der Sektions-Header:         64 (bytes)
Anzahl der Sektions-Header:        30
Sektions-Header Stringtabellen-Index: 27

Um nun das Helloworld Programm für die ARM-Architektur zu bauen nutzen wir jetzt den Crosscompiler aus der Toolchain

user@pc:~$ tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc RPi-Linux-Einfuehrung/examples/helloworld.c -o helloworld_arm

user@pc:~$ file helloworld_arm
helloworld_arm: ELF 32-bit LSB  executable, 
ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26,
BuildID[sha1]=cdf11632410d224e18045f46e4b56839e7f8df1d, not stripped    

Die erneute Überprüfung mit dem file Kommando zeigt jetzt das der Crosscompiler eine ausführbare Datei für ARM erzeugt hat.

Das kompilierte Programm helloworld_arm wird jetzt auf den Pi kopiert und dort gestartet ohne sich per ssh komplett einzuloggen.

user@pc:~$ scp helloworld_x86 pi@pi2
user@pc:~$ ssh pi2 ./helloworld_arm
Hello  RPi

Um beim Übersetzen nicht immer den gesamten Pfad des Crosscompiler aufrufen zu müssen, kann man den Pfad der PATH Shell-Umgebungsvariable hinzufügen.

user@pc:~$ export PATH=~/linux-einführung/tools/arm-bcm2708/gcc-
linaro-arm-linux-gnueabihf-raspbian/bin/:$PATH

user@pc:~$ echo $PATH
/home/user/linux-einführung/tools/arm-bcm2708/gcc-linaro-arm-
linux-gnueabihf-raspbian/bin/:/usr/local/sbin:/usr/local/bin:/usr/
sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

user@pc:~$ arm-linux-gnueabi-gcc -v
Es werden eingebaute Spezifikationen verwendet.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/bjoern/linux-einführung/tools/arm-bcm2708/
gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-
linux-gnueabihf/4.8.3/lto-wrapper
Ziel: arm-linux-gnueabihf
...
Thread-Modell: posix
gcc-Version 4.8.3 20140106 (prerelease) (crosstool-NG
linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11)

1.5.2 Makefile

Unter Linux werden zum Kompilieren gerne Makefiles eingesetzt. Diese Ermöglichen es ganze Softwareprojekte mit einem einzigen Befehlsaufruf Übersezten zu können.

Eine Typische Makefile hat folgenden Aufbau

CC=gcc
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=helloworld.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=helloworld
all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@
    @echo build for $(EXECUTABLE) completed!

.c.o:
    $(CC) $(CFLAGS) $< -o $@
clean:
    rm $(EXECUTABLE) $(OBJECTS)

In dem examples Verzeichnis liegt eine Makefile die man durch das anpassen der Variablen für sein eigenes Projekt verwenden kann.

Eine Makefile wird einfach mit dem make Kommando benutzt

user@pc:~/RPi-Linux-Einfuehrung/examples $ make 
gcc -c -Wall helloworld.c -o helloworld.o
gcc  helloworld.o -o helloworld
build for helloworld completed!

Um das Verzeichnis wieder von den erzeugten Daten zu bereinigen, gibt es in fast jeder Makefile das clean Ziel. Ziele werden dem Make-Kommando als erstes Argument übergeben.

user@pc:~/RPi-Linux-Einfuehrung/examples $ make clean
rm helloworld helloworld.o
cleanup finished

1.6 GPIO mit Python

Um die GPIOs unter Python anzusprechen kann man die Libary RPi.GPIO nutzen.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, sys, os
from random import random
import RPi.GPIO as GPIO

euid = os.geteuid()
#check if the script is running as root
if euid != 0:
    print "Script not started as root. Running sudo.."
    args = ['sudo', sys.executable] + sys.argv + [os.environ]
    os.execlpe('sudo', *args)

PORT = 12
GPIO.setmode(GPIO.BOARD) #use Board numbering
GPIO.setup(PORT, GPIO.OUT) #config Pin 12 to output

print ("Toggling PIN %s, to cancel press str-c" % PORT)
#turn Pin 12 on and off with random pause time
while True:
    GPIO.output(12, 1)
    time.sleep(random())
    GPIO.output(12, 0)
    time.sleep(random())
    

Das Demo Script wird per scp auf den RPi kopiert und anschließend gestartet.

user@pc:~/RPi-Linux-Einfuehrung/examples $ scp toggle_gpio.py pi2:
user@pc:~/RPi-Linux-Einfuehrung/examples $ ssh pi2
pi@pi2:~$ sudo ./toggle_gpio.py
Toggling PIN 12, to cancel press str-c

1.7 GPIO mit C

Um GPIO Peripherie unter Linux mit C anzusprechen gibt es mehrere Möglichkeiten. Die einfachste ist mit Sicherheit das /sys/ interface des Kernels zu nutzen. Hier steuert man die GPIOs über filedeskriptoren die auf eine “Datei” im /sys Verzeichnis zeigen, wie z.B. /sys/class/gpio/gpio18/value für den GPIO18 bzw. PIN 12. Die etwas elegantere Möglichkeit ist das einsetzen einer Library wie z.B. WiringPi

1.7.1 WiringPi

WiringPi ist eine GPIO Library für den Raspberry Pi die sich stark an der API des wiring Systems vom Arduino Projekt orientiert. Um die wiringPi Library in Aktion zu sehen gibt es ein kleines Demo Programm im examples Ordner.

user@pc:~/RPi-Linux-Einfuehrung/examples $ cat toggle_gpio_wiringpi.c   
...
#include <stdio.h>
#include <wiringPi.h>
 
int main (void)
{
  printf ("Demo wiringPi Library\n") ;
 
  /* init wiringPi Library */
  if (wiringPiSetup () == -1)
    return 1 ;
 
  /* set wiring Pi 1 / BCM_GPIO pin 18 / Board Pin 12 to output mode */
  pinMode (1, OUTPUT) ;
 
  while (1)
  {
    digitalWrite (1, 1) ; // set wiringpi port 1 to high 
    delay (200) ; // sleep for 200 ms
    digitalWrite (1, 0) ; // set wiringpi port 1 to low
    delay (200) ; // sleep for 200 ms
  }
  return 0 ;
}

.

user@pc:~/RPi-Linux-Einfuehrung/examples $ scp toggle_gpio_wiringpi.c   toggle_gpio_wiringpi.c ../wiringPi-b0a60c3.tar.gz pi2:
pi@pi2:~$ ssh pi2
pi@pi2:~$ tar xzf wiringPi-b0a60c3.tar.gz
pi@pi2:~$ cd wiringPi-b0a60c3/
pi@pi2:~/wiringPi-b0a60c3/$ sudo ./build

Mit diesen Schritten ist die wiringPi Library auf dem RPi eingerichtet. Nun kann die Demo Application mit dem gcc kompiliert werden.

pi@pi2:~/wiringPi-b0a60c3/$$ cd ..
pi@pi2:~$ gcc toggle_gpio_wiringpi.c -lwiringPi -o demo_wiringpi
pi@pi2:~$ ./demo_wiringpi
Demo wiringPi Library

pi@pi2:~$ exit

Beim kompilierte ist die Linkeroption -lwiringPi wichtig, damit nach dem Kompilieren das linken mit der wiringpi Library funktioniert. In der Makefile würde man dies dann klassisch an der Stelle LDFLAGS eintragen.

1.7.2 GPIO über Memory Mapping

Die performanteste aber auch eine der schwierigsten Möglichkeiten ist die GPIOs über das Memory Mapping anzusprechen. Hierbei wird der Speicherbereich (Register) des GPIO Controller in den Speicherbereich des Auszuführenden Programms eingeblendet. Änderungen an dieser Stelle werden direkt ohne Systemcalls des Kernels ect. auf die Register des GPIO Controller angewandt.

Im example Ordner gibt es auch hierfür ein Demo Programm zum ausprobieren (mmp_gpio.c). Dies kann man sich z.B. mit dem in Gitlab eingebauten Filebrowser anschauen. Dazu klickt man in der linken Seite auf Files um zum Filebrowser zu gelangen. Hier kann man sich unter examples/mmp_gpio.c das Code-Beispiel zum Memory Mapping anschauen bevor man es mit nachfolgenden Befehlen auf dem Raspberry Pi ausprobiert.

user@pc:~/RPi-Linux-Einfuehrung/examples $ scp mmp_gpio.c pi2:
user@pc:~/RPi-Linux-Einfuehrung/examples $ ssh pi2
pi@pi2:~$ gcc mmp_gpio.c -o mmp_gpio
pi@pi2:~$ ./mmp_gpio

Damit man die LED noch mit bloßem Auge blinken sieht, sind die Pausen zwischem den Ein- bzw. Ausschalten sehr lange gewählt. Wenn man anstatt der LED ein Oszilloskop an den GPIO Port anschließt, kann man die Pausen gänzlich entfernen und das togglen in einer Endlosschleife laufen lassen. Daran kann man dann gut sehen wie schnelle die RPi Hardware den Port togglen lassen kann. Dies kann man dann im vergleich dazu auch mit den anderen Demoprogrammen machen um die unterschiedlichen Geschwindigkeitsverluste durch die einzelnen Abstraktionen zu sehen.