Skip to contentSkip to conversation

replace tool examples with use case examples

PATCH In review Kent Gibson 3 participants 14 messages Jun 23, 2023 GPIO

lore
Share & tools
lore
#0 lore raw

cover replace tool examples with use case examples

This series is the continuation of providing a set of use case based examples for libgpiod. The focus of this series is replacement of the examples replicating the the tools with examples that minimally cover the use case that each tool addresses.

The mapping from tool to use case is:

  gpiodetect  ->  get_chip_info
  gpiofind    ->  find_line_by_name
  gpioget     ->  get_multiple_line_values
  gpioinfo    ->  get_line_info
  gpiomon     ->  watch_multiple_line_values
  gpionotify  ->  watch_line_info
  gpioset     ->  toggle_multiple_line_values

Also added a watch_line_rising example to demonstrate getting events from only one edge rather than both, so another gpiomon sub-case.

The rust bindings had a couple of additional examples, gpio_events and gpio_threaded_info_events.

gpio_threaded_info_events is an example of using one thread to generate info change events that are observed by another thread. This is borrowed from test cases and has no other practical application, but the reconfiguring component inspired the reconfigure_input_to_output example. That provides an example of reconfiguring a requested line, and is provided for all languages, not just rust.

gpio_events is an example of how borrowed buffered events must be cloned before the event buffer can be reused. This was simplified and renamed buffered_event_lifetimes. As I write this I realise it may also be applicable to other languages - as an example of using gpiod_edge_event_copy(). Maybe provide those in v2, or a subsequent series?

The series is split into 8 parts. For each language there is a patch that provides some consistency cleanups to make the existing examples more consistent with each other, with the examples in other languages, and with the examples to follow. There are also a few minor bug fixes that didn't seem sufficiently serious to warrant a separate patch.

The second patch for each language replaces the old tool examples with the new use case based examples.

Cheers,
Kent.

Kent Gibson (8):
core: examples: consistency cleanups
core: examples: add more use case examples
bindings: cxx: examples: consistency cleanup
bindings: cxx: examples: replace tools examples with use case examples
bindings: python: examples: consistency cleanup
bindings: python: examples: replace tools examples with use case
examples
bindings: rust: examples: consistency cleanup
bindings: rust: examples: replace tools examples with use case
examples

 bindings/cxx/examples/.gitignore              |  16 +-
 bindings/cxx/examples/Makefile.am             |  42 ++---
 .../cxx/examples/async_watch_line_value.cpp   |   8 +-
 bindings/cxx/examples/find_line_by_name.cpp   |  42 +++++
 bindings/cxx/examples/get_chip_info.cpp       |  27 ++++
 bindings/cxx/examples/get_line_info.cpp       |  39 +++++
 bindings/cxx/examples/get_line_value.cpp      |  28 ++--
 .../cxx/examples/get_multiple_line_values.cpp |  40 +++++
 bindings/cxx/examples/gpiodetectcxx.cpp       |  30 ----
 bindings/cxx/examples/gpiofindcxx.cpp         |  32 ----
 bindings/cxx/examples/gpiogetcxx.cpp          |  40 -----
 bindings/cxx/examples/gpioinfocxx.cpp         |  61 -------
 bindings/cxx/examples/gpiomoncxx.cpp          |  65 --------
 bindings/cxx/examples/gpionotifycxx.cpp       |  55 -------
 bindings/cxx/examples/gpiosetcxx.cpp          |  53 ------
 .../examples/reconfigure_input_to_output.cpp  |  56 +++++++
 bindings/cxx/examples/toggle_line_value.cpp   |  16 +-
 .../examples/toggle_multiple_line_values.cpp  |  63 ++++++++
 bindings/cxx/examples/watch_line_info.cpp     |  49 ++++++
 bindings/cxx/examples/watch_line_rising.cpp   |  64 ++++++++
 bindings/cxx/examples/watch_line_value.cpp    |  12 +-
 .../examples/watch_multiple_line_values.cpp   |  60 +++++++
 bindings/python/examples/Makefile.am          |  18 ++-
 .../python/examples/async_watch_line_value.py |  15 +-
 bindings/python/examples/find_line_by_name.py |  37 +++++
 bindings/python/examples/get_chip_info.py     |  20 +++
 bindings/python/examples/get_line_info.py     |  29 ++++
 bindings/python/examples/get_line_value.py    |  13 +-
 .../examples/get_multiple_line_values.py      |  29 ++++
 bindings/python/examples/gpiodetect.py        |  15 --
 bindings/python/examples/gpiofind.py          |  20 ---
 bindings/python/examples/gpioget.py           |  29 ----
 bindings/python/examples/gpioinfo.py          |  28 ----
 bindings/python/examples/gpiomon.py           |  26 ---
 bindings/python/examples/gpionotify.py        |  21 ---
 bindings/python/examples/gpioset.py           |  36 -----
 bindings/python/examples/helpers.py           |  15 --
 .../examples/reconfigure_input_to_output.py   |  39 +++++
 bindings/python/examples/toggle_line_value.py |  34 ++--
 .../examples/toggle_multiple_line_values.py   |  47 ++++++
 bindings/python/examples/watch_line_info.py   |  23 +++
 bindings/python/examples/watch_line_rising.py |  31 ++++
 bindings/python/examples/watch_line_value.py  |  19 ++-
 .../examples/watch_multiple_line_values.py    |  43 +++++
 bindings/rust/libgpiod/examples/Makefile.am   |  21 +--
 .../examples/buffered_event_lifetimes.rs      |  58 +++++++
 .../libgpiod/examples/find_line_by_name.rs    |  29 ++++
 .../rust/libgpiod/examples/get_chip_info.rs   |  22 +++
 .../rust/libgpiod/examples/get_line_info.rs   |  37 +++++
 .../rust/libgpiod/examples/get_line_value.rs  |   4 +-
 .../examples/get_multiple_line_values.rs      |  29 ++++
 .../rust/libgpiod/examples/gpio_events.rs     |  88 ----------
 .../examples/gpio_threaded_info_events.rs     | 132 ---------------
 bindings/rust/libgpiod/examples/gpiodetect.rs |  30 ----
 bindings/rust/libgpiod/examples/gpiofind.rs   |  36 -----
 bindings/rust/libgpiod/examples/gpioget.rs    |  45 ------
 bindings/rust/libgpiod/examples/gpioinfo.rs   |  97 -----------
 bindings/rust/libgpiod/examples/gpiomon.rs    |  74 ---------
 bindings/rust/libgpiod/examples/gpionotify.rs |  53 ------
 bindings/rust/libgpiod/examples/gpioset.rs    |  63 --------
 bindings/rust/libgpiod/examples/gpiowatch.rs  |  53 ------
 .../examples/reconfigure_input_to_output.rs   |  42 +++++
 .../libgpiod/examples/toggle_line_value.rs    |  17 +-
 .../examples/toggle_multiple_line_values.rs   |  55 +++++++
 .../rust/libgpiod/examples/watch_line_info.rs |  32 ++++
 .../libgpiod/examples/watch_line_rising.rs    |  44 +++++
 .../libgpiod/examples/watch_line_value.rs     |  10 +-
 .../examples/watch_multiple_line_values.rs    |  46 ++++++
 examples/.gitignore                           |   9 ++
 examples/Makefile.am                          |  35 +++-
 examples/async_watch_line_value.c             |   6 +-
 examples/find_line_by_name.c                  | 111 +++++++++++++
 examples/get_chip_info.c                      |  40 +++++
 examples/get_line_info.c                      |  56 +++++++
 examples/get_line_value.c                     |  11 +-
 examples/get_multiple_line_values.c           | 119 ++++++++++++++
 examples/reconfigure_input_to_output.c        | 152 ++++++++++++++++++
 examples/toggle_line_value.c                  |  17 +-
 examples/toggle_multiple_line_values.c        | 136 ++++++++++++++++
 examples/watch_line_info.c                    |  72 +++++++++
 examples/watch_line_rising.c                  | 129 +++++++++++++++
 examples/watch_line_value.c                   |   6 +-
 examples/watch_multiple_line_values.c         | 140 ++++++++++++++++
 83 files changed, 2289 insertions(+), 1352 deletions(-)
 create mode 100644 bindings/cxx/examples/find_line_by_name.cpp
 create mode 100644 bindings/cxx/examples/get_chip_info.cpp
 create mode 100644 bindings/cxx/examples/get_line_info.cpp
 create mode 100644 bindings/cxx/examples/get_multiple_line_values.cpp
 delete mode 100644 bindings/cxx/examples/gpiodetectcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiofindcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiogetcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpioinfocxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiomoncxx.cpp
 delete mode 100644 bindings/cxx/examples/gpionotifycxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiosetcxx.cpp
 create mode 100644 bindings/cxx/examples/reconfigure_input_to_output.cpp
 create mode 100644 bindings/cxx/examples/toggle_multiple_line_values.cpp
 create mode 100644 bindings/cxx/examples/watch_line_info.cpp
 create mode 100644 bindings/cxx/examples/watch_line_rising.cpp
 create mode 100644 bindings/cxx/examples/watch_multiple_line_values.cpp
 create mode 100755 bindings/python/examples/find_line_by_name.py
 create mode 100755 bindings/python/examples/get_chip_info.py
 create mode 100755 bindings/python/examples/get_line_info.py
 create mode 100755 bindings/python/examples/get_multiple_line_values.py
 delete mode 100755 bindings/python/examples/gpiodetect.py
 delete mode 100755 bindings/python/examples/gpiofind.py
 delete mode 100755 bindings/python/examples/gpioget.py
 delete mode 100755 bindings/python/examples/gpioinfo.py
 delete mode 100755 bindings/python/examples/gpiomon.py
 delete mode 100755 bindings/python/examples/gpionotify.py
 delete mode 100755 bindings/python/examples/gpioset.py
 delete mode 100644 bindings/python/examples/helpers.py
 create mode 100755 bindings/python/examples/reconfigure_input_to_output.py
 create mode 100755 bindings/python/examples/toggle_multiple_line_values.py
 create mode 100755 bindings/python/examples/watch_line_info.py
 create mode 100755 bindings/python/examples/watch_line_rising.py
 create mode 100755 bindings/python/examples/watch_multiple_line_values.py
 create mode 100644 bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs
 create mode 100644 bindings/rust/libgpiod/examples/find_line_by_name.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_chip_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_multiple_line_values.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpionotify.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
 create mode 100644 bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs
 create mode 100644 bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_rising.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_multiple_line_values.rs
 create mode 100644 examples/find_line_by_name.c
 create mode 100644 examples/get_chip_info.c
 create mode 100644 examples/get_line_info.c
 create mode 100644 examples/get_multiple_line_values.c
 create mode 100644 examples/reconfigure_input_to_output.c
 create mode 100644 examples/toggle_multiple_line_values.c
 create mode 100644 examples/watch_line_info.c
 create mode 100644 examples/watch_line_rising.c
 create mode 100644 examples/watch_multiple_line_values.c
Signature · 1 line
2.41.0
#1 lore raw

PATCH 1/8 core: examples: consistency cleanups

A collection of minor cleanups to make the examples more consistent and ease the addition of more examples:
- reformat Makefile.am to simplify adding more examples
- add line offset to value output
- remove commas from edge event output
- replace while(1) with for (;;)
- fix a typo in Makefile.am
- fix an error handling goto in toggle_line_value.c

---
 examples/Makefile.am              |  8 ++++++--
 examples/async_watch_line_value.c |  6 +++---
 examples/get_line_value.c         | 11 +++++++----
 examples/toggle_line_value.c      | 17 ++++++++++-------
 examples/watch_line_value.c       |  6 +++---
 5 files changed, 29 insertions(+), 19 deletions(-)
examples/Makefile.am +6 -2
index 4ad124b..55dfe39 100644
@@ -6,12 +6,16 @@ AM_CFLAGS += -Wall -Wextra -g -std=gnu89
 
 LDADD = $(top_builddir)/lib/libgpiod.la
 
-bin_PROGRAMS = async_watch_line_value get_line_value toggle_line_value watch_line_value
+noinst_PROGRAMS = \
+	async_watch_line_value \
+	get_line_value \
+	toggle_line_value \
+	watch_line_value
 
 async_watch_line_value_SOURCES = async_watch_line_value.c
 
 get_line_value_SOURCES = get_line_value.c
 
-toggle_line_valuer_SOURCES = toggle_line_value.c
+toggle_line_value_SOURCES = toggle_line_value.c
 
 watch_line_value_SOURCES = watch_line_value.c
examples/async_watch_line_value.c +3 -3
index 3292dda..f35fb1a 100644
@@ -74,7 +74,7 @@ static const char *edge_event_type_str(struct gpiod_edge_event *event)
 {
 	switch (gpiod_edge_event_get_event_type(event)) {
 	case GPIOD_EDGE_EVENT_RISING_EDGE:
-		return "Rising ";
+		return "Rising";
 	case GPIOD_EDGE_EVENT_FALLING_EDGE:
 		return "Falling";
 	default:
@@ -117,7 +117,7 @@ int main(void)
 	pollfd.fd = gpiod_line_request_get_fd(request);
 	pollfd.events = POLLIN;
 
-	while (1) {
+	for (;;) {
 		ret = poll(&pollfd, 1, -1);
 		if (ret == -1) {
 			fprintf(stderr, "error waiting for edge events: %s\n",
@@ -134,7 +134,7 @@ int main(void)
 		for (i = 0; i < ret; i++) {
 			event = gpiod_edge_event_buffer_get_event(event_buffer,
 								  i);
-			printf("offset: %d, type: %s, event #%ld\n",
+			printf("offset: %d  type: %-7s  event #%ld\n",
 			       gpiod_edge_event_get_line_offset(event),
 			       edge_event_type_str(event),
 			       gpiod_edge_event_get_line_seqno(event));
examples/get_line_value.c +7 -4
index 08e263a..1de9901 100644
@@ -64,12 +64,12 @@ close_chip:
 	return request;
 }
 
-static int print_value(enum gpiod_line_value value)
+static int print_value(unsigned int offset, enum gpiod_line_value value)
 {
 	if (value == GPIOD_LINE_VALUE_ACTIVE)
-		printf("Active\n");
+		printf("%d=Active\n", offset);
 	else if (value == GPIOD_LINE_VALUE_INACTIVE) {
-		printf("Inactive\n");
+		printf("%d=Inactive\n", offset);
 	} else {
 		fprintf(stderr, "error reading value: %s\n",
 			strerror(errno));
@@ -97,7 +97,10 @@ int main(void)
 	}
 
 	value = gpiod_line_request_get_value(request, line_offset);
-	ret = print_value(value);
+	ret = print_value(line_offset, value);
+
+	/* not strictly required here, but if the app wasn't exiting... */
+	gpiod_line_request_release(request);
 
 	return ret;
 }
examples/toggle_line_value.c +10 -7
index 63d7fb9..6e522d6 100644
@@ -40,7 +40,7 @@ request_output_line(const char *chip_path, unsigned int offset,
 	ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1,
 						  settings);
 	if (ret)
-		goto free_settings;
+		goto free_line_config;
 
 	if (consumer) {
 		req_cfg = gpiod_request_config_new();
@@ -72,12 +72,15 @@ static enum gpiod_line_value toggle_line_value(enum gpiod_line_value value)
 						    GPIOD_LINE_VALUE_ACTIVE;
 }
 
-static void print_value(enum gpiod_line_value value)
+static const char * value_str(enum gpiod_line_value value)
 {
 	if (value == GPIOD_LINE_VALUE_ACTIVE)
-		printf("Active\n");
-	else
-		printf("Inactive\n");
+		return "Active";
+	else if (value == GPIOD_LINE_VALUE_INACTIVE) {
+		return "Inactive";
+	} else {
+		return "Unknown";
+	}
 }
 
 int main(void)
@@ -97,8 +100,8 @@ int main(void)
 		return EXIT_FAILURE;
 	}
 
-	while (1) {
-		print_value(value);
+	for (;;) {
+		printf("%d=%s\n", line_offset, value_str(value));
 		sleep(1);
 		value = toggle_line_value(value);
 		gpiod_line_request_set_value(request, line_offset, value);
examples/watch_line_value.c +3 -3
index d962f20..879b09b 100644
@@ -73,7 +73,7 @@ static const char *edge_event_type_str(struct gpiod_edge_event *event)
 {
 	switch (gpiod_edge_event_get_event_type(event)) {
 	case GPIOD_EDGE_EVENT_RISING_EDGE:
-		return "Rising ";
+		return "Rising";
 	case GPIOD_EDGE_EVENT_FALLING_EDGE:
 		return "Falling";
 	default:
@@ -112,7 +112,7 @@ int main(void)
 		return EXIT_FAILURE;
 	}
 
-	while (1) {
+	for (;;) {
 		/* Blocks until at least one event is available. */
 		ret = gpiod_line_request_read_edge_events(request, event_buffer,
 							  event_buf_size);
@@ -124,7 +124,7 @@ int main(void)
 		for (i = 0; i < ret; i++) {
 			event = gpiod_edge_event_buffer_get_event(event_buffer,
 								  i);
-			printf("offset: %d, type: %s, event #%ld\n",
+			printf("offset: %d  type: %-7s  event #%ld\n",
 			       gpiod_edge_event_get_line_offset(event),
 			       edge_event_type_str(event),
 			       gpiod_edge_event_get_line_seqno(event));
Signature · 1 line
2.41.0
#2 lore raw

PATCH 2/8 core: examples: add more use case examples

In reply to Kent Gibson

Add examples for use cases drawn from the tools.

---
 examples/.gitignore                    |   9 ++
 examples/Makefile.am                   |  29 ++++-
 examples/find_line_by_name.c           | 111 ++++++++++++++++++
 examples/get_chip_info.c               |  40 +++++++
 examples/get_line_info.c               |  56 +++++++++
 examples/get_multiple_line_values.c    | 119 +++++++++++++++++++
 examples/reconfigure_input_to_output.c | 152 +++++++++++++++++++++++++
 examples/toggle_multiple_line_values.c | 136 ++++++++++++++++++++++
 examples/watch_line_info.c             |  72 ++++++++++++
 examples/watch_line_rising.c           | 129 +++++++++++++++++++++
 examples/watch_multiple_line_values.c  | 140 +++++++++++++++++++++++
 11 files changed, 992 insertions(+), 1 deletion(-)
 create mode 100644 examples/find_line_by_name.c
 create mode 100644 examples/get_chip_info.c
 create mode 100644 examples/get_line_info.c
 create mode 100644 examples/get_multiple_line_values.c
 create mode 100644 examples/reconfigure_input_to_output.c
 create mode 100644 examples/toggle_multiple_line_values.c
 create mode 100644 examples/watch_line_info.c
 create mode 100644 examples/watch_line_rising.c
 create mode 100644 examples/watch_multiple_line_values.c
examples/.gitignore +9 -0
index bdfde9a..8fd3ff3 100644
@@ -2,6 +2,15 @@
 # SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
 
 async_watch_line_value
+find_line_by_name
+get_chip_info
+get_line_info
 get_line_value
+get_multiple_line_values
+reconfigure_input_to_output
 toggle_line_value
+toggle_multiple_line_values
+watch_line_info
+watch_line_rising
 watch_line_value
+watch_multiple_line_values
examples/Makefile.am +28 -1
index 55dfe39..daf902b 100644
@@ -8,14 +8,41 @@ LDADD = $(top_builddir)/lib/libgpiod.la
 
 noinst_PROGRAMS = \
 	async_watch_line_value \
+	find_line_by_name \
+	get_chip_info \
+	get_line_info \
 	get_line_value \
+	get_multiple_line_values \
+	reconfigure_input_to_output \
 	toggle_line_value \
-	watch_line_value
+	toggle_multiple_line_values \
+	watch_line_info \
+	watch_line_rising \
+	watch_line_value \
+	watch_multiple_line_values
 
 async_watch_line_value_SOURCES = async_watch_line_value.c
 
+find_line_by_name_SOURCES = find_line_by_name.c
+
+get_chip_info_SOURCES = get_chip_info.c
+
+get_line_info_SOURCES = get_line_info.c
+
 get_line_value_SOURCES = get_line_value.c
 
+get_multiple_line_values_SOURCES = get_multiple_line_values.c
+
+reconfigure_input_to_output_SOURCES = reconfigure_input_to_output.c
+
 toggle_line_value_SOURCES = toggle_line_value.c
 
+toggle_multiple_line_value_SOURCES = toggle_multiple_line_value.c
+
+watch_line_info_SOURCES = watch_line_info.c
+
+watch_line_rising_SOURCES = watch_line_rising.c
+
 watch_line_value_SOURCES = watch_line_value.c
+
+watch_multiple_line_values_SOURCES = watch_multiple_line_values.c
examples/find_line_by_name.c new file +111 -0

111 lines not on this page · raw message

examples/get_chip_info.c new file +40 -0
new file mode 100644
index 0000000..5c181c8
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+/* Minimal example of reading the info for a chip. */
+
+#include <errno.h>
+#include <gpiod.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(void)
+{
+	/* Example configuration - customize to suit your situation. */
+	static const char *const chip_path = "/dev/gpiochip0";
+
+	struct gpiod_chip_info *info;
+	struct gpiod_chip *chip;
+
+	chip = gpiod_chip_open(chip_path);
+	if (!chip) {
+		fprintf(stderr, "failed to open chip: %s\n", strerror(errno));
+		return EXIT_FAILURE;
+	}
+
+	info = gpiod_chip_get_info(chip);
+	if (!info) {
+		fprintf(stderr, "failed to read info: %s\n", strerror(errno));
+		return EXIT_FAILURE;
+	}
+
+	printf("%s [%s] (%zu lines)\n", gpiod_chip_info_get_name(info),
+	       gpiod_chip_info_get_label(info),
+	       gpiod_chip_info_get_num_lines(info));
+
+	gpiod_chip_info_free(info);
+	gpiod_chip_close(chip);
+
+	return EXIT_SUCCESS;
+}
examples/get_line_info.c new file +56 -0

56 lines not on this page · raw message

examples/get_multiple_line_values.c new file +119 -0

119 lines not on this page · raw message

examples/reconfigure_input_to_output.c new file +152 -0

152 lines not on this page · raw message

examples/toggle_multiple_line_values.c new file +136 -0

136 lines not on this page · raw message

examples/watch_line_info.c new file +72 -0

72 lines not on this page · raw message

examples/watch_line_rising.c new file +129 -0

129 lines not on this page · raw message

examples/watch_multiple_line_values.c new file +140 -0

140 lines not on this page · raw message

Signature · 1 line
2.41.0
#3 lore raw

PATCH 3/8 bindings: cxx: examples: consistency cleanup

In reply to Kent Gibson

A collection of minor changes to be more consistent with other examples:
- capitalize comments
- add line offset to value outputs
- drop comma from edge event outputs
- drop trailing return where example loops indefintely
- sort includes

---
 .../cxx/examples/async_watch_line_value.cpp   |  8 +++---
 bindings/cxx/examples/get_line_value.cpp      | 28 +++++++++++--------
 bindings/cxx/examples/toggle_line_value.cpp   | 16 +++++------
 bindings/cxx/examples/watch_line_value.cpp    | 12 ++++----
 4 files changed, 33 insertions(+), 31 deletions(-)
bindings/cxx/examples/async_watch_line_value.cpp +4 -4
index e1d4a1e..d8317a5 100644
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <filesystem>
 #include <gpiod.hpp>
+#include <iomanip>
 #include <iostream>
 #include <poll.h>
 
@@ -79,10 +80,9 @@ int main(void)
 
 		for (const auto& event : buffer)
 			::std::cout << "offset: " << event.line_offset()
-				    << ", type: " << edge_event_type_str(event)
-				    << ", event #" << event.line_seqno()
+				    << "  type: " << ::std::setw(7)
+				    << ::std::left << edge_event_type_str(event)
+				    << "  event #" << event.line_seqno()
 				    << ::std::endl;
 	}
-
-	return EXIT_SUCCESS;
 }
bindings/cxx/examples/get_line_value.cpp +16 -12
index 8f4e739..a14d7e4 100644
@@ -10,7 +10,7 @@
 
 namespace {
 
-/* example configuration - customize to suit your situation */
+/* Example configuration - customize to suit your situation */
 const ::std::filesystem::path chip_path("/dev/gpiochip0");
 const ::gpiod::line::offset line_offset = 5;
 
@@ -18,17 +18,21 @@ const ::gpiod::line::offset line_offset = 5;
 
 int main(void)
 {
-	auto request =
-		::gpiod::chip(chip_path)
-			.prepare_request()
-			.set_consumer("get-line-value")
-			.add_line_settings(
-				line_offset,
-				::gpiod::line_settings().set_direction(
-					::gpiod::line::direction::INPUT))
-			.do_request();
-
-	::std::cout << request.get_value(line_offset) << ::std::endl;
+	auto request = ::gpiod::chip(chip_path)
+			       .prepare_request()
+			       .set_consumer("get-line-value")
+			       .add_line_settings(
+				       line_offset,
+				       ::gpiod::line_settings().set_direction(
+					       ::gpiod::line::direction::INPUT))
+			       .do_request();
+
+	::std::cout << line_offset << "="
+		    << (request.get_value(line_offset) ==
+					::gpiod::line::value::ACTIVE ?
+				"Active" :
+				"Inactive")
+		    << ::std::endl;
 
 	return EXIT_SUCCESS;
 }
bindings/cxx/examples/toggle_line_value.cpp +7 -9
index a060e8a..a17b43b 100644
@@ -6,8 +6,8 @@
 #include <cstdlib>
 #include <chrono>
 #include <filesystem>
-#include <iostream>
 #include <gpiod.hpp>
+#include <iostream>
 #include <thread>
 
 namespace {
@@ -19,15 +19,15 @@ const ::gpiod::line::offset line_offset = 5;
 ::gpiod::line::value toggle_value(::gpiod::line::value v)
 {
 	return (v == ::gpiod::line::value::ACTIVE) ?
-			::gpiod::line::value::INACTIVE :
-			::gpiod::line::value::ACTIVE;
+		       ::gpiod::line::value::INACTIVE :
+		       ::gpiod::line::value::ACTIVE;
 }
 
 } /* namespace */
 
 int main(void)
 {
-	::gpiod::line::value val = ::gpiod::line::value::ACTIVE;
+	::gpiod::line::value value = ::gpiod::line::value::ACTIVE;
 
 	auto request =
 		::gpiod::chip(chip_path)
@@ -40,12 +40,10 @@ int main(void)
 			.do_request();
 
 	for (;;) {
-		::std::cout << val << ::std::endl;
+		::std::cout << line_offset << "=" << value << ::std::endl;
 
 		std::this_thread::sleep_for(std::chrono::seconds(1));
-		val = toggle_value(val);
-		request.set_value(line_offset, val);
+		value = toggle_value(value);
+		request.set_value(line_offset, value);
 	}
-
-	return EXIT_SUCCESS;
 }
bindings/cxx/examples/watch_line_value.cpp +6 -6
index 5436884..5055789 100644
@@ -6,6 +6,7 @@
 #include <cstdlib>
 #include <filesystem>
 #include <gpiod.hpp>
+#include <iomanip>
 #include <iostream>
 
 namespace {
@@ -18,7 +19,7 @@ const char *edge_event_type_str(const ::gpiod::edge_event &event)
 {
 	switch (event.type()) {
 	case ::gpiod::edge_event::event_type::RISING_EDGE:
-		return "Rising ";
+		return "Rising";
 	case ::gpiod::edge_event::event_type::FALLING_EDGE:
 		return "Falling";
 	default:
@@ -61,11 +62,10 @@ int main(void)
 		request.read_edge_events(buffer);
 
 		for (const auto &event : buffer)
-			::std::cout << "offset: " << event.line_offset()
-				    << ", type: " << edge_event_type_str(event)
-				    << ", event #" << event.line_seqno()
+			::std::cout << "line: " << event.line_offset()
+				    << "  type: " << ::std::setw(7)
+				    << ::std::left << edge_event_type_str(event)
+				    << "  event #" << event.line_seqno()
 				    << ::std::endl;
 	}
-
-	return EXIT_SUCCESS;
 }
Signature · 1 line
2.41.0
#4 lore raw

PATCH 4/8 bindings: cxx: examples: replace tools examples with use case examples

In reply to Kent Gibson

Replace tool examples with use case examples drawn from the tools.

---
 bindings/cxx/examples/.gitignore              | 16 +++--
 bindings/cxx/examples/Makefile.am             | 42 +++++++-----
 bindings/cxx/examples/find_line_by_name.cpp   | 42 ++++++++++++
 bindings/cxx/examples/get_chip_info.cpp       | 27 ++++++++
 bindings/cxx/examples/get_line_info.cpp       | 39 +++++++++++
 .../cxx/examples/get_multiple_line_values.cpp | 40 ++++++++++++
 bindings/cxx/examples/gpiodetectcxx.cpp       | 30 ---------
 bindings/cxx/examples/gpiofindcxx.cpp         | 32 ---------
 bindings/cxx/examples/gpiogetcxx.cpp          | 40 ------------
 bindings/cxx/examples/gpioinfocxx.cpp         | 61 -----------------
 bindings/cxx/examples/gpiomoncxx.cpp          | 65 -------------------
 bindings/cxx/examples/gpionotifycxx.cpp       | 55 ----------------
 bindings/cxx/examples/gpiosetcxx.cpp          | 53 ---------------
 .../examples/reconfigure_input_to_output.cpp  | 56 ++++++++++++++++
 .../examples/toggle_multiple_line_values.cpp  | 63 ++++++++++++++++++
 bindings/cxx/examples/watch_line_info.cpp     | 49 ++++++++++++++
 bindings/cxx/examples/watch_line_rising.cpp   | 64 ++++++++++++++++++
 .../examples/watch_multiple_line_values.cpp   | 60 +++++++++++++++++
 18 files changed, 473 insertions(+), 361 deletions(-)
 create mode 100644 bindings/cxx/examples/find_line_by_name.cpp
 create mode 100644 bindings/cxx/examples/get_chip_info.cpp
 create mode 100644 bindings/cxx/examples/get_line_info.cpp
 create mode 100644 bindings/cxx/examples/get_multiple_line_values.cpp
 delete mode 100644 bindings/cxx/examples/gpiodetectcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiofindcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiogetcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpioinfocxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiomoncxx.cpp
 delete mode 100644 bindings/cxx/examples/gpionotifycxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiosetcxx.cpp
 create mode 100644 bindings/cxx/examples/reconfigure_input_to_output.cpp
 create mode 100644 bindings/cxx/examples/toggle_multiple_line_values.cpp
 create mode 100644 bindings/cxx/examples/watch_line_info.cpp
 create mode 100644 bindings/cxx/examples/watch_line_rising.cpp
 create mode 100644 bindings/cxx/examples/watch_multiple_line_values.cpp
bindings/cxx/examples/.gitignore +9 -7
index 268b3f6..0f9b39e 100644
@@ -1,14 +1,16 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 # SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <[email protected]>
 
-gpiodetectcxx
-gpiofindcxx
-gpiogetcxx
-gpioinfocxx
-gpiomoncxx
-gpionotifycxx
-gpiosetcxx
 async_watch_line_value
+find_line_by_name
+get_chip_info
+get_line_info
 get_line_value
+get_multiple_line_values
+reconfigure_input_to_output
 toggle_line_value
+toggle_multiple_line_values
+watch_line_info
+watch_line_rising
 watch_line_value
+watch_multiple_line_values
bindings/cxx/examples/Makefile.am +24 -18

60 lines not on this page · raw message

bindings/cxx/examples/find_line_by_name.cpp new file +42 -0

42 lines not on this page · raw message

bindings/cxx/examples/get_chip_info.cpp new file +27 -0
new file mode 100644
index 0000000..073a6c3
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+/* Minimal example of reading the info for a chip. */
+
+#include <cstdlib>
+#include <filesystem>
+#include <gpiod.hpp>
+#include <iostream>
+
+namespace {
+
+/* Example configuration - customize to suit your situation */
+const ::std::filesystem::path chip_path("/dev/gpiochip0");
+
+} /* namespace */
+
+int main(void)
+{
+	::gpiod::chip chip(chip_path);
+	auto info = chip.get_info();
+
+	::std::cout << info.name() << " [" << info.label() << "] ("
+		    << info.num_lines() << " lines)" << ::std::endl;
+
+	return EXIT_SUCCESS;
+}
bindings/cxx/examples/get_line_info.cpp new file +39 -0
new file mode 100644
index 0000000..f2f071e
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+/* Minimal example of reading the info for a line. */
+
+#include <cstdlib>
+#include <filesystem>
+#include <gpiod.hpp>
+#include <iomanip>
+#include <iostream>
+
+namespace {
+
+/* Example configuration - customize to suit your situation */
+const ::std::filesystem::path chip_path("/dev/gpiochip0");
+const ::gpiod::line::offset line_offset = 3;
+
+} /* namespace */
+
+int main(void)
+{
+	auto chip = ::gpiod::chip(chip_path);
+	auto info = chip.get_line_info(line_offset);
+
+	::std::cout << "line " << ::std::setw(3) << info.offset() << ": "
+		    << ::std::setw(12)
+		    << (info.name().empty() ? "unnamed" : info.name()) << " "
+		    << ::std::setw(12)
+		    << (info.consumer().empty() ? "unused" : info.consumer())
+		    << " " << ::std::setw(8)
+		    << (info.direction() == ::gpiod::line::direction::INPUT ?
+				"input" :
+				"output")
+		    << " " << ::std::setw(10)
+		    << (info.active_low() ? "active-low" : "active-high")
+		    << ::std::endl;
+
+	return EXIT_SUCCESS;
+}
bindings/cxx/examples/get_multiple_line_values.cpp new file +40 -0
new file mode 100644
index 0000000..d1f22e7
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+/* Minimal example of reading multiple lines. */
+
+#include <cstdlib>
+#include <gpiod.hpp>
+#include <iostream>
+
+namespace {
+
+/* Example configuration - customize to suit your situation */
+const ::std::filesystem::path chip_path("/dev/gpiochip0");
+const ::gpiod::line::offsets line_offsets = { 5, 3, 7 };
+
+} /* namespace */
+
+int main(void)
+{
+	auto request = ::gpiod::chip(chip_path)
+			       .prepare_request()
+			       .set_consumer("get-multiple-line-values")
+			       .add_line_settings(
+				       line_offsets,
+				       ::gpiod::line_settings().set_direction(
+					       ::gpiod::line::direction::INPUT))
+			       .do_request();
+
+	auto values = request.get_values();
+
+	for (size_t i = 0; i < line_offsets.size(); i++)
+		::std::cout << line_offsets[i] << "="
+			    << (values[i] == ::gpiod::line::value::ACTIVE ?
+					"Active" :
+					"Inactive")
+			    << ' ';
+	::std::cout << ::std::endl;
+
+	return EXIT_SUCCESS;
+}
bindings/cxx/examples/gpiodetectcxx.cpp deleted +0 -30
deleted file mode 100644
index 7dbb0e0..0000000
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <[email protected]>
-
-/* C++ reimplementation of the gpiodetect tool. */
-
-#include <cstdlib>
-#include <filesystem>
-#include <gpiod.hpp>
-#include <iostream>
-
-int main(int argc, char **argv)
-{
-	if (argc != 1) {
-		::std::cerr << "usage: " << argv[0] << ::std::endl;
-		return EXIT_FAILURE;
-	}
-
-	for (const auto& entry: ::std::filesystem::directory_iterator("/dev/")) {
-		if (::gpiod::is_gpiochip_device(entry.path())) {
-			::gpiod::chip chip(entry.path());
-			auto info = chip.get_info();
-
-			::std::cout << info.name() << " [" <<
-				       info.label() << "] (" <<
-				       info.num_lines() << " lines)" << ::std::endl;
-		}
-	}
-
-	return EXIT_SUCCESS;
-}
bindings/cxx/examples/gpiofindcxx.cpp deleted +0 -32
deleted file mode 100644
index cd36be7..0000000
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <[email protected]>
-
-/* C++ reimplementation of the gpiofind tool. */
-
-#include <gpiod.hpp>
-
-#include <cstdlib>
-#include <filesystem>
-#include <iostream>
-
-int main(int argc, char **argv)
-{
-	if (argc != 2) {
-		::std::cerr << "usage: " << argv[0] << " <line name>" << ::std::endl;
-		return EXIT_FAILURE;
-	}
-
-	for (const auto& entry: ::std::filesystem::directory_iterator("/dev/")) {
-		if (::gpiod::is_gpiochip_device(entry.path())) {
-			::gpiod::chip chip(entry.path());
-
-			auto offset = chip.get_line_offset_from_name(argv[1]);
-			if (offset >= 0) {
-				::std::cout << chip.get_info().name() << " " << offset << ::std::endl;
-				return EXIT_SUCCESS;
-			}
-		}
-	}
-
-	return EXIT_FAILURE;
-}
bindings/cxx/examples/gpiogetcxx.cpp deleted +0 -40
deleted file mode 100644
index b0d4a7d..0000000
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <[email protected]>
-
-/* Simplified C++ reimplementation of the gpioget tool. */
-
-#include <gpiod.hpp>
-
-#include <cstdlib>
-#include <iostream>
-
-int main(int argc, char **argv)
-{
-	if (argc < 3) {
-		::std::cerr << "usage: " << argv[0] << " <chip> <line_offset0> ..." << ::std::endl;
-		return EXIT_FAILURE;
-	}
-
-	::gpiod::line::offsets offsets;
-
-	for (int i = 2; i < argc; i++)
-		offsets.push_back(::std::stoul(argv[i]));
-
-	auto request = ::gpiod::chip(argv[1])
-		.prepare_request()
-		.set_consumer("gpiogetcxx")
-		.add_line_settings(
-			offsets,
-			::gpiod::line_settings()
-				.set_direction(::gpiod::line::direction::INPUT)
-		)
-		.do_request();
-
-	auto vals = request.get_values();
-
-	for (auto& it: vals)
-		::std::cout << (it == ::gpiod::line::value::ACTIVE ? "1" : "0") << ' ';
-	::std::cout << ::std::endl;
-
-	return EXIT_SUCCESS;
-}
bindings/cxx/examples/gpioinfocxx.cpp deleted +0 -61

61 lines not on this page · raw message

bindings/cxx/examples/gpiomoncxx.cpp deleted +0 -65

65 lines not on this page · raw message

bindings/cxx/examples/gpionotifycxx.cpp deleted +0 -55

55 lines not on this page · raw message

bindings/cxx/examples/gpiosetcxx.cpp deleted +0 -53

53 lines not on this page · raw message

bindings/cxx/examples/reconfigure_input_to_output.cpp new file +56 -0

56 lines not on this page · raw message

bindings/cxx/examples/toggle_multiple_line_values.cpp new file +63 -0

63 lines not on this page · raw message

bindings/cxx/examples/watch_line_info.cpp new file +49 -0

49 lines not on this page · raw message

bindings/cxx/examples/watch_line_rising.cpp new file +64 -0

64 lines not on this page · raw message

bindings/cxx/examples/watch_multiple_line_values.cpp new file +60 -0

60 lines not on this page · raw message

Signature · 1 line
2.41.0
#5 lore raw

PATCH 5/8 bindings: python: examples: consistency cleanup

In reply to Kent Gibson

A collection of minor changes to be more consistent with other examples:
- capitalize comments
- add line offset to value outputs
- drop comma from edge event outputs
- improve behaviour if run on a platform that does not match the example configuration
- use with to cleanup request in toggle_line_value.py

---
 .../python/examples/async_watch_line_value.py | 15 ++++----
 bindings/python/examples/get_line_value.py    | 13 ++++---
 bindings/python/examples/toggle_line_value.py | 34 +++++++------------
 bindings/python/examples/watch_line_value.py  | 19 +++++------
 4 files changed, 35 insertions(+), 46 deletions(-)
bindings/python/examples/async_watch_line_value.py +7 -8
index ed09ec9..ea8314f 100755
@@ -19,12 +19,8 @@ def edge_type(event):
     return "Unknown"
 
 
-def async_watch_line_value():
-    # example configuration - customise to suit your situation
-    chip_path = "/dev/gpiochip0"
-    line_offset = 5
-
-    # assume a button connecting the pin to ground,
+def async_watch_line_value(chip_path, line_offset):
+    # Assume a button connecting the pin to ground,
     # so pull it up and provide some debounce.
     with gpiod.request_lines(
         chip_path,
@@ -40,7 +36,7 @@ def async_watch_line_value():
         poll = select.poll()
         poll.register(request.fd, select.POLLIN)
         while True:
-            # other fds could be registered with the poll and be handled
+            # Other fds could be registered with the poll and be handled
             # separately using the return value (fd, event) from poll()
             poll.poll()
             for event in request.read_edge_events():
@@ -51,4 +47,7 @@ def async_watch_line_value():
 
 
 if __name__ == "__main__":
-    async_watch_line_value()
+    try:
+        async_watch_line_value("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_line_value.py +6 -7
index ab733df..f3ca13b 100755
@@ -9,19 +9,18 @@ import gpiod
 from gpiod.line import Direction
 
 
-def get_line_value():
-    # example configuration - customise to suit your situation
-    chip_path = "/dev/gpiochip0"
-    line_offset = 5
-
+def get_line_value(chip_path, line_offset):
     with gpiod.request_lines(
         chip_path,
         consumer="get-line-value",
         config={line_offset: gpiod.LineSettings(direction=Direction.INPUT)},
     ) as request:
         value = request.get_value(line_offset)
-        print(value)
+        print("{}={}".format(line_offset, value))
 
 
 if __name__ == "__main__":
-    get_line_value()
+    try:
+        get_line_value("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/toggle_line_value.py +13 -21
index 46e52f9..e0de8fb 100755
@@ -16,21 +16,11 @@ def toggle_value(value):
     return Value.INACTIVE
 
 
-def print_value(value):
-    if value == Value.ACTIVE:
-        print("Active")
-    else:
-        print("Inactive")
-
-
-def toggle_line_value():
-    # example configuration - customise to suit your situation
-    chip_path = "/dev/gpiochip0"
-    line_offset = 5
-
+def toggle_line_value(chip_path, line_offset):
+    value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"}
     value = Value.ACTIVE
 
-    request = gpiod.request_lines(
+    with gpiod.request_lines(
         chip_path,
         consumer="toggle-line-value",
         config={
@@ -38,14 +28,16 @@ def toggle_line_value():
                 direction=Direction.OUTPUT, output_value=value
             )
         },
-    )
-
-    while True:
-        print_value(value)
-        time.sleep(1)
-        value = toggle_value(value)
-        request.set_value(line_offset, value)
+    ) as request:
+        while True:
+            print("{}={}".format(line_offset, value_str[value]))
+            time.sleep(1)
+            value = toggle_value(value)
+            request.set_value(line_offset, value)
 
 
 if __name__ == "__main__":
-    toggle_line_value()
+    try:
+        toggle_line_value("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_line_value.py +9 -10
index 42fc0bd..841bf40 100755
@@ -12,18 +12,14 @@ from gpiod.line import Bias, Edge
 
 def edge_type(event):
     if event.event_type is event.Type.RISING_EDGE:
-        return "Rising "
+        return "Rising"
     if event.event_type is event.Type.FALLING_EDGE:
         return "Falling"
     return "Unknown"
 
 
-def watch_line_value():
-    # example configuration - customise to suit your situation
-    chip_path = "/dev/gpiochip0"
-    line_offset = 5
-
-    # assume a button connecting the pin to ground,
+def watch_line_value(chip_path, line_offset):
+    # Assume a button connecting the pin to ground,
     # so pull it up and provide some debounce.
     with gpiod.request_lines(
         chip_path,
@@ -37,13 +33,16 @@ def watch_line_value():
         },
     ) as request:
         while True:
-            # blocks until at least one event is available
+            # Blocks until at least one event is available
             for event in request.read_edge_events():
                 print(
-                    "offset: %d, type: %s, event #%d"
+                    "line: %d  type: %-7s  event #%d"
                     % (event.line_offset, edge_type(event), event.line_seqno)
                 )
 
 
 if __name__ == "__main__":
-    watch_line_value()
+    try:
+        watch_line_value("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
Signature · 1 line
2.41.0
#6 lore raw

PATCH 6/8 bindings: python: examples: replace tools examples with use case examples

In reply to Kent Gibson

Replace tool examples with use case examples drawn from the tools.

---
 bindings/python/examples/Makefile.am          | 18 +++----
 bindings/python/examples/find_line_by_name.py | 37 +++++++++++++++
 bindings/python/examples/get_chip_info.py     | 20 ++++++++
 bindings/python/examples/get_line_info.py     | 29 ++++++++++++
 .../examples/get_multiple_line_values.py      | 29 ++++++++++++
 bindings/python/examples/gpiodetect.py        | 15 ------
 bindings/python/examples/gpiofind.py          | 20 --------
 bindings/python/examples/gpioget.py           | 29 ------------
 bindings/python/examples/gpioinfo.py          | 28 -----------
 bindings/python/examples/gpiomon.py           | 26 ----------
 bindings/python/examples/gpionotify.py        | 21 ---------
 bindings/python/examples/gpioset.py           | 36 --------------
 bindings/python/examples/helpers.py           | 15 ------
 .../examples/reconfigure_input_to_output.py   | 39 +++++++++++++++
 .../examples/toggle_multiple_line_values.py   | 47 +++++++++++++++++++
 bindings/python/examples/watch_line_info.py   | 23 +++++++++
 bindings/python/examples/watch_line_rising.py | 31 ++++++++++++
 .../examples/watch_multiple_line_values.py    | 43 +++++++++++++++++
 18 files changed, 308 insertions(+), 198 deletions(-)
 create mode 100755 bindings/python/examples/find_line_by_name.py
 create mode 100755 bindings/python/examples/get_chip_info.py
 create mode 100755 bindings/python/examples/get_line_info.py
 create mode 100755 bindings/python/examples/get_multiple_line_values.py
 delete mode 100755 bindings/python/examples/gpiodetect.py
 delete mode 100755 bindings/python/examples/gpiofind.py
 delete mode 100755 bindings/python/examples/gpioget.py
 delete mode 100755 bindings/python/examples/gpioinfo.py
 delete mode 100755 bindings/python/examples/gpiomon.py
 delete mode 100755 bindings/python/examples/gpionotify.py
 delete mode 100755 bindings/python/examples/gpioset.py
 delete mode 100644 bindings/python/examples/helpers.py
 create mode 100755 bindings/python/examples/reconfigure_input_to_output.py
 create mode 100755 bindings/python/examples/toggle_multiple_line_values.py
 create mode 100755 bindings/python/examples/watch_line_info.py
 create mode 100755 bindings/python/examples/watch_line_rising.py
 create mode 100755 bindings/python/examples/watch_multiple_line_values.py
bindings/python/examples/Makefile.am +10 -8
index c8c1c98..52abafc 100644
@@ -3,13 +3,15 @@
 
 EXTRA_DIST = \
 	async_watch_line_value.py \
+	find_line_by_name.py \
+	get_chip_info.py \
+	get_line_info.py \
 	get_line_value.py \
-	gpiodetect.py \
-	gpiofind.py \
-	gpioget.py \
-	gpioinfo.py \
-	gpiomon.py \
-	gpionotify.py \
-	gpioset.py \
+	get_multiple_line_values.py \
+	reconfigure_input_to_output.py \
 	toggle_line_value.py \
-	watch_line_value.py
+	toggle_multiple_line_values.py \
+	watch_line_requests.py \
+	watch_line_value.py \
+	watch_line_rising.py \
+	watch_multiple_line_values.py
bindings/python/examples/find_line_by_name.py new file +37 -0
new file mode 100755
index 0000000..58f1cd0
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of finding a line with the given name."""
+
+import gpiod
+import os
+
+
+def gpio_chips():
+    for entry in os.scandir("/dev/"):
+        if gpiod.is_gpiochip_device(entry.path):
+            yield entry.path
+
+
+def find_line_by_name(line_name):
+    # Names are not guaranteed unique, so this finds the first line with
+    # the given name.
+    for path in gpio_chips():
+        with gpiod.Chip(path) as chip:
+            try:
+                offset = chip.line_offset_from_id(line_name)
+                print("{}: {} {}".format(line_name, chip.get_info().name, offset))
+                return
+            except OSError:
+                # An OSError is raised if the name is not found.
+                continue
+
+    print("line '{}' not found".format(line_name))
+
+
+if __name__ == "__main__":
+    try:
+        find_line_by_name("GPIO19")
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_chip_info.py new file +20 -0
new file mode 100755
index 0000000..7dc76fb
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading the info for a chip."""
+
+import gpiod
+
+
+def get_chip_info(chip_path):
+    with gpiod.Chip(chip_path) as chip:
+        info = chip.get_info()
+        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))
+
+
+if __name__ == "__main__":
+    try:
+        get_chip_info("/dev/gpiochip0")
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_line_info.py new file +29 -0
new file mode 100755
index 0000000..cd4ebcc
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading the info for a line."""
+
+import gpiod
+
+
+def get_line_info(chip_path, line_offset):
+    with gpiod.Chip(chip_path) as chip:
+        info = chip.get_line_info(line_offset)
+        is_input = info.direction == gpiod.line.Direction.INPUT
+        print(
+            "line {:>3}: {:>12} {:>12} {:>8} {:>10}".format(
+                info.offset,
+                info.name or "unnamed",
+                info.consumer or "unused",
+                "input" if is_input else "output",
+                "active-low" if info.active_low else "active-high",
+            )
+        )
+
+
+if __name__ == "__main__":
+    try:
+        get_line_info("/dev/gpiochip0", 3)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_multiple_line_values.py new file +29 -0
new file mode 100755
index 0000000..46cf0b2
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading multiple lines."""
+
+import gpiod
+
+from gpiod.line import Direction
+
+
+def get_multiple_line_values(chip_path, line_offsets):
+    with gpiod.request_lines(
+        chip_path,
+        consumer="get-multiple-line-values",
+        config={tuple(line_offsets): gpiod.LineSettings(direction=Direction.INPUT)},
+    ) as request:
+        vals = request.get_values()
+
+        for offset, val in zip(line_offsets, vals):
+            print("{}={} ".format(offset, val), end="")
+        print()
+
+
+if __name__ == "__main__":
+    try:
+        get_multiple_line_values("/dev/gpiochip0", [5, 3, 7])
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/gpiodetect.py deleted +0 -15
deleted file mode 100755
index dc98b03..0000000
@@ -1,15 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Reimplementation of the gpiodetect tool in Python."""
-
-import gpiod
-import os
-
-from helpers import gpio_chips
-
-if __name__ == "__main__":
-    for chip in gpio_chips():
-        info = chip.get_info()
-        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))
bindings/python/examples/gpiofind.py deleted +0 -20
deleted file mode 100755
index d41660d..0000000
@@ -1,20 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Reimplementation of the gpiofind tool in Python."""
-
-import gpiod
-import os
-import sys
-
-if __name__ == "__main__":
-    for entry in os.scandir("/dev/"):
-        if gpiod.is_gpiochip_device(entry.path):
-            with gpiod.Chip(entry.path) as chip:
-                offset = chip.line_offset_from_id(sys.argv[1])
-                if offset is not None:
-                    print("{} {}".format(chip.get_info().name, offset))
-                    sys.exit(0)
-
-    sys.exit(1)
bindings/python/examples/gpioget.py deleted +0 -29
deleted file mode 100755
index bf7e0a6..0000000
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioget tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Direction
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
-
-    request = gpiod.request_lines(
-        path,
-        consumer="gpioget.py",
-        config={tuple(lines): gpiod.LineSettings(direction=Direction.INPUT)},
-    )
-
-    vals = request.get_values()
-
-    for val in vals:
-        print("{} ".format(val.value), end="")
-    print()
bindings/python/examples/gpioinfo.py deleted +0 -28
deleted file mode 100755
index 3996dcf..0000000
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioinfo tool in Python."""
-
-import gpiod
-import os
-
-from helpers import gpio_chips
-
-if __name__ == "__main__":
-    for chip in gpio_chips():
-        cinfo = chip.get_info()
-        print("{} - {} lines:".format(cinfo.name, cinfo.num_lines))
-
-        for offset in range(0, cinfo.num_lines):
-            linfo = chip.get_line_info(offset)
-            is_input = linfo.direction == gpiod.line.Direction.INPUT
-            print(
-                "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format(
-                    linfo.offset,
-                    linfo.name or "unnamed",
-                    linfo.consumer or "unused",
-                    "input" if is_input else "output",
-                    "active-low" if linfo.active_low else "active-high",
-                )
-            )
bindings/python/examples/gpiomon.py deleted +0 -26
deleted file mode 100755
index 702d7c8..0000000
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpiomon tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Edge
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpiomon.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
-
-    with gpiod.request_lines(
-        path,
-        consumer="gpiomon.py",
-        config={tuple(lines): gpiod.LineSettings(edge_detection=Edge.BOTH)},
-    ) as request:
-        while True:
-            for event in request.read_edge_events():
-                print(event)
bindings/python/examples/gpionotify.py deleted +0 -21
deleted file mode 100755
index 4e50515..0000000
@@ -1,21 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2023 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpionotify tool in Python."""
-
-import gpiod
-import sys
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpionotify.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-
-    with gpiod.Chip(path) as chip:
-        for line in sys.argv[2:]:
-            chip.watch_line_info(line)
-
-        while True:
-            print(chip.read_info_event())
bindings/python/examples/gpioset.py deleted +0 -36
deleted file mode 100755
index e6a516c..0000000
@@ -1,36 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioset tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Direction, Value
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError(
-            "usage: gpioset.py <gpiochip> <offset1>=<value1> <offset2>=<value2> ..."
-        )
-
-    path = sys.argv[1]
-
-    def parse_value(arg):
-        x, y = arg.split("=")
-        return (x, Value(int(y)))
-
-    def make_settings(val):
-        return gpiod.LineSettings(direction=Direction.OUTPUT, output_value=val)
-
-    lvs = [parse_value(arg) for arg in sys.argv[2:]]
-    config = dict((l, make_settings(v)) for (l, v) in lvs)
-
-    request = gpiod.request_lines(
-        path,
-        consumer="gpioset.py",
-        config=config,
-    )
-
-    input()
bindings/python/examples/helpers.py deleted +0 -15
deleted file mode 100644
index 8b91173..0000000
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-import gpiod
-import os
-
-
-def gpio_chips():
-    for path in [
-        entry.path
-        for entry in os.scandir("/dev/")
-        if gpiod.is_gpiochip_device(entry.path)
-    ]:
-        with gpiod.Chip(path) as chip:
-            yield chip
bindings/python/examples/reconfigure_input_to_output.py new file +39 -0
new file mode 100755
index 0000000..60d3015
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of requesting a line intended for bi-directional use as input and then switching to output."""
+
+import gpiod
+
+from gpiod.line import Direction, Value
+
+
+def reconfigure_input_to_output(chip_path, line_offset):
+    # request the line initially as an input
+    with gpiod.request_lines(
+        chip_path,
+        consumer="reconfigure-input-to-output",
+        config={line_offset: gpiod.LineSettings(direction=Direction.INPUT)},
+    ) as request:
+        # read the current line value
+        value = request.get_value(line_offset)
+        print("{}={} (input)".format(line_offset, value))
+        # switch the line to an output and drive it low
+        request.reconfigure_lines(
+            config={
+                line_offset: gpiod.LineSettings(
+                    direction=Direction.OUTPUT, output_value=Value.INACTIVE
+                )
+            }
+        )
+        # report the current driven value
+        value = request.get_value(line_offset)
+        print("{}={} (output)".format(line_offset, value))
+
+
+if __name__ == "__main__":
+    try:
+        reconfigure_input_to_output("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/toggle_multiple_line_values.py new file +47 -0

47 lines not on this page · raw message

bindings/python/examples/watch_line_info.py new file +23 -0
new file mode 100755
index 0000000..e49a669
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of watching for info changes on particular lines."""
+
+import gpiod
+
+
+def watch_line_info(chip_path, line_offsets):
+    with gpiod.Chip(chip_path) as chip:
+        for offset in line_offsets:
+            chip.watch_line_info(offset)
+
+        while True:
+            print(chip.read_info_event())
+
+
+if __name__ == "__main__":
+    try:
+        watch_line_info("/dev/gpiochip0", [5, 3, 7])
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_line_rising.py new file +31 -0
new file mode 100755
index 0000000..2350d76
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of watching for rising edges on a single line."""
+
+import gpiod
+
+from gpiod.line import Edge
+
+
+def watch_line_rising(chip_path, line_offset):
+    with gpiod.request_lines(
+        chip_path,
+        consumer="watch-line-rising",
+        config={line_offset: gpiod.LineSettings(edge_detection=Edge.RISING)},
+    ) as request:
+        while True:
+            # Blocks until at least one event is available
+            for event in request.read_edge_events():
+                print(
+                    "line: %d  type: Rising   event #%d"
+                    % (event.line_offset, event.line_seqno)
+                )
+
+
+if __name__ == "__main__":
+    try:
+        watch_line_rising("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_multiple_line_values.py new file +43 -0

43 lines not on this page · raw message

Signature · 1 line
2.41.0
#7 lore raw

Re: [libgpiod][PATCH 6/8] bindings: python: examples: replace tools examples with use case examples

Quoted 77 lines · Kent Gibson

Replace tool examples with use case examples drawn from the tools.

---
 bindings/python/examples/Makefile.am          | 18 +++----
 bindings/python/examples/find_line_by_name.py | 37 +++++++++++++++
 bindings/python/examples/get_chip_info.py     | 20 ++++++++
 bindings/python/examples/get_line_info.py     | 29 ++++++++++++
 .../examples/get_multiple_line_values.py      | 29 ++++++++++++
 bindings/python/examples/gpiodetect.py        | 15 ------
 bindings/python/examples/gpiofind.py          | 20 --------
 bindings/python/examples/gpioget.py           | 29 ------------
 bindings/python/examples/gpioinfo.py          | 28 -----------
 bindings/python/examples/gpiomon.py           | 26 ----------
 bindings/python/examples/gpionotify.py        | 21 ---------
 bindings/python/examples/gpioset.py           | 36 --------------
 bindings/python/examples/helpers.py           | 15 ------
 .../examples/reconfigure_input_to_output.py   | 39 +++++++++++++++
 .../examples/toggle_multiple_line_values.py   | 47 +++++++++++++++++++
 bindings/python/examples/watch_line_info.py   | 23 +++++++++
 bindings/python/examples/watch_line_rising.py | 31 ++++++++++++
 .../examples/watch_multiple_line_values.py    | 43 +++++++++++++++++
 18 files changed, 308 insertions(+), 198 deletions(-)
 create mode 100755 bindings/python/examples/find_line_by_name.py
 create mode 100755 bindings/python/examples/get_chip_info.py
 create mode 100755 bindings/python/examples/get_line_info.py
 create mode 100755 bindings/python/examples/get_multiple_line_values.py
 delete mode 100755 bindings/python/examples/gpiodetect.py
 delete mode 100755 bindings/python/examples/gpiofind.py
 delete mode 100755 bindings/python/examples/gpioget.py
 delete mode 100755 bindings/python/examples/gpioinfo.py
 delete mode 100755 bindings/python/examples/gpiomon.py
 delete mode 100755 bindings/python/examples/gpionotify.py
 delete mode 100755 bindings/python/examples/gpioset.py
 delete mode 100644 bindings/python/examples/helpers.py
 create mode 100755 bindings/python/examples/reconfigure_input_to_output.py
 create mode 100755 bindings/python/examples/toggle_multiple_line_values.py
 create mode 100755 bindings/python/examples/watch_line_info.py
 create mode 100755 bindings/python/examples/watch_line_rising.py
 create mode 100755 bindings/python/examples/watch_multiple_line_values.py
bindings/python/examples/Makefile.am +10 -8
index c8c1c98..52abafc 100644
@@ -3,13 +3,15 @@
 
 EXTRA_DIST = \
        async_watch_line_value.py \
+       find_line_by_name.py \
+       get_chip_info.py \
+       get_line_info.py \
        get_line_value.py \
-       gpiodetect.py \
-       gpiofind.py \
-       gpioget.py \
-       gpioinfo.py \
-       gpiomon.py \
-       gpionotify.py \
-       gpioset.py \
+       get_multiple_line_values.py \
+       reconfigure_input_to_output.py \
        toggle_line_value.py \
-       watch_line_value.py
+       toggle_multiple_line_values.py \
+       watch_line_requests.py \
+       watch_line_value.py \
+       watch_line_rising.py \
+       watch_multiple_line_values.py
bindings/python/examples/find_line_by_name.py new file +1 -0
new file mode 100755
index 0000000..58f1cd0
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3

bindings/python/examples/find_line_by_name.py line 11

Quoted 10 lines
bindings/python/examples/find_line_by_name.py new file +10 -0
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of finding a line with the given name."""
+
+import gpiod
+import os
+
+
+def gpio_chips():

Please call it get_gpio_chip() to indicate it's an action performed by the function.

Quoted 366 lines
bindings/python/examples/find_line_by_name.py new file +26 -0
+    for entry in os.scandir("/dev/"):
+        if gpiod.is_gpiochip_device(entry.path):
+            yield entry.path
+
+
+def find_line_by_name(line_name):
+    # Names are not guaranteed unique, so this finds the first line with
+    # the given name.
+    for path in gpio_chips():
+        with gpiod.Chip(path) as chip:
+            try:
+                offset = chip.line_offset_from_id(line_name)
+                print("{}: {} {}".format(line_name, chip.get_info().name, offset))
+                return
+            except OSError:
+                # An OSError is raised if the name is not found.
+                continue
+
+    print("line '{}' not found".format(line_name))
+
+
+if __name__ == "__main__":
+    try:
+        find_line_by_name("GPIO19")
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_chip_info.py new file +20 -0
new file mode 100755
index 0000000..7dc76fb
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading the info for a chip."""
+
+import gpiod
+
+
+def get_chip_info(chip_path):
+    with gpiod.Chip(chip_path) as chip:
+        info = chip.get_info()
+        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))
+
+
+if __name__ == "__main__":
+    try:
+        get_chip_info("/dev/gpiochip0")
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_line_info.py new file +29 -0
new file mode 100755
index 0000000..cd4ebcc
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading the info for a line."""
+
+import gpiod
+
+
+def get_line_info(chip_path, line_offset):
+    with gpiod.Chip(chip_path) as chip:
+        info = chip.get_line_info(line_offset)
+        is_input = info.direction == gpiod.line.Direction.INPUT
+        print(
+            "line {:>3}: {:>12} {:>12} {:>8} {:>10}".format(
+                info.offset,
+                info.name or "unnamed",
+                info.consumer or "unused",
+                "input" if is_input else "output",
+                "active-low" if info.active_low else "active-high",
+            )
+        )
+
+
+if __name__ == "__main__":
+    try:
+        get_line_info("/dev/gpiochip0", 3)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/get_multiple_line_values.py new file +29 -0
new file mode 100755
index 0000000..46cf0b2
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of reading multiple lines."""
+
+import gpiod
+
+from gpiod.line import Direction
+
+
+def get_multiple_line_values(chip_path, line_offsets):
+    with gpiod.request_lines(
+        chip_path,
+        consumer="get-multiple-line-values",
+        config={tuple(line_offsets): gpiod.LineSettings(direction=Direction.INPUT)},
+    ) as request:
+        vals = request.get_values()
+
+        for offset, val in zip(line_offsets, vals):
+            print("{}={} ".format(offset, val), end="")
+        print()
+
+
+if __name__ == "__main__":
+    try:
+        get_multiple_line_values("/dev/gpiochip0", [5, 3, 7])
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/gpiodetect.py deleted +0 -15
deleted file mode 100755
index dc98b03..0000000
@@ -1,15 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Reimplementation of the gpiodetect tool in Python."""
-
-import gpiod
-import os
-
-from helpers import gpio_chips
-
-if __name__ == "__main__":
-    for chip in gpio_chips():
-        info = chip.get_info()
-        print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines))
bindings/python/examples/gpiofind.py deleted +0 -20
deleted file mode 100755
index d41660d..0000000
@@ -1,20 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Reimplementation of the gpiofind tool in Python."""
-
-import gpiod
-import os
-import sys
-
-if __name__ == "__main__":
-    for entry in os.scandir("/dev/"):
-        if gpiod.is_gpiochip_device(entry.path):
-            with gpiod.Chip(entry.path) as chip:
-                offset = chip.line_offset_from_id(sys.argv[1])
-                if offset is not None:
-                    print("{} {}".format(chip.get_info().name, offset))
-                    sys.exit(0)
-
-    sys.exit(1)
bindings/python/examples/gpioget.py deleted +0 -29
deleted file mode 100755
index bf7e0a6..0000000
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioget tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Direction
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
-
-    request = gpiod.request_lines(
-        path,
-        consumer="gpioget.py",
-        config={tuple(lines): gpiod.LineSettings(direction=Direction.INPUT)},
-    )
-
-    vals = request.get_values()
-
-    for val in vals:
-        print("{} ".format(val.value), end="")
-    print()
bindings/python/examples/gpioinfo.py deleted +0 -28
deleted file mode 100755
index 3996dcf..0000000
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioinfo tool in Python."""
-
-import gpiod
-import os
-
-from helpers import gpio_chips
-
-if __name__ == "__main__":
-    for chip in gpio_chips():
-        cinfo = chip.get_info()
-        print("{} - {} lines:".format(cinfo.name, cinfo.num_lines))
-
-        for offset in range(0, cinfo.num_lines):
-            linfo = chip.get_line_info(offset)
-            is_input = linfo.direction == gpiod.line.Direction.INPUT
-            print(
-                "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format(
-                    linfo.offset,
-                    linfo.name or "unnamed",
-                    linfo.consumer or "unused",
-                    "input" if is_input else "output",
-                    "active-low" if linfo.active_low else "active-high",
-                )
-            )
bindings/python/examples/gpiomon.py deleted +0 -26
deleted file mode 100755
index 702d7c8..0000000
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpiomon tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Edge
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpiomon.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-    lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]]
-
-    with gpiod.request_lines(
-        path,
-        consumer="gpiomon.py",
-        config={tuple(lines): gpiod.LineSettings(edge_detection=Edge.BOTH)},
-    ) as request:
-        while True:
-            for event in request.read_edge_events():
-                print(event)
bindings/python/examples/gpionotify.py deleted +0 -21
deleted file mode 100755
index 4e50515..0000000
@@ -1,21 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2023 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpionotify tool in Python."""
-
-import gpiod
-import sys
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError("usage: gpionotify.py <gpiochip> <offset1> <offset2> ...")
-
-    path = sys.argv[1]
-
-    with gpiod.Chip(path) as chip:
-        for line in sys.argv[2:]:
-            chip.watch_line_info(line)
-
-        while True:
-            print(chip.read_info_event())
bindings/python/examples/gpioset.py deleted +0 -36
deleted file mode 100755
index e6a516c..0000000
@@ -1,36 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-"""Simplified reimplementation of the gpioset tool in Python."""
-
-import gpiod
-import sys
-
-from gpiod.line import Direction, Value
-
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        raise TypeError(
-            "usage: gpioset.py <gpiochip> <offset1>=<value1> <offset2>=<value2> ..."
-        )
-
-    path = sys.argv[1]
-
-    def parse_value(arg):
-        x, y = arg.split("=")
-        return (x, Value(int(y)))
-
-    def make_settings(val):
-        return gpiod.LineSettings(direction=Direction.OUTPUT, output_value=val)
-
-    lvs = [parse_value(arg) for arg in sys.argv[2:]]
-    config = dict((l, make_settings(v)) for (l, v) in lvs)
-
-    request = gpiod.request_lines(
-        path,
-        consumer="gpioset.py",
-        config=config,
-    )
-
-    input()
bindings/python/examples/helpers.py deleted +0 -15
deleted file mode 100644
index 8b91173..0000000
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
-
-import gpiod
-import os
-
-
-def gpio_chips():
-    for path in [
-        entry.path
-        for entry in os.scandir("/dev/")
-        if gpiod.is_gpiochip_device(entry.path)
-    ]:
-        with gpiod.Chip(path) as chip:
-            yield chip
bindings/python/examples/reconfigure_input_to_output.py new file +0 -0
new file mode 100755
index 0000000..60d3015

bindings/python/examples/reconfigure_input_to_output.py line 5

Quoted 5 lines
bindings/python/examples/reconfigure_input_to_output.py new file +5 -0
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of requesting a line intended for bi-directional use as input and then switching to output."""

black doesn't break strings but could you limit it to 88 chars here?

Quoted 178 lines
bindings/python/examples/reconfigure_input_to_output.py new file +34 -0
+
+import gpiod
+
+from gpiod.line import Direction, Value
+
+
+def reconfigure_input_to_output(chip_path, line_offset):
+    # request the line initially as an input
+    with gpiod.request_lines(
+        chip_path,
+        consumer="reconfigure-input-to-output",
+        config={line_offset: gpiod.LineSettings(direction=Direction.INPUT)},
+    ) as request:
+        # read the current line value
+        value = request.get_value(line_offset)
+        print("{}={} (input)".format(line_offset, value))
+        # switch the line to an output and drive it low
+        request.reconfigure_lines(
+            config={
+                line_offset: gpiod.LineSettings(
+                    direction=Direction.OUTPUT, output_value=Value.INACTIVE
+                )
+            }
+        )
+        # report the current driven value
+        value = request.get_value(line_offset)
+        print("{}={} (output)".format(line_offset, value))
+
+
+if __name__ == "__main__":
+    try:
+        reconfigure_input_to_output("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/toggle_multiple_line_values.py new file +47 -0
new file mode 100755
index 0000000..12b968d
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of toggling multiple lines."""
+
+import gpiod
+import time
+
+from gpiod.line import Direction, Value
+
+
+def toggle_value(value):
+    if value == Value.INACTIVE:
+        return Value.ACTIVE
+    return Value.INACTIVE
+
+
+def toggle_multiple_line_values(chip_path, line_values):
+    value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"}
+
+    request = gpiod.request_lines(
+        chip_path,
+        consumer="toggle-multiple-line-values",
+        config={
+            tuple(line_values.keys()): gpiod.LineSettings(direction=Direction.OUTPUT)
+        },
+        output_values=line_values,
+    )
+
+    while True:
+        print(
+            " ".join("{}={}".format(l, value_str[v]) for (l, v) in line_values.items())
+        )
+        time.sleep(1)
+        for l, v in line_values.items():
+            line_values[l] = toggle_value(v)
+        request.set_values(line_values)
+
+
+if __name__ == "__main__":
+    try:
+        toggle_multiple_line_values(
+            "/dev/gpiochip0", {5: Value.ACTIVE, 3: Value.ACTIVE, 7: Value.INACTIVE}
+        )
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_line_info.py new file +23 -0
new file mode 100755
index 0000000..e49a669
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of watching for info changes on particular lines."""
+
+import gpiod
+
+
+def watch_line_info(chip_path, line_offsets):
+    with gpiod.Chip(chip_path) as chip:
+        for offset in line_offsets:
+            chip.watch_line_info(offset)
+
+        while True:
+            print(chip.read_info_event())
+
+
+if __name__ == "__main__":
+    try:
+        watch_line_info("/dev/gpiochip0", [5, 3, 7])
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_line_rising.py new file +31 -0
new file mode 100755
index 0000000..2350d76
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of watching for rising edges on a single line."""
+
+import gpiod
+
+from gpiod.line import Edge
+
+
+def watch_line_rising(chip_path, line_offset):
+    with gpiod.request_lines(
+        chip_path,
+        consumer="watch-line-rising",
+        config={line_offset: gpiod.LineSettings(edge_detection=Edge.RISING)},
+    ) as request:
+        while True:
+            # Blocks until at least one event is available
+            for event in request.read_edge_events():
+                print(
+                    "line: %d  type: Rising   event #%d"
+                    % (event.line_offset, event.line_seqno)
+                )
+
+
+if __name__ == "__main__":
+    try:
+        watch_line_rising("/dev/gpiochip0", 5)
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
bindings/python/examples/watch_multiple_line_values.py new file +19 -0
new file mode 100755
index 0000000..4fbf05c
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+
+"""Minimal example of watching for edges on multiple lines."""
+
+import gpiod
+
+from gpiod.line import Edge
+
+
+def edge_type(event):
+    if event.event_type is event.Type.RISING_EDGE:
+        return "Rising"
+    if event.event_type is event.Type.FALLING_EDGE:
+        return "Falling"
+    return "Unknown"
+
+

bindings/python/examples/watch_multiple_line_values.py line 29

Quoted 10 lines
bindings/python/examples/watch_multiple_line_values.py new file +10 -0
+def watch_multiple_line_values(chip_path, line_offsets):
+    with gpiod.request_lines(
+        chip_path,
+        consumer="watch-multiple-line-values",
+        config={tuple(line_offsets): gpiod.LineSettings(edge_detection=Edge.BOTH)},
+    ) as request:
+        while True:
+            for event in request.read_edge_events():
+                print(
+                    "offset: %d  type: %-7s  event #%d  line event #%d"

Could you please stick to the "{}".format() style of output formatting for print() that we already use across the code base? Unless there's a very good reason not to?

Bart

Quoted 17 lines
bindings/python/examples/watch_multiple_line_values.py new file +14 -1
+                    % (
+                        event.line_offset,
+                        edge_type(event),
+                        event.global_seqno,
+                        event.line_seqno,
+                    )
+                )
+
+
+if __name__ == "__main__":
+    try:
+        watch_multiple_line_values("/dev/gpiochip0", [5, 3, 7])
+    except OSError as ex:
+        print(ex, "\nCustomise the example configuration to suit your situation")
--

2.41.0

#8 lore raw

PATCH 7/8 bindings: rust: examples: consistency cleanup

In reply to Kent Gibson

A collection of minor changes to be more consistent with other examples:
- capitalize comments
- add line offset to value outputs
- drop comma from edge event outputs

---
 .../rust/libgpiod/examples/get_line_value.rs    |  4 ++--
 .../rust/libgpiod/examples/toggle_line_value.rs | 17 ++++++++---------
 .../rust/libgpiod/examples/watch_line_value.rs  | 10 +++++-----
 3 files changed, 15 insertions(+), 16 deletions(-)
bindings/rust/libgpiod/examples/get_line_value.rs +2 -2
index 732fb71..39141e2 100644
@@ -6,7 +6,7 @@
 use libgpiod::line;
 
 fn main() -> libgpiod::Result<()> {
-    // example configuration - customize to suit your situation
+    // Example configuration - customize to suit your situation
     let chip_path = "/dev/gpiochip0";
     let line_offset = 5;
 
@@ -23,6 +23,6 @@ fn main() -> libgpiod::Result<()> {
     let request = chip.request_lines(Some(&rconfig), &lconfig)?;
 
     let value = request.value(line_offset)?;
-    println!("{:?}", value);
+    println!("{}={:?}", line_offset, value);
     Ok(())
 }
bindings/rust/libgpiod/examples/toggle_line_value.rs +8 -9
index cd7038e..6d5f697 100644
@@ -3,22 +3,21 @@
 //
 // Minimal example of toggling a single line.
 
-use libgpiod::line;
-use std::time::Duration;
+use core::time::Duration;
+use libgpiod::line::{self, Value};
 
-fn toggle_value(value: line::Value) -> line::Value {
+fn toggle_value(value: Value) -> Value {
     match value {
-        line::Value::Active => line::Value::InActive,
-        line::Value::InActive => line::Value::Active,
+        Value::Active => Value::InActive,
+        Value::InActive => Value::Active,
     }
 }
 
 fn main() -> libgpiod::Result<()> {
-    // example configuration - customize to suit your situation
+    // Example configuration - customize to suit your situation
     let chip_path = "/dev/gpiochip0";
     let line_offset = 5;
-
-    let mut value = line::Value::Active;
+    let mut value = Value::Active;
 
     let mut settings = line::Settings::new()?;
     settings
@@ -35,7 +34,7 @@ fn main() -> libgpiod::Result<()> {
     let mut req = chip.request_lines(Some(&rconfig), &lconfig)?;
 
     loop {
-        println!("{:?}", value);
+        println!("{}={:?}", line_offset, value);
         std::thread::sleep(Duration::from_secs(1));
         value = toggle_value(value);
         req.set_value(line_offset, value)?;
bindings/rust/libgpiod/examples/watch_line_value.rs +5 -5
index 5a95b6a..3bf40af 100644
@@ -7,12 +7,12 @@ use libgpiod::line;
 use std::time::Duration;
 
 fn main() -> libgpiod::Result<()> {
-    // example configuration - customize to suit your situation
+    // Example configuration - customize to suit your situation
     let chip_path = "/dev/gpiochip0";
     let line_offset = 5;
 
     let mut lsettings = line::Settings::new()?;
-    // assume a button connecting the pin to ground,
+    // Assume a button connecting the pin to ground,
     // so pull it up and provide some debounce.
     lsettings
         .set_edge_detection(Some(line::Edge::Both))?
@@ -28,7 +28,7 @@ fn main() -> libgpiod::Result<()> {
     let chip = libgpiod::chip::Chip::open(&chip_path)?;
     let request = chip.request_lines(Some(&rconfig), &lconfig)?;
 
-    // a larger buffer is an optimisation for reading bursts of events from the
+    // A larger buffer is an optimisation for reading bursts of events from the
     // kernel, but that is not necessary in this case, so 1 is fine.
     let mut buffer = libgpiod::request::Buffer::new(1)?;
     loop {
@@ -37,10 +37,10 @@ fn main() -> libgpiod::Result<()> {
         for event in events {
             let event = event?;
             println!(
-                "line: {}, type: {}, event #{}",
+                "line: {}  type: {:<7}  event #{}",
                 event.line_offset(),
                 match event.event_type()? {
-                    line::EdgeKind::Rising => "Rising ",
+                    line::EdgeKind::Rising => "Rising",
                     line::EdgeKind::Falling => "Falling",
                 },
                 event.line_seqno()
Signature · 1 line
2.41.0
#10 lore raw

PATCH 8/8 bindings: rust: examples: replace tools examples with use case examples

In reply to Kent Gibson

Replace tool examples with use case examples drawn from the tools, gpio_events example with buffered_event_lifetimes, and gpio_threaded_info_events with reconfigure_input_to_output.

---
 bindings/rust/libgpiod/examples/Makefile.am   |  21 +--
 .../examples/buffered_event_lifetimes.rs      |  58 ++++++++
 .../libgpiod/examples/find_line_by_name.rs    |  29 ++++
 .../rust/libgpiod/examples/get_chip_info.rs   |  22 +++
 .../rust/libgpiod/examples/get_line_info.rs   |  37 +++++
 .../examples/get_multiple_line_values.rs      |  29 ++++
 .../rust/libgpiod/examples/gpio_events.rs     |  88 ------------
 .../examples/gpio_threaded_info_events.rs     | 132 ------------------
 bindings/rust/libgpiod/examples/gpiodetect.rs |  30 ----
 bindings/rust/libgpiod/examples/gpiofind.rs   |  36 -----
 bindings/rust/libgpiod/examples/gpioget.rs    |  45 ------
 bindings/rust/libgpiod/examples/gpioinfo.rs   |  97 -------------
 bindings/rust/libgpiod/examples/gpiomon.rs    |  74 ----------
 bindings/rust/libgpiod/examples/gpionotify.rs |  53 -------
 bindings/rust/libgpiod/examples/gpioset.rs    |  63 ---------
 bindings/rust/libgpiod/examples/gpiowatch.rs  |  53 -------
 .../examples/reconfigure_input_to_output.rs   |  42 ++++++
 .../examples/toggle_multiple_line_values.rs   |  55 ++++++++
 .../rust/libgpiod/examples/watch_line_info.rs |  32 +++++
 .../libgpiod/examples/watch_line_rising.rs    |  44 ++++++
 .../examples/watch_multiple_line_values.rs    |  46 ++++++
 21 files changed, 405 insertions(+), 681 deletions(-)
 create mode 100644 bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs
 create mode 100644 bindings/rust/libgpiod/examples/find_line_by_name.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_chip_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_multiple_line_values.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpionotify.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
 create mode 100644 bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs
 create mode 100644 bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_rising.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_multiple_line_values.rs
bindings/rust/libgpiod/examples/Makefile.am +11 -10
index b3338bd..ea1826f 100644
@@ -3,16 +3,17 @@
 # SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <[email protected]>
 
 EXTRA_DIST = \
+	buffered_event_lifetimes.rs \
+	find_line_by_name.rs \
+	get_chip_info.rs \
+	get_line_info.rs \
 	get_line_value.rs \
-	gpiodetect.rs \
-	gpio_events.rs \
-	gpiofind.rs \
-	gpioget.rs \
-	gpioinfo.rs \
-	gpiomon.rs \
-	gpionotify.rs \
-	gpioset.rs \
+	get_multiple_line_values.rs \
 	gpio_threaded_info_events.rs \
-	gpiowatch.rs \
+	reconfigure_input_to_output \
 	toggle_line_value.rs \
-	watch_line_value.rs
+	toggle_multiple_line_values.rs \
+	watch_line_info.rs \
+	watch_line_rising.rs \
+	watch_line_value.rs \
+	watch_multiple_line_values.rs
bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs new file +58 -0

58 lines not on this page · raw message

bindings/rust/libgpiod/examples/find_line_by_name.rs new file +29 -0
new file mode 100644
index 0000000..f7b9919
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+//
+// Minimal example of finding a line with the given name.
+
+fn main() -> libgpiod::Result<()> {
+    // Example configuration - customize to suit your situation
+    let line_name = "GPIO19";
+
+    // Names are not guaranteed unique, so this finds the first line with
+    // the given name.
+    for chip in libgpiod::gpiochip_devices(&"/dev")? {
+        let offset = chip.line_offset_from_name(line_name);
+
+        if offset.is_ok() {
+            let info = chip.info()?;
+            println!(
+                "{}: {} {}",
+                line_name,
+                info.name()?,
+                offset?
+            );
+            return Ok(());
+        }
+    }
+
+    println!("line '{}' not found", line_name);
+    Ok(())
+}
bindings/rust/libgpiod/examples/get_chip_info.rs new file +22 -0
new file mode 100644
index 0000000..cc23c86
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+//
+// Minimal example of reading the info for a chip.
+
+use libgpiod::{self, Result};
+
+fn main() -> Result<()> {
+    // Example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    let info = chip.info()?;
+    println!(
+        "{} [{}] ({} lines)",
+        info.name()?,
+        info.label()?,
+        info.num_lines(),
+    );
+
+    Ok(())
+}
bindings/rust/libgpiod/examples/get_line_info.rs new file +37 -0
new file mode 100644
index 0000000..086db90
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+//
+// Minimal example of reading the info for a line.
+
+use libgpiod::line::Direction;
+
+fn main() -> libgpiod::Result<()> {
+    // Example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offset = 3;
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    let info = chip.line_info(line_offset)?;
+
+    let name = info.name().unwrap_or("unnamed");
+    let consumer = info.consumer().unwrap_or("unused");
+
+    let dir = match info.direction()? {
+        Direction::AsIs => "none",
+        Direction::Input => "input",
+        Direction::Output => "output",
+    };
+
+    let low = if info.is_active_low() {
+        "active-low"
+    } else {
+        "active-high"
+    };
+
+    println!(
+        "line {:>3}: {:>12} {:>12} {:>8} {:>10}",
+        line_offset, name, consumer, dir, low
+    );
+
+    Ok(())
+}
bindings/rust/libgpiod/examples/get_multiple_line_values.rs new file +29 -0
new file mode 100644
index 0000000..a1be5a6
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+//
+// Minimal example of reading multiple lines.
+
+use libgpiod::line::{self, Direction};
+
+fn main() -> libgpiod::Result<()> {
+    // Example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offsets = [5, 3, 7];
+
+    let mut lsettings = line::Settings::new()?;
+    let mut lconfig = line::Config::new()?;
+
+    lsettings.set_direction(Direction::Input)?;
+    lconfig.add_line_settings(&line_offsets, lsettings)?;
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+
+    let mut rconfig = libgpiod::request::Config::new()?;
+    rconfig.set_consumer("get-multiple-line-values")?;
+
+    let request = chip.request_lines(Some(&rconfig), &lconfig)?;
+    let values = request.values()?;
+
+    println!("{:?}", values);
+    Ok(())
+}
bindings/rust/libgpiod/examples/gpio_events.rs deleted +0 -88

88 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs deleted +0 -132

132 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpiodetect.rs deleted +0 -30
deleted file mode 100644
index 9792252..0000000
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
-// SPDX-FileCopyrightText: 2022 Linaro Ltd.
-// SPDX-FileCopyrightText: 2022 Viresh Kumar <[email protected]>
-//
-// Simplified Rust implementation of gpiodetect tool.
-
-use std::env;
-use std::path::Path;
-
-use libgpiod::{self, Error, Result};
-
-fn main() -> Result<()> {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 {
-        println!("Usage: {}", args[0]);
-        return Err(Error::InvalidArguments);
-    }
-
-    for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? {
-        let info = chip.info()?;
-        println!(
-            "{} [{}] ({})",
-            info.name()?,
-            info.label()?,
-            info.num_lines(),
-        );
-    }
-
-    Ok(())
-}
bindings/rust/libgpiod/examples/gpiofind.rs deleted +0 -36
deleted file mode 100644
index da0530d..0000000
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
-// SPDX-FileCopyrightText: 2022 Linaro Ltd.
-// SPDX-FileCopyrightText: 2022 Viresh Kumar <[email protected]>
-//
-// Simplified Rust implementation of gpiofind tool.
-
-use std::env;
-use std::path::Path;
-
-use libgpiod::{self, Error, Result};
-
-fn main() -> Result<()> {
-    let args: Vec<String> = env::args().collect();
-    if args.len() != 2 {
-        println!("Usage: {} <line-name>", args[0]);
-        return Err(Error::InvalidArguments);
-    }
-
-    for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? {
-        let offset = chip.line_offset_from_name(&args[1]);
-        let info = chip.info()?;
-
-        if offset.is_ok() {
-            println!(
-                "Line {} found: Chip: {}, offset: {}",
-                args[1],
-                info.name()?,
-                offset?
-            );
-            return Ok(());
-        }
-    }
-
-    println!("Failed to find line: {}", args[1]);
-    Ok(())
-}
bindings/rust/libgpiod/examples/gpioget.rs deleted +0 -45

45 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpioinfo.rs deleted +0 -97

97 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpiomon.rs deleted +0 -74

74 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpionotify.rs deleted +0 -53

53 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpioset.rs deleted +0 -63

63 lines not on this page · raw message

bindings/rust/libgpiod/examples/gpiowatch.rs deleted +0 -53

53 lines not on this page · raw message

bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs new file +42 -0

42 lines not on this page · raw message

bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs new file +55 -0

55 lines not on this page · raw message

bindings/rust/libgpiod/examples/watch_line_info.rs new file +32 -0
new file mode 100644
index 0000000..e84ce13
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
+//
+// Minimal example of watching for info changes on particular lines.
+
+use libgpiod::line::InfoChangeKind;
+
+fn main() -> libgpiod::Result<()> {
+    // Example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offsets = [5, 3, 7];
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    for offset in line_offsets {
+        let _info = chip.watch_line_info(offset)?;
+    }
+
+    loop {
+        // Blocks until at least one event is available.
+        let event = chip.read_info_event()?;
+        println!(
+            "line: {} {:<9} {:?}",
+            event.line_info()?.offset(),
+            match event.event_type()? {
+                InfoChangeKind::LineRequested => "Requested",
+                InfoChangeKind::LineReleased => "Released",
+                InfoChangeKind::LineConfigChanged => "Reconfig",
+            },
+            event.timestamp()
+        );
+    }
+}
bindings/rust/libgpiod/examples/watch_line_rising.rs new file +44 -0

44 lines not on this page · raw message

bindings/rust/libgpiod/examples/watch_multiple_line_values.rs new file +46 -0

46 lines not on this page · raw message

Signature · 1 line
2.41.0
Reviewed-by on v1 8/8
#11 lore raw

Re: [libgpiod][PATCH 8/8] bindings: rust: examples: replace tools examples with use case examples

Quoted 5 lines · Kent Gibson

Replace tool examples with use case examples drawn from the tools, gpio_events example with buffered_event_lifetimes, and gpio_threaded_info_events with reconfigure_input_to_output.

Quoted 1 line
    let mut buffer = libgpiod::request::Buffer::new(4)?;

Slightly tangential:

Maybe the API should provide some sensible defaults for the buffer size? (Or just set a sane default and provide ways to override it)? The change from 1 -> 4 for bulk operations seems reasonable, but I feel like a user just getting started with all of this likely won't know what might be good values to pick...

- Erik

#12 lore raw

Re: [libgpiod][PATCH 8/8] bindings: rust: examples: replace tools examples with use case examples

Quoted 11 lines · Erik Schilling
Quoted 5 lines · Kent Gibson

Replace tool examples with use case examples drawn from the tools, gpio_events example with buffered_event_lifetimes, and gpio_threaded_info_events with reconfigure_input_to_output.

Quoted 1 line
    let mut buffer = libgpiod::request::Buffer::new(4)?;
Quoted 8 lines

Slightly tangential:

Maybe the API should provide some sensible defaults for the buffer size? (Or just set a sane default and provide ways to override it)? The change from 1 -> 4 for bulk operations seems reasonable, but I feel like a user just getting started with all of this likely won't know what might be good values to pick...

The C API does that - it defaults to 64, IIRC - if you pass in 0. And the Rust will do the same - read the docs:

    /// Create a new edge event buffer.
    ///
    /// If capacity equals 0, it will be set to a default value of 64. If
    /// capacity is larger than 1024, it will be limited to 1024.

Using 64 seems excessive to me, so I explictly set more reasonable sizes in the examples.

Btw a casual user is probably fine with 1 - the events will still be buffered in the kernel so the only advantages of > 1 is to reduce the number of reads when handling bursts, and so drain the kernel buffer slightly quicker. I expect that the only users who would see an appreciable difference in behaviour with different userspace buffer sizes probably have a good idea why they want to be setting it. Again, would be good to document that - if it isn't already.

Cheers,
Kent.

#13 lore raw
In reply to Kent Gibson
Quoted 205 lines · Kent Gibson

This series is the continuation of providing a set of use case based examples for libgpiod. The focus of this series is replacement of the examples replicating the the tools with examples that minimally cover the use case that each tool addresses.

The mapping from tool to use case is:

  gpiodetect  ->  get_chip_info
  gpiofind    ->  find_line_by_name
  gpioget     ->  get_multiple_line_values
  gpioinfo    ->  get_line_info
  gpiomon     ->  watch_multiple_line_values
  gpionotify  ->  watch_line_info
  gpioset     ->  toggle_multiple_line_values

Also added a watch_line_rising example to demonstrate getting events from only one edge rather than both, so another gpiomon sub-case.

The rust bindings had a couple of additional examples, gpio_events and gpio_threaded_info_events.

gpio_threaded_info_events is an example of using one thread to generate info change events that are observed by another thread. This is borrowed from test cases and has no other practical application, but the reconfiguring component inspired the reconfigure_input_to_output example. That provides an example of reconfiguring a requested line, and is provided for all languages, not just rust.

gpio_events is an example of how borrowed buffered events must be cloned before the event buffer can be reused. This was simplified and renamed buffered_event_lifetimes. As I write this I realise it may also be applicable to other languages - as an example of using gpiod_edge_event_copy(). Maybe provide those in v2, or a subsequent series?

The series is split into 8 parts. For each language there is a patch that provides some consistency cleanups to make the existing examples more consistent with each other, with the examples in other languages, and with the examples to follow. There are also a few minor bug fixes that didn't seem sufficiently serious to warrant a separate patch.

The second patch for each language replaces the old tool examples with the new use case based examples.

Cheers,
Kent.

Kent Gibson (8):
core: examples: consistency cleanups
core: examples: add more use case examples
bindings: cxx: examples: consistency cleanup
bindings: cxx: examples: replace tools examples with use case examples
bindings: python: examples: consistency cleanup
bindings: python: examples: replace tools examples with use case
examples
bindings: rust: examples: consistency cleanup
bindings: rust: examples: replace tools examples with use case
examples

 bindings/cxx/examples/.gitignore              |  16 +-
 bindings/cxx/examples/Makefile.am             |  42 ++---
 .../cxx/examples/async_watch_line_value.cpp   |   8 +-
 bindings/cxx/examples/find_line_by_name.cpp   |  42 +++++
 bindings/cxx/examples/get_chip_info.cpp       |  27 ++++
 bindings/cxx/examples/get_line_info.cpp       |  39 +++++
 bindings/cxx/examples/get_line_value.cpp      |  28 ++--
 .../cxx/examples/get_multiple_line_values.cpp |  40 +++++
 bindings/cxx/examples/gpiodetectcxx.cpp       |  30 ----
 bindings/cxx/examples/gpiofindcxx.cpp         |  32 ----
 bindings/cxx/examples/gpiogetcxx.cpp          |  40 -----
 bindings/cxx/examples/gpioinfocxx.cpp         |  61 -------
 bindings/cxx/examples/gpiomoncxx.cpp          |  65 --------
 bindings/cxx/examples/gpionotifycxx.cpp       |  55 -------
 bindings/cxx/examples/gpiosetcxx.cpp          |  53 ------
 .../examples/reconfigure_input_to_output.cpp  |  56 +++++++
 bindings/cxx/examples/toggle_line_value.cpp   |  16 +-
 .../examples/toggle_multiple_line_values.cpp  |  63 ++++++++
 bindings/cxx/examples/watch_line_info.cpp     |  49 ++++++
 bindings/cxx/examples/watch_line_rising.cpp   |  64 ++++++++
 bindings/cxx/examples/watch_line_value.cpp    |  12 +-
 .../examples/watch_multiple_line_values.cpp   |  60 +++++++
 bindings/python/examples/Makefile.am          |  18 ++-
 .../python/examples/async_watch_line_value.py |  15 +-
 bindings/python/examples/find_line_by_name.py |  37 +++++
 bindings/python/examples/get_chip_info.py     |  20 +++
 bindings/python/examples/get_line_info.py     |  29 ++++
 bindings/python/examples/get_line_value.py    |  13 +-
 .../examples/get_multiple_line_values.py      |  29 ++++
 bindings/python/examples/gpiodetect.py        |  15 --
 bindings/python/examples/gpiofind.py          |  20 ---
 bindings/python/examples/gpioget.py           |  29 ----
 bindings/python/examples/gpioinfo.py          |  28 ----
 bindings/python/examples/gpiomon.py           |  26 ---
 bindings/python/examples/gpionotify.py        |  21 ---
 bindings/python/examples/gpioset.py           |  36 -----
 bindings/python/examples/helpers.py           |  15 --
 .../examples/reconfigure_input_to_output.py   |  39 +++++
 bindings/python/examples/toggle_line_value.py |  34 ++--
 .../examples/toggle_multiple_line_values.py   |  47 ++++++
 bindings/python/examples/watch_line_info.py   |  23 +++
 bindings/python/examples/watch_line_rising.py |  31 ++++
 bindings/python/examples/watch_line_value.py  |  19 ++-
 .../examples/watch_multiple_line_values.py    |  43 +++++
 bindings/rust/libgpiod/examples/Makefile.am   |  21 +--
 .../examples/buffered_event_lifetimes.rs      |  58 +++++++
 .../libgpiod/examples/find_line_by_name.rs    |  29 ++++
 .../rust/libgpiod/examples/get_chip_info.rs   |  22 +++
 .../rust/libgpiod/examples/get_line_info.rs   |  37 +++++
 .../rust/libgpiod/examples/get_line_value.rs  |   4 +-
 .../examples/get_multiple_line_values.rs      |  29 ++++
 .../rust/libgpiod/examples/gpio_events.rs     |  88 ----------
 .../examples/gpio_threaded_info_events.rs     | 132 ---------------
 bindings/rust/libgpiod/examples/gpiodetect.rs |  30 ----
 bindings/rust/libgpiod/examples/gpiofind.rs   |  36 -----
 bindings/rust/libgpiod/examples/gpioget.rs    |  45 ------
 bindings/rust/libgpiod/examples/gpioinfo.rs   |  97 -----------
 bindings/rust/libgpiod/examples/gpiomon.rs    |  74 ---------
 bindings/rust/libgpiod/examples/gpionotify.rs |  53 ------
 bindings/rust/libgpiod/examples/gpioset.rs    |  63 --------
 bindings/rust/libgpiod/examples/gpiowatch.rs  |  53 ------
 .../examples/reconfigure_input_to_output.rs   |  42 +++++
 .../libgpiod/examples/toggle_line_value.rs    |  17 +-
 .../examples/toggle_multiple_line_values.rs   |  55 +++++++
 .../rust/libgpiod/examples/watch_line_info.rs |  32 ++++
 .../libgpiod/examples/watch_line_rising.rs    |  44 +++++
 .../libgpiod/examples/watch_line_value.rs     |  10 +-
 .../examples/watch_multiple_line_values.rs    |  46 ++++++
 examples/.gitignore                           |   9 ++
 examples/Makefile.am                          |  35 +++-
 examples/async_watch_line_value.c             |   6 +-
 examples/find_line_by_name.c                  | 111 +++++++++++++
 examples/get_chip_info.c                      |  40 +++++
 examples/get_line_info.c                      |  56 +++++++
 examples/get_line_value.c                     |  11 +-
 examples/get_multiple_line_values.c           | 119 ++++++++++++++
 examples/reconfigure_input_to_output.c        | 152 ++++++++++++++++++
 examples/toggle_line_value.c                  |  17 +-
 examples/toggle_multiple_line_values.c        | 136 ++++++++++++++++
 examples/watch_line_info.c                    |  72 +++++++++
 examples/watch_line_rising.c                  | 129 +++++++++++++++
 examples/watch_line_value.c                   |   6 +-
 examples/watch_multiple_line_values.c         | 140 ++++++++++++++++
 83 files changed, 2289 insertions(+), 1352 deletions(-)
 create mode 100644 bindings/cxx/examples/find_line_by_name.cpp
 create mode 100644 bindings/cxx/examples/get_chip_info.cpp
 create mode 100644 bindings/cxx/examples/get_line_info.cpp
 create mode 100644 bindings/cxx/examples/get_multiple_line_values.cpp
 delete mode 100644 bindings/cxx/examples/gpiodetectcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiofindcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiogetcxx.cpp
 delete mode 100644 bindings/cxx/examples/gpioinfocxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiomoncxx.cpp
 delete mode 100644 bindings/cxx/examples/gpionotifycxx.cpp
 delete mode 100644 bindings/cxx/examples/gpiosetcxx.cpp
 create mode 100644 bindings/cxx/examples/reconfigure_input_to_output.cpp
 create mode 100644 bindings/cxx/examples/toggle_multiple_line_values.cpp
 create mode 100644 bindings/cxx/examples/watch_line_info.cpp
 create mode 100644 bindings/cxx/examples/watch_line_rising.cpp
 create mode 100644 bindings/cxx/examples/watch_multiple_line_values.cpp
 create mode 100755 bindings/python/examples/find_line_by_name.py
 create mode 100755 bindings/python/examples/get_chip_info.py
 create mode 100755 bindings/python/examples/get_line_info.py
 create mode 100755 bindings/python/examples/get_multiple_line_values.py
 delete mode 100755 bindings/python/examples/gpiodetect.py
 delete mode 100755 bindings/python/examples/gpiofind.py
 delete mode 100755 bindings/python/examples/gpioget.py
 delete mode 100755 bindings/python/examples/gpioinfo.py
 delete mode 100755 bindings/python/examples/gpiomon.py
 delete mode 100755 bindings/python/examples/gpionotify.py
 delete mode 100755 bindings/python/examples/gpioset.py
 delete mode 100644 bindings/python/examples/helpers.py
 create mode 100755 bindings/python/examples/reconfigure_input_to_output.py
 create mode 100755 bindings/python/examples/toggle_multiple_line_values.py
 create mode 100755 bindings/python/examples/watch_line_info.py
 create mode 100755 bindings/python/examples/watch_line_rising.py
 create mode 100755 bindings/python/examples/watch_multiple_line_values.py
 create mode 100644 bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs
 create mode 100644 bindings/rust/libgpiod/examples/find_line_by_name.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_chip_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/get_multiple_line_values.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioget.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpionotify.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpioset.rs
 delete mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs
 create mode 100644 bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs
 create mode 100644 bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_info.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_rising.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_multiple_line_values.rs
 create mode 100644 examples/find_line_by_name.c
 create mode 100644 examples/get_chip_info.c
 create mode 100644 examples/get_line_info.c
 create mode 100644 examples/get_multiple_line_values.c
 create mode 100644 examples/reconfigure_input_to_output.c
 create mode 100644 examples/toggle_multiple_line_values.c
 create mode 100644 examples/watch_line_info.c
 create mode 100644 examples/watch_line_rising.c
 create mode 100644 examples/watch_multiple_line_values.c
Quoted 3 lines

--
2.41.0

Thanks! I applied patches 1-5 and 7-8. I had some comments on patch 6, you don't have to resend the others.

Bart