Şu ana kadarki anlayışım (belirtildiği gibi) sysfs arayüzünün kullanımdan kaldırılmasıdır. Kullanıcı alanında en az iki nispeten yeni C API vardır (WiringPi ve PiGpio'dan özür dileriz). Bir veya her ikisi de libgpiod etiketine sahip gibi görünüyor
Bunlar buster (ancak jessie değil) ile kurulabilir:
apt-get install gpiod libgpiod-dev libgpiod-doc
Streç hakkında emin değilim. Ayrıca hangi API'nin hangi yüklemeleri gerektirdiğinden de emin değilim.
1) İlk C API, veri yapılarını tutan ve gpios ile etkileşim kurmak için sistem çağrıları ile kullanılan /usr/include/linux/gpio.h dosyasına dayanır. Bu yazı Linus Walleij tarafından yazılmıştır. Bu API'nın bir örneği aşağıda gösterilmektedir ve kod yorumlarında belirtilen Linus Walleij tarafından yapılan bir konuşmadan türetilmiştir. Bu API'yı kullanan programların aşağıdaki örnekte gösterilen #includes olması gerekir, ancak herhangi bir kütüphaneyle (AFAIK) derlenmesi gerekmez.
2) İkinci C API'si, kurulumu özetleyen ve işleyen ve bağlamsız okuma, yazma ve diğer işlevlere izin veren basitleştirilmiş bir arabirim sağlayan /usr/include/gpiod.h dosyasına dayanır. Bu Bartosz Golaszewski tarafından sağlanıyor. API'ya giriş, Bartosz tarafından bazı slaytlarda şu adreste bulunabilir:
https://ostconf.com/system/attachments/files/000/001/532/original/Linux_Piter_2018_-_New_GPIO_interface_for_linux_userspace.pdf?1541021776
Bu API'yı kullanan bazı iyi örnekleri şu adreste bulabilirsiniz:
https://framagit.org/cpb/example-programs-using-libgpiod/-/tree/master/
Bu API'yı kullanan programların şunları yapması gerektiğini unutmayın:
#include <gpiod.h>
ve -lgpiod kütüphanesiyle derlenmelidir (örneğin):
gcc -o read-gpio -lgpiod read-gpio.c
Bazı örnekleri başarıyla derledim ve çalıştırdım.
** Bartosz Golaszewski tarafından /usr/include/gpiod.hpp adresine bağlı bir C ++ API'si de bulunmaktadır. C API'sına dayalı bir C ++ sarıcıdır ve C ++ 11 standardına bağlıdır.
Bu API'yı kullanan programlar:
#include <gpiod.hpp>
Bu API'yi kullanmanın bir örneği, C API ile aynı slaytlarda bulunur.
https://ostconf.com/system/attachments/files/000/001/532/original/Linux_Piter_2018_-_New_GPIO_interface_for_linux_userspace.pdf?1541021776
Bu örnekleri derlemek için henüz almadım, ancak henüz keşfetmediğim bir kütüphane katılımı olduğundan şüpheleniyorum.
Aşağıda C API numarası 1'i (Linus Walleij tarafından yazılan) kullanan örnek bir gpio okuma programı verilmiştir. / Dev / gpiochip0 üzerindeki gpio 4'ü tekrar tekrar okur ve değerini yazdırır.
/****
* 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;
}
Şununla derleyin:
gcc -o gpio-read gpio-read.c
Yürütme:
./gpio-read
Bu, her 0.25 saniyede bir spesifik gpio ofsetinin değerini gösterecektir.
/sys/class/gpio/export
, çekirdek hizmetlerini kullanabilmelerine rağmen, donanıma doğrudan eriştikleri için GPIO pinleriyle ETKİLEŞMEZ . Kesinlikle WiringPi ve AFAIK pigpiod doğrudan SoC kayıtlarına erişir.