Template:LIBGPIOD V2 C EXAMPLE: Difference between revisions

From Variscite Wiki
(Created page with "== libgpiod C Application == [{{#var:LIBGPIOD_URL}} libgpiod] provides bindings for C/C++ applications. C++ examples are available in the libgpiod [{{#var:LIBGPIOD_URL}}/tree/bindings/cxx/examples /tree/bindings/cxx/examples ] directory. Below is a simple C application demonstrating how to use the bindings with GPIO4_IO21: '''Makefile:''' all: main.cpp $(CC) $(CCFLAGS) -Og -lgpiod main.c -g -o hello.bin clean: rm -f hello.bin '''main.c''' <pre> #include <gpiod....")
 
No edit summary
Line 6: Line 6:


'''Makefile:'''
'''Makefile:'''
all: main.cpp
LDFLAGS = -lgpiod
$(CC) $(CCFLAGS) -Og -lgpiod main.c -g -o hello.bin
 
clean:
TARGET = main
rm -f hello.bin
SRCS = main.c
 
all: $(TARGET)
 
$(TARGET): $(SRCS)
$(CXX) $(SRCS) $(LDFLAGS) -o $(TARGET)
 
clean:
rm -f $(TARGET)


'''main.c'''
'''main.c'''
<pre>
<pre>
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
/* Minimal example of reading a single line. */
#include <errno.h>
#include <gpiod.h>
#include <gpiod.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>


#define    CONSUMER    "Variscite Demo"
/* Request a line as input. */
static struct gpiod_line_request *request_input_line(const char *chip_path,
    unsigned int offset,
    const char *consumer)
{
struct gpiod_request_config *req_cfg = NULL;
struct gpiod_line_request *request = NULL;
struct gpiod_line_settings *settings;
struct gpiod_line_config *line_cfg;
struct gpiod_chip *chip;
int ret;


int main(int argc, char **argv)
chip = gpiod_chip_open(chip_path);
if (!chip)
return NULL;
 
settings = gpiod_line_settings_new();
if (!settings)
goto close_chip;
 
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
 
line_cfg = gpiod_line_config_new();
if (!line_cfg)
goto free_settings;
 
ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1,
  settings);
if (ret)
goto free_line_config;
 
if (consumer) {
req_cfg = gpiod_request_config_new();
if (!req_cfg)
goto free_line_config;
 
gpiod_request_config_set_consumer(req_cfg, consumer);
}
 
request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
 
gpiod_request_config_free(req_cfg);
 
free_line_config:
gpiod_line_config_free(line_cfg);
 
free_settings:
gpiod_line_settings_free(settings);
 
close_chip:
gpiod_chip_close(chip);
 
return request;
}
 
static int print_value(unsigned int offset, enum gpiod_line_value value)
{
if (value == GPIOD_LINE_VALUE_ACTIVE)
printf("%d=Active\n", offset);
else if (value == GPIOD_LINE_VALUE_INACTIVE) {
printf("%d=Inactive\n", offset);
} else {
fprintf(stderr, "error reading value: %s\n",
strerror(errno));
return EXIT_FAILURE;
}
 
return EXIT_SUCCESS;
}
 
int main(void)
{
{
    unsigned int i, ret, val;
/* Example configuration - customize to suit your situation. */
    struct gpiod_chip *chip;
static const char *const chip_path = "/dev/gpiochip3";
    struct gpiod_line *line;
static const unsigned int line_offset = 21;
    const char * chipname = "gpiochip3";
    const unsigned int line_num = 21;


    chip = gpiod_chip_open_by_name(chipname);
struct gpiod_line_request *request;
    if (!chip) {
enum gpiod_line_value value;
        perror("Open chip failed\n");
int ret;
        goto end;
    }


    line = gpiod_chip_get_line(chip, line_num);
request = request_input_line(chip_path, line_offset, "get-line-value");
    if (!line) {
if (!request) {
        perror("Get line failed\n");
fprintf(stderr, "failed to request line: %s\n",
        goto close_chip;
strerror(errno));
    }
return EXIT_FAILURE;
}


    ret = gpiod_line_request_output(line, CONSUMER, 0);
value = gpiod_line_request_get_value(request, line_offset);
    if (ret < 0) {
ret = print_value(line_offset, value);
        perror("Request line as output failed\n");
        goto release_line;
    }


    /* Blink 5 times */
/* not strictly required here, but if the app wasn't exiting... */
    val = 0;
gpiod_line_request_release(request);
    for (i = 0; i < 5; i++) {
        ret = gpiod_line_set_value(line, val);
        if (ret < 0) {
            perror("Set line output failed\n");
            goto release_line;
        }
        printf("Output %u on line #%u\n", val, line_num);
        sleep(1);
        val = !val;
    }


release_line:
return ret;
    gpiod_line_release(line);
close_chip:
    gpiod_chip_close(chip);
end:
    return 0;
}
}
</pre>
</pre>

Revision as of 17:38, 5 March 2025

libgpiod C Application

[ libgpiod] provides bindings for C/C++ applications. C++ examples are available in the libgpiod [/tree/bindings/cxx/examples /tree/bindings/cxx/examples ] directory.

Below is a simple C application demonstrating how to use the bindings with GPIO4_IO21:

Makefile: LDFLAGS = -lgpiod

TARGET = main SRCS = main.c

all: $(TARGET)

$(TARGET): $(SRCS) $(CXX) $(SRCS) $(LDFLAGS) -o $(TARGET)

clean: rm -f $(TARGET)

main.c

// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>

/* Minimal example of reading a single line. */

#include <errno.h>
#include <gpiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Request a line as input. */
static struct gpiod_line_request *request_input_line(const char *chip_path,
						     unsigned int offset,
						     const char *consumer)
{
	struct gpiod_request_config *req_cfg = NULL;
	struct gpiod_line_request *request = NULL;
	struct gpiod_line_settings *settings;
	struct gpiod_line_config *line_cfg;
	struct gpiod_chip *chip;
	int ret;

	chip = gpiod_chip_open(chip_path);
	if (!chip)
		return NULL;

	settings = gpiod_line_settings_new();
	if (!settings)
		goto close_chip;

	gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);

	line_cfg = gpiod_line_config_new();
	if (!line_cfg)
		goto free_settings;

	ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1,
						  settings);
	if (ret)
		goto free_line_config;

	if (consumer) {
		req_cfg = gpiod_request_config_new();
		if (!req_cfg)
			goto free_line_config;

		gpiod_request_config_set_consumer(req_cfg, consumer);
	}

	request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);

	gpiod_request_config_free(req_cfg);

free_line_config:
	gpiod_line_config_free(line_cfg);

free_settings:
	gpiod_line_settings_free(settings);

close_chip:
	gpiod_chip_close(chip);

	return request;
}

static int print_value(unsigned int offset, enum gpiod_line_value value)
{
	if (value == GPIOD_LINE_VALUE_ACTIVE)
		printf("%d=Active\n", offset);
	else if (value == GPIOD_LINE_VALUE_INACTIVE) {
		printf("%d=Inactive\n", offset);
	} else {
		fprintf(stderr, "error reading value: %s\n",
			strerror(errno));
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}

int main(void)
{
	/* Example configuration - customize to suit your situation. */
	static const char *const chip_path = "/dev/gpiochip3";
	static const unsigned int line_offset = 21;

	struct gpiod_line_request *request;
	enum gpiod_line_value value;
	int ret;

	request = request_input_line(chip_path, line_offset, "get-line-value");
	if (!request) {
		fprintf(stderr, "failed to request line: %s\n",
			strerror(errno));
		return EXIT_FAILURE;
	}

	value = gpiod_line_request_get_value(request, line_offset);
	ret = print_value(line_offset, value);

	/* not strictly required here, but if the app wasn't exiting... */
	gpiod_line_request_release(request);

	return ret;
}