C से GPIO पिन को नियंत्रित करें


10

अधिकांश पुस्तकालयों में, कई भाषाओं में, GPIO पिन के माध्यम से /sys/class/gpio/export, /sys/class/gpio/importऔर /sys/class/gpio/gpio10/value, आदि के साथ बातचीत करते हैं, हालांकि लिनक्स कर्नेल डॉक्स स्पष्ट रूप से बताते हैं कि चीजें करने का विरासत तरीका है।

चीजों को करने का गैर विरासत तरीका क्या है ?

यदि मैं कर्नेल स्पेस में सही ढंग से समझता हूं तो मैं इन कार्यों या मानक कर्नेल ड्राइवरों का उपयोग आम GPIO कार्यों के लिए करूंगा ।

मैं उपयोगकर्ता स्थान के लिए क्या उपयोग करूंगा? क्या गैर विरासत के लिए एक Sysfs इंटरफ़ेस है?

पुनश्च: मुझे पता है कि कर्नेल डॉक्स यह बताता है कि विरासत में मिला पूर्णांक आधारित इंटरफेस हालांकि माना जाता है कि अभी भी संगतता कारणों के लिए उपयोग करने योग्य है। हालाँकि मुझे उस विरासत कोड का उपयोग करने में कोई दिलचस्पी नहीं है।


1
अधिकांश पुस्तकालयों GPIO पिन के साथ बातचीत नहीं करते /sys/class/gpio/exportहैं, क्योंकि वे सीधे हार्डवेयर तक पहुंचते हैं, हालांकि वे कर्नेल सेवाओं का उपयोग कर सकते हैं। निश्चित रूप से WiringPi और AFAIK पिगोडी सीधे SoC रजिस्टरों तक पहुंचते हैं।
मिलिवेज

जवाबों:


12

sysfsहटा दिया गया है और के साथ बदल दिया गया है libgpiod

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

बातचीत के /dev/gpiochipxबजाय के साथ कर रहे हैं /sys/class/gpio

एकमात्र स्पष्ट सुधार (मेरे लिए) यह है कि GPIO घटनाओं में अब एक समय-स्टैंप है।


0

अब तक मेरी समझ यह है कि (जैसा कि कहा गया है) sysfs इंटरफ़ेस को हटा दिया गया है। उपयोगकर्ता स्थान में कम से कम दो अपेक्षाकृत नए C API हैं (WiringPi और PiGpio के लिए माफी)। एक या दोनों लेबल libgpiod लगता है

उन्हें बस्टर (लेकिन जस्सी नहीं) पर स्थापित किया जा सकता है:

apt-get install gpiod libgpiod-dev libgpiod-doc

खिंचाव के बारे में निश्चित नहीं। यह भी सुनिश्चित नहीं है कि एपीआई को कौन सा इंस्टॉल करना है।

1) पहला C API /usr/include/linux/gpio.h पर निर्भर करता है जो gpios के साथ बातचीत करने के लिए सिस्टम कॉल्स के साथ उपयोग की जाने वाली डेटा संरचना और परिभाषित करता है। यह लिनुस वाल्लेइज द्वारा लिखा गया है। इस एपीआई का एक उदाहरण नीचे दिखाया गया है, और कोड टिप्पणी में इंगित लिनुस वाल्लेइज द्वारा एक बात से लिया गया है। इस API का उपयोग करने वाले कार्यक्रमों में नीचे दिए गए उदाहरण में दिखाए गए #includes होने चाहिए लेकिन उन्हें किसी लाइब्रेरी (AFAIK) के साथ संकलित करने की आवश्यकता नहीं है।

2) दूसरा C API /usr/include/gpiod.h पर निर्भर करता है, जो एक सरलीकृत इंटरफ़ेस प्रदान करता है जो अमूर्त सेटअप और हैंडल करता है और निरर्थक रीड, राइट और अन्य फ़ंक्शन की अनुमति देता है। यह बार्टोज़ गोलास्ज़वेस्की द्वारा बनाए रखा गया है। कुछ स्लाइडों में बार्टोज़ द्वारा एपीआई के लिए एक परिचय दिया गया है जो यहां पाया जा सकता है:

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

इस एपीआई का उपयोग करने वाले कुछ अच्छे उदाहरण यहां देखे जा सकते हैं:

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

ध्यान दें कि इस एपीआई का उपयोग करने वाले कार्यक्रमों को निम्नलिखित होना चाहिए:

#include <gpiod.h>

और -lgpiod पुस्तकालय (उदाहरण के लिए) के साथ संकलित किया जाएगा:

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

मैंने सफलतापूर्वक कुछ उदाहरणों को संकलित और चलाया है।

** एक सी ++ एपीआई भी है जो बार्टोज़ गोलसविस्की द्वारा प्रदान किया गया है जो /usr/include/gpiod.hpp पर निर्भर करता है। यह C ++ पर आधारित C ​​++ का आवरण है और यह C ++ 11 मानक पर निर्भर करता है।

इस एपीआई का उपयोग करने वाले कार्यक्रमों को होना चाहिए:

#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 का उपयोग कर रहा है (एक लाइनस वाल्लीज द्वारा लिखित)। यह बार-बार 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

यह प्रत्येक 0.25 सेकंड में विशिष्ट gpio ऑफसेट का मूल्य दिखाएगा।


तो, एपीआई क्या है? क्या यह स्थापित किया गया है apt-get install gpiod? क्या फ़ंक्शन प्रोटोटाइप अंदर हैं <linux/gpio.h>? क्या किसी लाइब्रेरी फ़ाइल को लिंक करना है?
दिमित्री ग्रिगोरीव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.