Kontroluj piny GPIO od C


9

Większość bibliotek, w wielu językach, interakcję z pinów GPIO poprzez /sys/class/gpio/export, /sys/class/gpio/import, /sys/class/gpio/gpio10/value, itd. Jednak jądro Linux docs jasno stwierdzić , że jest to sposób spuścizna robi rzeczy.

Jaki jest nieoczywisty sposób robienia rzeczy?

Jeśli dobrze rozumiem w przestrzeni jądra, użyłbym tych funkcji lub standardowych sterowników jądra do typowych zadań GPIO.

Czego miałbym użyć do przestrzeni użytkownika? Czy istnieje interfejs Sysfs dla nie-dziedzictwa?

PS: Wiem, że dokumenty jądra stwierdzają, że starszy interfejs oparty na liczbach całkowitych, choć uważany za przestarzały, jest nadal użyteczny ze względu na kompatybilność. Jednak nie jestem zainteresowany użyciem tego starszego kodu.


1
Większość bibliotek NIE wchodzi w interakcje ze stykami GPIO, /sys/class/gpio/exportponieważ mają bezpośredni dostęp do sprzętu, chociaż MOGĄ korzystać z usług jądra. Z pewnością okres przejściowy WiringPi i AFAIK ma bezpośredni dostęp do rejestrów SoC.
Milliways,

Odpowiedzi:



0

Jak dotąd rozumiem, że (jak już wspomniano) interfejs sysfs jest przestarzały. Istnieją co najmniej dwa stosunkowo nowe interfejsy API C w przestrzeni użytkownika (przepraszam WiringPi i PiGpio). Wydaje się, że jeden lub oba mają etykietę libgpiod

Można je zainstalować na buster (ale nie jessie) za pomocą:

apt-get install gpiod libgpiod-dev libgpiod-doc

Nie jestem pewien co do rozciągania. Nie jestem również pewien, który interfejs API wymaga instalacji.

1) Pierwszy C API opiera się na /usr/include/linux/gpio.h, który przechowuje struktury danych i definiuje używane z wywołaniami systemowymi do interakcji z gpios. To jest napisane przez Linusa Walleij. Przykład tego interfejsu API pokazano poniżej i pochodzi on z wykładu Linusa Walleija wskazanego w komentarzach do kodu. Programy używające tego interfejsu API muszą mieć #include pokazane w poniższym przykładzie, ale nie muszą być kompilowane z żadnymi bibliotekami (AFAIK).

2) Drugi interfejs API języka C opiera się na /usr/include/gpiod.h, który zapewnia uproszczony interfejs, który streszcza konfigurację i obsługuje oraz umożliwia bez kontekstowe odczyty, zapisy i inne funkcje. Utrzymuje to Bartosz Golaszewski. Wprowadzenie do API znajduje się w niektórych slajdach Bartosz, które można znaleźć na:

https://ostconf.com/system/attachments/files/000/001/532/original/Linux_Piter_2018_-_New_GPIO_interface_for_linux_userspace.pdf?1541021776

Kilka dobrych przykładów używania tego interfejsu API można znaleźć na stronie:

https://framagit.org/cpb/example-programs-using-libgpiod/-/tree/master/

Pamiętaj, że programy korzystające z tego interfejsu API muszą:

#include <gpiod.h>

i zostanie skompilowany z biblioteką -lgpiod (na przykład):

gcc -o read-gpio -lgpiod read-gpio.c

Udało mi się skompilować i uruchomić kilka przykładów.

** Istnieje interfejs API C ++ również dostarczony przez Bartosza Golaszewskiego, który zależy od /usr/include/gpiod.hpp. Jest to opakowanie C ++ oparte na C API i zależy od standardu C ++ 11.

Programy korzystające z tego interfejsu API muszą:

#include <gpiod.hpp>

Przykład użycia tego interfejsu API znajduje się na tych samych slajdach co interfejs API C.

https://ostconf.com/system/attachments/files/000/001/532/original/Linux_Piter_2018_-_New_GPIO_interface_for_linux_userspace.pdf?1541021776

Nie udało mi się jeszcze skompilować tych przykładów, ale podejrzewam, że jest jeszcze biblioteka, którą muszę odkryć.


Poniżej znajduje się przykładowy program do odczytu gpio wykorzystujący C API numer 1 z góry (ten autorstwa Linusa Walleij). Wielokrotnie czyta gpio 4 na / dev / gpiochip0 i wypisuje jego wartość.

/****
* gpio-read.c -- example program for reading gpio values using the <linux/gpio.h> C API
* The API consists primarily of data structures used as parameters to system calls.
* Adapted from from a youtube video of Linus Walleij at the Embedded Linux Conference Europe
* GPIO for Engineers and Makers: starting at timestamp 44:11
* For simplicity, there is no error checking.
****/

//Need the gpio API and support for the system calls.
#include <linux/gpio.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>


int main(){


//Opening device and getting file descriptor.
int fd = open("/dev/gpiochip0",O_RDONLY);

//structure for holding chip information
//This structure is defined in /usr/include/linux/gpio.h
struct gpiochip_info cinfo;

//Getting the chip information via the ioctl system call
//GPIO_GET_CHIPINFO_IOCTL defined also in /usr/include/linux/gpio.h
int ret = ioctl(fd,GPIO_GET_CHIPINFO_IOCTL,&cinfo);

//print out the chip information
fprintf(stdout, "GPIO chip: %s, \"%s\", %u GPIO lines\n",
    cinfo.name, cinfo.label, cinfo.lines);

//structure for holding line information.
//structure defined in /usr/include/linux/gpio.h
struct gpioline_info linfo;

//get generic line information from system call
ret = ioctl(fd,GPIO_GET_LINEINFO_IOCTL, &linfo);

//Not sure what this line_offset is, but we specify the gpio number later.
fprintf(stdout,"line %2d: %s\n",linfo.line_offset,linfo.name);

//Reading lines
//Set up some handles for requests and data
struct gpiohandle_request req;
struct gpiohandle_data data;

//Although req and data can read multiple gpios at a time, we'll use just one
//This reads line offset 4, which corresponds to the BCM value in "gpio readall"
req.lineoffsets[0] = 4;
//have to indicate how many lines we are reading.
req.lines = 1;
//Make this an input request
req.flags = GPIOHANDLE_REQUEST_INPUT;

//Optionally give the line a name
strcpy(req.consumer_label, "First Switch");

//Get a line handle. Note that req.fd is provided a handle for the next ioctl. 
int lhfd = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);

//Loop with some delay that keeps checking the input and displaying the value
for(int ii = 0; ii < 1000; ++ii){

    ret = ioctl(req.fd,  GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);

    printf("line %d is %s\n",req.lineoffsets[0], data.values[0] ? "high" : "low");
    //wait 0.25 seconds
    usleep(250000);
}

return 0;
}

Połącz z

gcc -o gpio-read gpio-read.c

Wykonać:

./gpio-read

To pokaże wartość określonego przesunięcia gpio co 0,25 sekundy.


Więc jaki jest interfejs API? Czy jest zainstalowany za pomocą apt-get install gpiod? Czy w środku są prototypy funkcji <linux/gpio.h>? Czy istnieje plik biblioteki, z którym można się połączyć?
Dmitrij Grigoriew
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.