querdenker engineering
Schnittstellen und Services

Digitale IOs

Digitale Eingänge und Ausgänge mit libgpiod aus C und Python verwenden.

Digitale IOs werden über /dev/gpiochip* und libgpiod angesprochen. Die GPIO-sysfs-Schnittstelle wird dafür nicht verwendet.

Voraussetzungen

  • Der GPIO-Controller ist im Device Tree aktiviert.
  • Der passende Geräteknoten /dev/gpiochipX ist vorhanden.
  • GPIO-Chip, Line-Name oder Line-Offset sind für das System dokumentiert.
  • Das Programm besitzt die erforderlichen Zugriffsrechte.

Für die Beispiele sind außerdem folgende Versionen festzulegen:

  • libgpiod: [LIBGPIOD-VERSION]
  • Python-Bindings gpiod: [PYTHON-GPIOD-VERSION]
  • C-Compiler/Linker: [C-TOOLCHAIN-VERSION]
gpiodetect
gpioinfo /dev/gpiochip0

Verwende bevorzugt einen stabilen Line-Namen. Ein numerischer Offset ist nur dann geeignet, wenn er für die konkrete Hardwarevariante dauerhaft festgelegt ist.

Ausgang schalten

Beim Request wird die Leitung exklusiv reserviert. Nach dem Ende des Requests gibt die Anwendung die Leitung wieder frei.

#include <gpiod.h>

int main(void)
{
    const unsigned int offset = [GPIO-OFFSET];
    struct gpiod_chip *chip = gpiod_chip_open("/dev/gpiochip0");
    struct gpiod_line_settings *settings = gpiod_line_settings_new();
    struct gpiod_line_config *line_config = gpiod_line_config_new();
    struct gpiod_request_config *request_config = gpiod_request_config_new();
    struct gpiod_line_request *request;
    int result = 1;

    if (!chip || !settings || !line_config || !request_config) {
        goto cleanup;
    }

    gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT);
    gpiod_line_settings_set_output_value(settings, GPIOD_LINE_VALUE_INACTIVE);
    if (gpiod_line_config_add_line_settings(line_config, &offset, 1U, settings) < 0) {
        goto cleanup;
    }

    gpiod_request_config_set_consumer(request_config, "[PROGRAMMNAME]");
    request = gpiod_chip_request_lines(chip, request_config, line_config);
    if (!request) {
        goto cleanup;
    }

    result = gpiod_line_request_set_value(
        request, offset, GPIOD_LINE_VALUE_ACTIVE);
    gpiod_line_request_release(request);

cleanup:
    gpiod_request_config_free(request_config);
    gpiod_line_config_free(line_config);
    gpiod_line_settings_free(settings);
    gpiod_chip_close(chip);
    return result < 0 ? 1 : 0;
}

Eingang lesen

Ein Eingang wird ebenfalls exklusiv angefordert. Für Flankenerkennung werden zusätzlich RISING, FALLING oder BOTH als Edge-Detection konfiguriert.

/* Die Initialisierung entspricht dem Ausgangsbeispiel. */
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_config_add_line_settings(line_config, &offset, 1U, settings);

struct gpiod_line_request *request =
    gpiod_chip_request_lines(chip, request_config, line_config);
if (!request) {
    return 1;
}

const enum gpiod_line_value value =
    gpiod_line_request_get_value(request, offset);
gpiod_line_request_release(request);

Elektrische Eigenschaften

Active-Low, Pull-up/Pull-down, Open-Drain, Debounce und Flankenerkennung werden als LineSettings konfiguriert. Diese Werte müssen zur elektrischen Beschaltung passen und dürfen nicht aus einem Beispiel übernommen werden.

[PLATZHALTER: GPIO-Chips, Line-Namen, Offsets, Pegel, Pull-Widerstände, freigegebene Eingangs-/Ausgangsmodi und libgpiod-Paketnamen]