ควบคุมพิน GPIO จาก C


9

ห้องสมุดส่วนใหญ่ในหลายภาษาโต้ตอบกับ GPIO หมุดผ่าน/sys/class/gpio/export, /sys/class/gpio/import, /sys/class/gpio/gpio10/valueเป็นต้นอย่างไรก็ตามลินุกซ์เคอร์เนลเอกสารรัฐอย่างชัดเจนว่าเป็นวิธีที่มรดกของการทำสิ่งที่

อะไรคือมรดกที่ไม่ใช่วิธีการทำสิ่ง?

ถ้าฉันเข้าใจอย่างถูกต้องในพื้นที่เคอร์เนลฉันจะใช้ฟังก์ชั่นเหล่านี้หรือไดรเวอร์เคอร์เนลมาตรฐานสำหรับงาน GPIO ทั่วไป

ฉันจะใช้อะไรกับพื้นที่ผู้ใช้ มีอินเตอร์เฟส Sysfs สำหรับรุ่นที่ไม่ใช่มรดกหรือไม่?

PS: ฉันรู้เคอร์เนล docs ระบุว่าอินเทอร์เฟซที่ใช้จำนวนเต็มแบบดั้งเดิมแม้ว่าการพิจารณาว่าเลิกใช้แล้วยังคงสามารถใช้งานได้สำหรับเหตุผลความเข้ากันได้ อย่างไรก็ตามฉันไม่สนใจที่จะใช้รหัสเดิม


1
ไลบรารีส่วนใหญ่ไม่โต้ตอบกับหมุด GPIO ผ่านทาง/sys/class/gpio/exportพวกเขาเข้าถึงฮาร์ดแวร์โดยตรงแม้ว่าพวกเขาสามารถใช้บริการเคอร์เนล แน่นอน WiringPi และ AFAIK pigpiod เข้าถึงการลงทะเบียน SoC โดยตรง
Milliways

คำตอบ:


12

sysfslibgpiodได้รับการคัดค้านและได้รับการแทนที่ด้วย

https://www.beyondlogic.org/an-introduction-to-chardev-gpio-and-libgpiod-on-the-raspberry-pi/

ปฏิสัมพันธ์กับมากกว่า/dev/gpiochipx/sys/class/gpio

การปรับปรุงที่ชัดเจนเพียงอย่างเดียว (สำหรับฉัน) คือเหตุการณ์ GPIO ในปัจจุบันมีการประทับเวลา


0

ความเข้าใจของฉันจนถึงขณะนี้คือ (ตามที่ระบุไว้) ส่วนต่อประสาน sysfs นั้นเลิก มี C APIs ที่ค่อนข้างใหม่อย่างน้อยสองรายการในพื้นที่ผู้ใช้ (ขออภัยที่ WiringPi และ PiGpio) หนึ่งหรือทั้งสองดูเหมือนจะมีป้ายกำกับ libgpiod

สามารถติดตั้งบนบัสเตอร์ (แต่ไม่ใช่เจสซี) ด้วย:

apt-get install gpiod libgpiod-dev libgpiod-doc

ไม่แน่ใจเกี่ยวกับการยืด ยังไม่แน่ใจว่า API ใดที่ต้องติดตั้ง

1) C API แรกใช้ /usr/include/linux/gpio.h ซึ่งเก็บโครงสร้างข้อมูลและกำหนดใช้กับการเรียกระบบเพื่อโต้ตอบกับ gpios สิ่งนี้เขียนโดย Linus Walleij ตัวอย่างของ API นี้แสดงอยู่ด้านล่างและมาจากการพูดคุยโดย Linus Walleij ที่ระบุไว้ในความคิดเห็นของรหัส โปรแกรมที่ใช้ API นี้ต้องมี #includes แสดงในตัวอย่างด้านล่าง แต่ไม่จำเป็นต้องรวบรวมกับไลบรารีใด ๆ (AFAIK)

2) C API ที่สองขึ้นอยู่กับ /usr/include/gpiod.h ซึ่งมีอินเทอร์เฟซที่เรียบง่ายที่การตั้งค่าและจัดการ abstracts และช่วยให้การอ่านการเขียนและฟังก์ชั่นอื่น ๆ นี่คือการบำรุงรักษาโดย Bartosz Golaszewski คำแนะนำเกี่ยวกับ API นั้นมีให้ในบางสไลด์โดย Bartosz ซึ่งสามารถดูได้ที่:

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

ตัวอย่างที่ดีที่ใช้ API นี้มีอยู่ที่:

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

โปรดทราบว่าโปรแกรมที่ใช้ API นี้จะต้อง:

#include <gpiod.h>

และถูกคอมไพล์ด้วยไลบรารี -lgpiod (ตัวอย่าง):

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

ฉันรวบรวมและเรียกใช้ตัวอย่างบางส่วนได้สำเร็จ

** มี C ++ API ให้บริการโดย Bartosz Golaszewski ซึ่งขึ้นอยู่กับ /usr/include/gpiod.hpp เป็น C ++ a wrapper ตาม C API และขึ้นอยู่กับมาตรฐาน C ++ 11

โปรแกรมที่ใช้ API นี้จะต้อง:

#include <gpiod.hpp>

ตัวอย่างการใช้ API นี้พบได้ในสไลด์เดียวกับ C API

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

ฉันยังไม่ได้รับตัวอย่างเหล่านี้เพื่อรวบรวม แต่สงสัยว่ามีห้องสมุดที่ฉันยังไม่ได้ค้นพบ


ด้านล่างเป็นตัวอย่างโปรแกรมอ่าน gpio โดยใช้หมายเลข C API 1 จากด้านบน (โปรแกรมที่เขียนโดย Linus Walleij) มันอ่าน gpio 4 ซ้ำ ๆ บน / dev / gpiochip0 และพิมพ์ค่าของมัน

/****
* 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;
}

รวบรวมกับ

gcc -o gpio-read gpio-read.c

ดำเนินการ:

./gpio-read

นี่จะแสดงค่าของ gpio ที่เจาะจงชดเชยทุก 0.25 วินาที


ดังนั้น API คืออะไร ติดตั้งโดยใช้apt-get install gpiodหรือไม่ ต้นแบบฟังก์ชั่นอยู่ภายใน<linux/gpio.h>หรือไม่ มีไฟล์ไลบรารีที่จะเชื่อมโยงกับ?
Dmitry Grigoryev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.