sebring
Posts: 1
Joined: Thu Jun 08, 2023 3:26 pm

GPIO-Zugriff von C-routine aus möglich?

Thu Jun 08, 2023 3:33 pm

Hallo. Ich habe mir eine Bibliothek geschaffen, die mir in C-Programmen erlaubt, mit den GPIO2-GPIO27 Ein/Ausgängen zu hantieren und damit meinen PI 400 für Steuerungszwecke im Amateurfunk einzusetzen. Was mir allerdings noch fehlt: ich brauche einen direkten Zugriff auf die GPPIO im Linux-Kernel von meinem PI 400. In welchem C-Header finde ich die entsprechenden (Kernel-) Funktionen und Symbole? Dann kann ich das vervollständigen und die Bibliothek als CC ins Netz stellen.

Btw: die Bibliothek ist mit GNAT Ada programmiert, also constraint-gesichert und leicht lesbar... :-)

Bratze
Posts: 7
Joined: Thu Jun 08, 2023 11:13 pm

Re: GPIO-Zugriff von C-routine aus möglich?

Fri Jun 09, 2023 6:37 pm

Hallo Sebring,

man kann mit C-Programmen auf die GPIOs zugreifen.

Der Kernel „ kennt” aber die GPIOs nicht.
Entweder musst Du entsprechende Treiber nachinstallieren,
dazu benötigt man aber kein C,
oder Teile einer entsprechenden Library werden mit dem Linker (z.B. via : -lwiringpi) in ein C-Programm eingebunden.

C-Header wäre dann:
#include "wiringpi.h"

Wenn Du es ganz eilig hast, kannst Du auch via MMU direkt auf die GPIO-Register zugreifen, und dann zusätzlich dem Prozess einen eigenen Core zuordnen.

Wozu benötigst Du denn einen direkten Zugriff, wenn Du schon ein funktionierendes Programm hast ?

Gruß

Bratze
Last edited by Bratze on Fri Jun 09, 2023 6:54 pm, edited 2 times in total.

Golem4
Posts: 2
Joined: Tue Aug 29, 2023 2:09 pm

Re: GPIO-Zugriff von C-routine aus möglich?

Tue Aug 29, 2023 2:58 pm

Hallo Sebring,

ich bin auch gerade daran, Direcktzugriff auf die GPIO`s zu bekommen.

Ist eigentlich icht so kompliziert, wenn man die Variablen- und Registerzuweisung hinbekommt, und das mit der Bitverschliebung (Hier Beschrieben: https://www.kampis-elektroecke.de/raspb ... o-zugriff/) kapiert.
Dann must du nur noch die Bitzuordnung im Register (findest du hier: https://iwer.info/article/Elektrotechni ... index.html) verstehen, und du kanst loslegen.
Ich habe nur noch ein Problem mit "open /dev/mem". Bei der Programmausführung wird mir irgentwie der Zugriff verweigert.

Hier ein Programmfragment, was ich zum Ausprobieren geschrieben habe:

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

#define Peripherie_Basis 0x20000000
#define GPIO_Basis (Peripherie_Basis + 0x200000)
#define BLOCK_SIZE 0x03

struct BCM2835_Peripherie {
long GPIO;
unsigned long Adress;
long Memory;
void *Map;
volatile unsigned int *Addr;
};
struct BCM2835_Peripherie *Peripherie;

int main()
{
Peripherie->Memory = open("/dev/mem", O_RDWR | O_SYNC);
if (Peripherie->Memory < 0)
{
printf("Oeffnen von /dev/mem fehlgeschlagen!\n");
return -1;
}
Peripherie->Map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
Peripherie->Memory,
Peripherie->Adress
);
if (Peripherie->Map < 0)
{
printf("Mapping fehlgeschlagen!\n");
return -1;
}
Peripherie->Addr = (volatile unsigned int*)Peripherie->Map;
struct BCM2835_Peripherie GPIO = {GPIO_Basis};
long Status20;
long Status21;
long Status22;

*(GPIO.Addr + 0x03) = 0x01 << 0x18; // GPIO20 (PIN38) auf OUT (Write) setzen
*(GPIO.Addr + 0x07) = 0x01 << 0x07; // GPIO20 (PIN38) auf HIGHT setzen
*(GPIO.Addr + 0x07) &= ~(0x01 << 0x07); // GPIO20 (PIN38) auf LOW setzen (Bitwehrt löschen)
*(GPIO.Addr + 0x03) &= ~(0x07 << 0x18); // GPIO20 (PIN38) auf IN (Read) setzen (Bitmuster löschen)
Status20 = *(GPIO.Addr + 0x0E); // GPIO20 (PIN38) Status Bitmuster auslehsen
Status20 &= (0x01 << 0x07); // GPIO20 (PIN38) Bitmuster-UND-Vergleich
Status20 = Status20 >> 0x07; // GPIO20 (PIN38) Zurück

ist ev. manches überflüssig, und die GPIO -Wehrte müssen auch nicht unbedingt stimmen.

Grße Golem

Return to “Deutsch”