Skip to contentSkip to conversation

tools: improvements for v2

PATCH Superseded Kent Gibson 1 participant 7 messages Jul 8, 2022 GPIO

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover tools: improvements for v2

This patch series is an optimistic reimagining of the tools intended to simplify usage for well configured systems, i.e. for systems where lines can be uniquely identified by name. In such systems the chip and offset location of the line is no longer of relevance to the user, so the tools should be able to operate without mentioning them.
e.g.
gpioget GPIO17

gpioset GPIO17=active

  gpiomon --localtime GPIO17 GPIO18 

It is accepted that the kernel does not guarantee line name uniqueness within the system, or even within a chip, and not all systems are well configured, so the tools retain the option to identify lines by chip and offset. The hope and expectation is that over time systems will become more well configured, not less, and identification of GPIO lines by name will become the norm.

The core of the series is patch 1 which is a reworking of the tools to support identifying lines by name, and to operate across multiple GPIO chips if named lines are located on different chips.
The gpioset tool is extended to support toggling lines and interactive control of line values, so some common use cases can be trivially implemented from the command line.
e.g.
gpioset --toggle 500ms LED=on

will blink the LED line at 1Hz, indefinitely.
More complex outputs can be generated by adding more entries to the toggle sequence:
gpioset --toggle 1s,2s,1s,300ms LED=on

Even more complex outputs can be generated by driving gpioset in interactive mode from another script.

Those are the major changes. A more complete list of the changes can be found in the patch description.

The core tool changes are contained in patch 2. To simplify review, patch 1 removes old code replaced by that in patch 2 and 3.

Patch 3 updates and extends the tool tests to cover the reworked tools, including demonstrating gpioset being driven interactively via a script.

Patch 4 adds a gpiowatch tool that monitors changes to the state line information, similar to the gpio-watch tool in the kernel, and patch 5 extends the test suite to cover it.

Patch 6 removes the gpiofind tool, as the other tools now perform the name to offset search themselves.

Cheers,
Kent.

Changes V1 -> v2:
- code formatting, particularly trying to keep to the 80 character limit and C style comments.
- move global config fields into the struct config for each tool.
- switch gpioset from readline to libedit.
- add tests for symlink chip path behaviour.
- long lived tools flush stdout before blocking.
- fix copyrights
- replace gpiosim attr lookup functions with cached values.
- remove gpiofind

Kent Gibson (6):
tools: remove old code to simplify review
tools: line name focussed rework
tools: tests for line name focussed rework
tools: add gpiowatch
tools: gpiowatch tests
tools: remove gpiofind

 configure.ac               |    8 +-
 man/Makefile.am            |    2 +-
 tools/.gitignore           |    1 +
 tools/Makefile.am          |    6 +-
 tools/gpio-tools-test      |    3 -
 tools/gpio-tools-test.bats | 2639 +++++++++++++++++++++++++++---------
 tools/gpiodetect.c         |  122 +-
 tools/gpiofind.c           |   93 --
 tools/gpioget.c            |  214 +--
 tools/gpioinfo.c           |  363 +++--
 tools/gpiomon.c            |  524 ++++---
 tools/gpioset.c            |  944 +++++++++----
 tools/gpiowatch.c          |  231 ++++
 tools/tools-common.c       |  679 +++++++++-
 tools/tools-common.h       |   63 +-
 15 files changed, 4355 insertions(+), 1537 deletions(-)
 delete mode 100644 tools/gpiofind.c
 create mode 100644 tools/gpiowatch.c
Signature · 1 line
2.37.0
#1 lore raw

PATCH v2 1/6 tools: remove old code to simplify review

Remove functions that are so heavily modified in the subsequent patch that they are effectively complete re-writes, so the old code just obfuscates the new.

---
 tools/gpio-tools-test.bats | 893 -------------------------------------
 tools/gpiodetect.c         |  79 ----
 tools/gpiofind.c           |  80 ----
 tools/gpioget.c            | 140 ------
 tools/gpioinfo.c           | 240 ----------
 tools/gpiomon.c            | 301 -------------
 tools/gpioset.c            | 315 -------------
 tools/tools-common.c       |  68 ---
 8 files changed, 2116 deletions(-)
tools/gpio-tools-test.bats +0 -893
index 69ad786..d200df1 100755
@@ -220,896 +220,3 @@ teardown() {
 	gpiosim_cleanup
 }
 
-#
-# gpiodetect test cases
-#
-
-@test "gpiodetect: list chips" {
-	gpiosim_chip sim0 num_lines=4
-	gpiosim_chip sim1 num_lines=8
-	gpiosim_chip sim2 num_lines=16
-
-	run_tool gpiodetect
-
-	test "$status" -eq 0
-	output_contains_line "$(gpiosim_chip_name sim0) [$(gpiosim_dev_name sim0)-node0] (4 lines)"
-	output_contains_line "$(gpiosim_chip_name sim1) [$(gpiosim_dev_name sim1)-node0] (8 lines)"
-	output_contains_line "$(gpiosim_chip_name sim2) [$(gpiosim_dev_name sim2)-node0] (16 lines)"
-}
-
-@test "gpiodetect: invalid args" {
-	run_tool gpiodetect unimplemented-arg
-	test "$status" -eq 1
-}
-
-#
-# gpioinfo test cases
-#
-
-@test "gpioinfo: dump all chips" {
-	gpiosim_chip sim0 num_lines=4
-	gpiosim_chip sim1 num_lines=8
-
-	run_tool gpioinfo
-
-	test "$status" -eq 0
-	output_contains_line "$(gpiosim_chip_name sim0) - 4 lines:"
-	output_contains_line "$(gpiosim_chip_name sim1) - 8 lines:"
-
-	output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-	output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-}
-
-@test "gpioinfo: dump all chips with one line exported" {
-	gpiosim_chip sim0 num_lines=4
-	gpiosim_chip sim1 num_lines=8
-
-	coproc_run_tool gpioset --mode=signal --active-low "$(gpiosim_chip_name sim1)" 7=1
-
-	run_tool gpioinfo
-
-	test "$status" -eq 0
-	output_contains_line "$(gpiosim_chip_name sim0) - 4 lines:"
-	output_contains_line "$(gpiosim_chip_name sim1) - 8 lines:"
-	output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-	output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+\\\"gpioset\\\"\\s+output\\s+active-low"
-
-	coproc_tool_kill
-	coproc_tool_wait
-}
-
-@test "gpioinfo: dump one chip" {
-	gpiosim_chip sim0 num_lines=8
-	gpiosim_chip sim1 num_lines=4
-
-	run_tool gpioinfo "$(gpiosim_chip_name sim1)"
-
-	test "$status" -eq 0
-	assert_fail output_contains_line "$(gpiosim_chip_name sim0) - 8 lines:"
-	output_contains_line "$(gpiosim_chip_name sim1) - 4 lines:"
-	output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-	assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-}
-
-@test "gpioinfo: dump all but one chip" {
-	gpiosim_chip sim0 num_lines=4
-	gpiosim_chip sim1 num_lines=4
-	gpiosim_chip sim2 num_lines=8
-	gpiosim_chip sim3 num_lines=4
-
-	run_tool gpioinfo "$(gpiosim_chip_name sim0)" \
-			"$(gpiosim_chip_name sim1)" "$(gpiosim_chip_name sim3)"
-
-	test "$status" -eq 0
-	output_contains_line "$(gpiosim_chip_name sim0) - 4 lines:"
-	output_contains_line "$(gpiosim_chip_name sim1) - 4 lines:"
-	assert_fail output_contains_line "$(gpiosim_chip_name sim2) - 8 lines:"
-	output_contains_line "$(gpiosim_chip_name sim3) - 4 lines:"
-	output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-	assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
-}
-
-@test "gpioinfo: inexistent chip" {
-	run_tool gpioinfo "inexistent"
-
-	test "$status" -eq 1
-}
-
-#
-# gpiofind test cases
-#
-
-@test "gpiofind: line found" {
-	gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=3:bar
-	gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz line_name=7:foobar
-	gpiosim_chip sim2 num_lines=16
-
-	run_tool gpiofind foobar
-
-	test "$status" -eq "0"
-	test "$output" = "$(gpiosim_chip_name sim1) 7"
-}
-
-@test "gpiofind: line not found" {
-	gpiosim_chip sim0 num_lines=4
-	gpiosim_chip sim1 num_lines=8
-	gpiosim_chip sim2 num_lines=16
-
-	run_tool gpiofind nonexistent-line
-
-	test "$status" -eq "1"
-}
-
-@test "gpiofind: invalid args" {
-	run_tool gpiodetect unimplemented-arg
-	test "$status" -eq 1
-}
-
-#
-# gpioget test cases
-#
-
-@test "gpioget: read all lines" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	run_tool gpioget "$(gpiosim_chip_name sim0)" 0 1 2 3 4 5 6 7
-
-	test "$status" -eq "0"
-	test "$output" = "0 0 1 1 0 1 0 1"
-}
-
-@test "gpioget: read all lines (active-low)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	run_tool gpioget --active-low "$(gpiosim_chip_name sim0)" 0 1 2 3 4 5 6 7
-
-	test "$status" -eq "0"
-	test "$output" = "1 1 0 0 1 0 1 0"
-}
-
-@test "gpioget: read all lines (pull-up)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	run_tool gpioget --bias=pull-up "$(gpiosim_chip_name sim0)" 0 1 2 3 4 5 6 7
-
-	test "$status" -eq "0"
-	test "$output" = "1 1 1 1 1 1 1 1"
-}
-
-@test "gpioget: read all lines (pull-down)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	run_tool gpioget --bias=pull-down "$(gpiosim_chip_name sim0)" 0 1 2 3 4 5 6 7
-
-	test "$status" -eq "0"
-	test "$output" = "0 0 0 0 0 0 0 0"
-}
-
-@test "gpioget: read some lines" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 1 pull-up
-	gpiosim_set_pull sim0 4 pull-up
-	gpiosim_set_pull sim0 6 pull-up
-
-	run_tool gpioget "$(gpiosim_chip_name sim0)" 0 1 4 6
-
-	test "$status" -eq "0"
-	test "$output" = "0 1 1 1"
-}
-
-@test "gpioget: no arguments" {
-	run_tool gpioget
-
-	test "$status" -eq "1"
-	output_regex_match ".*gpiochip must be specified"
-}
-
-@test "gpioget: no lines specified" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioget "$(gpiosim_chip_name sim0)"
-
-	test "$status" -eq "1"
-	output_regex_match ".*at least one GPIO line offset must be specified"
-}
-
-@test "gpioget: too many lines specified" {
-	gpiosim_chip sim0 num_lines=4
-
-	run_tool gpioget "$(gpiosim_chip_name sim0)" 0 1 2 3 4
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines.*"
-}
-
-@test "gpioget: same line twice" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioget "$(gpiosim_chip_name sim0)" 0 0
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines"
-}
-
-@test "gpioget: invalid bias" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioget --bias=bad "$(gpiosim_chip_name sim0)" 0 1
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid bias.*"
-}
-
-#
-# gpioset test cases
-#
-
-@test "gpioset: set lines and wait for SIGTERM" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpioset --mode=signal "$(gpiosim_chip_name sim0)" \
-					0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 0 0
-	gpiosim_check_value sim0 1 0
-	gpiosim_check_value sim0 2 1
-	gpiosim_check_value sim0 3 1
-	gpiosim_check_value sim0 4 1
-	gpiosim_check_value sim0 5 1
-	gpiosim_check_value sim0 6 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set lines and wait for SIGTERM (active-low)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpioset --active-low --mode=signal "$(gpiosim_chip_name sim0)" \
-					0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 0 1
-	gpiosim_check_value sim0 1 1
-	gpiosim_check_value sim0 2 0
-	gpiosim_check_value sim0 3 0
-	gpiosim_check_value sim0 4 0
-	gpiosim_check_value sim0 5 0
-	gpiosim_check_value sim0 6 1
-	gpiosim_check_value sim0 7 0
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set lines and wait for SIGTERM (push-pull)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpioset --drive=push-pull --mode=signal "$(gpiosim_chip_name sim0)" \
-					0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 0 0
-	gpiosim_check_value sim0 1 0
-	gpiosim_check_value sim0 2 1
-	gpiosim_check_value sim0 3 1
-	gpiosim_check_value sim0 4 1
-	gpiosim_check_value sim0 5 1
-	gpiosim_check_value sim0 6 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set lines and wait for SIGTERM (open-drain)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	coproc_run_tool gpioset --drive=open-drain --mode=signal "$(gpiosim_chip_name sim0)" \
-					0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 0 0
-	gpiosim_check_value sim0 1 0
-	gpiosim_check_value sim0 2 1
-	gpiosim_check_value sim0 3 1
-	gpiosim_check_value sim0 4 0
-	gpiosim_check_value sim0 5 1
-	gpiosim_check_value sim0 6 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set lines and wait for SIGTERM (open-source)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 5 pull-up
-	gpiosim_set_pull sim0 7 pull-up
-
-	coproc_run_tool gpioset --drive=open-source --mode=signal "$(gpiosim_chip_name sim0)" \
-					0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 0 0
-	gpiosim_check_value sim0 1 0
-	gpiosim_check_value sim0 2 1
-	gpiosim_check_value sim0 3 1
-	gpiosim_check_value sim0 4 1
-	gpiosim_check_value sim0 5 1
-	gpiosim_check_value sim0 6 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set some lines and wait for ENTER" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpioset --mode=wait "$(gpiosim_chip_name sim0)" \
-					1=0 2=1 5=1 6=0 7=1
-
-	gpiosim_check_value sim0 1 0
-	gpiosim_check_value sim0 2 1
-	gpiosim_check_value sim0 5 1
-	gpiosim_check_value sim0 6 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_stdin_write ""
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set some lines and wait for SIGINT" {
-	gpiosim_chip sim0 num_lines=4
-
-	coproc_run_tool gpioset --mode=signal "$(gpiosim_chip_name sim0)" 0=1
-
-	gpiosim_check_value sim0 0 1
-
-	coproc_tool_kill -SIGINT
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: set some lines and wait with --mode=time" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpioset --mode=time --sec=1 --usec=200000 \
-				"$(gpiosim_chip_name sim0)" 0=1 5=0 7=1
-
-	gpiosim_check_value sim0 0 1
-	gpiosim_check_value sim0 5 0
-	gpiosim_check_value sim0 7 1
-
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: no arguments" {
-	run_tool gpioset
-
-	test "$status" -eq "1"
-	output_regex_match ".*gpiochip must be specified"
-}
-
-@test "gpioset: no lines specified" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim1)"
-
-	test "$status" -eq "1"
-	output_regex_match ".*at least one GPIO line offset to value mapping must be specified"
-}
-
-@test "gpioset: too many lines specified" {
-	gpiosim_chip sim0 num_lines=4
-
-	run_tool gpioset "$(gpiosim_chip_name sim0)" 0=1 1=1 2=1 3=1 4=1 5=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines.*"
-}
-
-@test "gpioset: use --sec without --mode=time" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset --mode=exit --sec=1 "$(gpiosim_chip_name sim0)" 0=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*can't specify wait time in this mode"
-}
-
-@test "gpioset: use --usec without --mode=time" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset --mode=exit --usec=1 "$(gpiosim_chip_name sim1)" 0=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*can't specify wait time in this mode"
-}
-
-@test "gpioset: default mode" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim0)" 0=1
-
-	test "$status" -eq "0"
-}
-
-@test "gpioset: invalid mapping" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim1)" 0=c
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid offset<->value mapping"
-}
-
-@test "gpioset: invalid value" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim1)" 0=3
-
-	test "$status" -eq "1"
-	output_regex_match ".*value must be 0 or 1"
-}
-
-@test "gpioset: invalid offset" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim1)" 4000000000=0
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid offset"
-}
-
-@test "gpioset: invalid bias" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset --bias=bad "$(gpiosim_chip_name sim1)" 0=1 1=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid bias.*"
-}
-
-@test "gpioset: invalid drive" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset --drive=bad "$(gpiosim_chip_name sim1)" 0=1 1=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid drive.*"
-}
-
-@test "gpioset: daemonize in invalid mode" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset --background "$(gpiosim_chip_name sim1)" 0=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*can't daemonize in this mode"
-}
-
-@test "gpioset: same line twice" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpioset "$(gpiosim_chip_name sim0)" 0=1 0=1
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines"
-}
-
-#
-# gpiomon test cases
-#
-
-@test "gpiomon: single rising edge event" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --rising-edge "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
-}
-
-@test "gpiomon: single falling edge event" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --falling-edge "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
-}
-
-@test "gpiomon: single falling edge event (pull-up)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 4 pull-down
-
-	coproc_run_tool gpiomon --bias=pull-up "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
-}
-
-@test "gpiomon: single rising edge event (pull-down)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 4 pull-up
-
-	coproc_run_tool gpiomon --bias=pull-down "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
-}
-
-@test "gpiomon: single rising edge event (active-low)" {
-	gpiosim_chip sim0 num_lines=8
-
-	gpiosim_set_pull sim0 4 pull-up
-
-	coproc_run_tool gpiomon --rising-edge --active-low "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
-}
-
-@test "gpiomon: single rising edge event (silent mode)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --rising-edge --silent "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test -z "$output"
-}
-
-@test "gpiomon: four alternating events" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --num-events=4 "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
-	output_regex_match \
-"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
-}
-
-@test "gpiomon: exit after SIGINT" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "$(gpiosim_chip_name sim0)" 4
-
-	coproc_tool_kill -SIGINT
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test -z "$output"
-}
-
-@test "gpiomon: exit after SIGTERM" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "$(gpiosim_chip_name sim0)" 4
-
-	coproc_tool_kill -SIGTERM
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test -z "$output"
-}
-
-@test "gpiomon: both event flags" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --falling-edge --rising-edge "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-	gpiosim_set_pull sim0 4 pull-down
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match \
-"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
-	output_regex_match \
-"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
-}
-
-@test "gpiomon: watch multiple lines" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --format=%o "$(gpiosim_chip_name sim0)" 1 2 3 4 5
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 3 pull-up
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "${lines[0]}" = "2"
-	test "${lines[1]}" = "3"
-	test "${lines[2]}" = "4"
-}
-
-@test "gpiomon: watch multiple lines (lines in mixed-up order)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon --format=%o "$(gpiosim_chip_name sim0)" 5 2 7 1 6
-
-	gpiosim_set_pull sim0 2 pull-up
-	gpiosim_set_pull sim0 1 pull-up
-	gpiosim_set_pull sim0 6 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "${lines[0]}" = "2"
-	test "${lines[1]}" = "1"
-	test "${lines[2]}" = "6"
-}
-
-@test "gpiomon: same line twice" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpiomon "$(gpiosim_chip_name sim0)" 0 0
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines"
-}
-
-@test "gpiomon: no arguments" {
-	run_tool gpiomon
-
-	test "$status" -eq "1"
-	output_regex_match ".*gpiochip must be specified"
-}
-
-@test "gpiomon: line not specified" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpiomon "$(gpiosim_chip_name sim0)"
-
-	test "$status" -eq "1"
-	output_regex_match ".*GPIO line offset must be specified"
-}
-
-@test "gpiomon: line out of range" {
-	gpiosim_chip sim0 num_lines=4
-
-	run_tool gpiomon "$(gpiosim_chip_name sim0)" 5
-
-	test "$status" -eq "1"
-	output_regex_match ".*unable to request lines"
-}
-
-@test "gpiomon: invalid bias" {
-	gpiosim_chip sim0 num_lines=8
-
-	run_tool gpiomon --bias=bad "$(gpiosim_chip_name sim0)" 0 1
-
-	test "$status" -eq "1"
-	output_regex_match ".*invalid bias.*"
-}
-
-@test "gpiomon: custom format (event type + offset)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%e %o" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "1 4"
-}
-
-@test "gpiomon: custom format (event type + offset joined)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%e%o" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "14"
-}
-
-@test "gpiomon: custom format (timestamp)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%e %o %s.%n" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	output_regex_match "1 4 [0-9]+\\.[0-9]+"
-}
-
-@test "gpiomon: custom format (double percent sign)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%%" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "%"
-}
-
-@test "gpiomon: custom format (double percent sign + event type specifier)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%%e" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "%e"
-}
-
-@test "gpiomon: custom format (single percent sign)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "%"
-}
-
-@test "gpiomon: custom format (single percent sign between other characters)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=foo % bar" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "foo % bar"
-}
-
-@test "gpiomon: custom format (unknown specifier)" {
-	gpiosim_chip sim0 num_lines=8
-
-	coproc_run_tool gpiomon "--format=%x" "$(gpiosim_chip_name sim0)" 4
-
-	gpiosim_set_pull sim0 4 pull-up
-	sleep 0.2
-
-	coproc_tool_kill
-	coproc_tool_wait
-
-	test "$status" -eq "0"
-	test "$output" = "%x"
-}
tools/gpiodetect.c +0 -79

82 lines not on this page · raw message

tools/gpiofind.c +0 -80

83 lines not on this page · raw message

tools/gpioget.c +0 -140

143 lines not on this page · raw message

tools/gpioinfo.c +0 -240

243 lines not on this page · raw message

tools/gpiomon.c +0 -301

304 lines not on this page · raw message

tools/gpioset.c +0 -315

318 lines not on this page · raw message

tools/tools-common.c +0 -68

83 lines not on this page · raw message

Signature · 1 line
2.37.0
#2 lore raw

PATCH v2 2/6 tools: line name focussed rework

In reply to Kent Gibson

Rework the tool suite to support identifying lines by name and to support operating on the GPIO lines available to the user at once, rather than on one particular GPIO chip.

All tools, other than gpiodetect, now provide the name to (chip,offset) mapping that was previously only performed by gpiofind. As names are not guaranteed to be unique, a --strict option is provided for all tools to either abort the operation or report all lines with the matching name, as appropriate.
By default the tools operate on the first line found with a matching name.

Selection of line by (chip,offset) is still supported with a --chip option, though it restricts the scope of the operation to an individual chip. When the --chip option is specified, the lines are assumed to be identified by offset where they parse as an integer, else by name. To cater for the unusual case where a line name parses as an integer, but is different from the offset, the --by-name option forces the lines to be identified by name.

The updated tools are intentionally NOT backwardly compatible with the previous tools. Using old command lines with the updated tools will almost certainly fail, though migrating old command lines is generally as simple as adding a '-c' before the chip.

In addition the individual tools are modified as follows:

gpiodetect:

Add the option to select individual chips.

gpiofind:

Add the option to display the info for found lines.

gpioinfo:

Change the focus from chips to lines, so the scope can be an individual line, a subset of lines, all lines on a particular chip, or all the lines available to the user. For line scope a single line summary is output for each line. For chip scope the existing format displaying a summary of the chip and each of its lines is retained.

Line attributes are consolidated into a list format, and are extended to cover all attributes supported by uAPI v2.

gpioget:

The default output format is becomes line=value, as per the input for gpioset, and the value is reported as active or inactive, rather than 0 or 1.
The previous format is available using the --numeric option.

Add an optional hold period between requesting a line and reading the value to allow the line to settle once the requested configuration has been applied (e.g. bias).

gpiomon:

Consolidate the edge options into a single option.

Add a debounce period option.

Add options to report event times as UTC or localtime.

Add format specifiers for GPIO chip path, line name, stringified event type, and event time as a datetime.

Rearrange default output format to place fields with more predicable widths to the left, and to separate major field groups with tabs. Lines are identified consistent with the command line.

gpioset:

Add a hold period option that specifies the minimum period the line value must be held for. This applies to all set options.

Support line values specified as active/inactive, on/off and true/false, as well as 1/0.

Add a toggle option that specifies a time sequence over which the requested lines should be toggled. If the sequence is 0 terminated then gpioset exits when the sequence completes, else it repeats the sequence. This allows for anything from simple blinkers to bit bashing from the command line. e.g. gpioset -t 500ms LED=on

Add an interactive option to provide a shell-like interface to allow manual or scripted manipulation of requested lines. A basic command set allows lines to be get, set, or toggled, and to insert sleeps between operations.

Remove the --mode, --sec, and --usec options.
The combination of hold period and interactive mode provide functionality equivalent to the old --mode options.

---
 configure.ac         |   8 +-
 tools/Makefile.am    |   2 +-
 tools/gpiodetect.c   | 113 +++++-
 tools/gpiofind.c     | 152 +++++++-
 tools/gpioget.c      | 194 ++++++++++-
 tools/gpioinfo.c     | 227 +++++++++++-
 tools/gpiomon.c      | 427 ++++++++++++++++++++++-
 tools/gpioset.c      | 805 ++++++++++++++++++++++++++++++++++++++++++-
 tools/tools-common.c | 663 ++++++++++++++++++++++++++++++++++-
 tools/tools-common.h |  63 +++-
 10 files changed, 2615 insertions(+), 39 deletions(-)
configure.ac +4 -4
index ab03673..b4b8d26 100644
@@ -105,14 +105,14 @@ AC_DEFUN([FUNC_NOT_FOUND_TOOLS],
 AC_DEFUN([HEADER_NOT_FOUND_TOOLS],
 	[ERR_NOT_FOUND([$1 header], [tools])])
 
+AC_DEFUN([LIB_NOT_FOUND_TOOLS],
+	[ERR_NOT_FOUND([lib$1], [tools])])
+
 if test "x$with_tools" = xtrue
 then
 	# These are only needed to build tools
-	AC_CHECK_FUNC([basename], [], [FUNC_NOT_FOUND_TOOLS([basename])])
 	AC_CHECK_FUNC([daemon], [], [FUNC_NOT_FOUND_TOOLS([daemon])])
-	AC_CHECK_FUNC([signalfd], [], [FUNC_NOT_FOUND_TOOLS([signalfd])])
-	AC_CHECK_FUNC([setlinebuf], [], [FUNC_NOT_FOUND_TOOLS([setlinebuf])])
-	AC_CHECK_HEADERS([sys/signalfd.h], [], [HEADER_NOT_FOUND_TOOLS([sys/signalfd.h])])
+	PKG_CHECK_MODULES(LIBEDIT, libedit)
 fi
 
 AC_ARG_ENABLE([tests],
tools/Makefile.am +1 -1
index 4a13266..b5f5c2d 100644
@@ -7,7 +7,7 @@ AM_CFLAGS += -Wall -Wextra -g -std=gnu89
 noinst_LTLIBRARIES = libtools-common.la
 libtools_common_la_SOURCES = tools-common.c tools-common.h
 
-LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la
+LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la $(LIBEDIT_LIBS)
 
 bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon gpiofind
 
tools/gpiodetect.c +111 -2

122 lines not on this page · raw message

tools/gpiofind.c +151 -1

161 lines not on this page · raw message

tools/gpioget.c +193 -1

205 lines not on this page · raw message

tools/gpioinfo.c +225 -2

236 lines not on this page · raw message

tools/gpiomon.c +423 -4

442 lines not on this page · raw message

tools/gpioset.c +803 -2

818 lines not on this page · raw message

tools/tools-common.c +647 -16

715 lines not on this page · raw message

tools/tools-common.h +57 -6

82 lines not on this page · raw message

Signature · 1 line
2.37.0
#3 lore raw

PATCH v2 3/6 tools: tests for line name focussed rework

In reply to Kent Gibson

Rework the tools tests and expand to cover new functionality.

---
 tools/gpio-tools-test      |    3 -
 tools/gpio-tools-test.bats | 2270 ++++++++++++++++++++++++++++++++++--
 2 files changed, 2185 insertions(+), 88 deletions(-)
tools/gpio-tools-test +0 -3
index 234f9bd..1a012dc 100755
@@ -37,9 +37,6 @@ check_prog() {
 # Check all required non-coreutils tools
 check_prog bats
 check_prog modprobe
-check_prog rmmod
-check_prog udevadm
-check_prog timeout
 
 # Check if we're running a kernel at the required version or later
 check_kernel $MIN_KERNEL_VERSION
tools/gpio-tools-test.bats +2185 -85

2,371 lines not on this page · raw message

Signature · 1 line
2.37.0
#4 lore raw

PATCH v2 4/6 tools: add gpiowatch

In reply to Kent Gibson

Add a gpiowatch tool, based on gpiomon, but reporting line info change events similar to the gpio-watch tool in the linux kernel.

---
 man/Makefile.am   |   2 +-
 tools/.gitignore  |   1 +
 tools/Makefile.am |   4 +-
 tools/gpiowatch.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+), 2 deletions(-)
 create mode 100644 tools/gpiowatch.c
man/Makefile.am +1 -1
index 4d2c29b..3badd3b 100644
@@ -3,7 +3,7 @@
 
 if WITH_MANPAGES
 
-dist_man1_MANS = gpiodetect.man gpioinfo.man gpioget.man gpioset.man gpiofind.man gpiomon.man
+dist_man1_MANS = gpiodetect.man gpioinfo.man gpioget.man gpioset.man gpiofind.man gpiomon.man gpiowatch.man
 
 %.man: $(top_builddir)/tools/$(*F)
 	help2man $(top_builddir)/tools/$(*F) --include=$(srcdir)/template --output=$(builddir)/$@ --no-info
tools/.gitignore +1 -0
index 0d53de9..6175e26 100644
@@ -7,3 +7,4 @@ gpioget
 gpioset
 gpiomon
 gpiofind
+gpiowatch
tools/Makefile.am +3 -1
index b5f5c2d..31b7cc9 100644
@@ -9,7 +9,7 @@ libtools_common_la_SOURCES = tools-common.c tools-common.h
 
 LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la $(LIBEDIT_LIBS)
 
-bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon gpiofind
+bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon gpiofind gpiowatch
 
 gpiodetect_SOURCES = gpiodetect.c
 
@@ -23,6 +23,8 @@ gpiomon_SOURCES = gpiomon.c
 
 gpiofind_SOURCES = gpiofind.c
 
+gpiowatch_SOURCES = gpiowatch.c
+
 EXTRA_DIST = gpio-tools-test gpio-tools-test.bats
 
 if WITH_TESTS
tools/gpiowatch.c new file +231 -0

231 lines not on this page · raw message

Signature · 1 line
2.37.0
#5 lore raw

PATCH v2 5/6 tools: gpiowatch tests

In reply to Kent Gibson

Extend the tool test suite to cover the gpiowatch tool.

---
 tools/gpio-tools-test.bats | 289 +++++++++++++++++++++++++++++++++++++
 1 file changed, 289 insertions(+)
tools/gpio-tools-test.bats +289 -0
index fad234b..a9161e3 100755
@@ -2320,3 +2320,292 @@ request_release_line() {
 	dut_read
 	output_is "%x"
 }
+
+#
+# gpiowatch test cases
+#
+
+@test "gpiowatch: by name" {
+	gpiosim_chip sim0 num_lines=8 line_name=4:foo
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner foo
+	dut_regex_match "Watching line .*"
+
+	request_release_line $sim0 4
+
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+foo\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+foo\\s+.*"
+	# tools currently have no way to generate a RECONFIG event
+}
+
+@test "gpiowatch: by offset" {
+	gpiosim_chip sim0 num_lines=8
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner --chip $sim0 4
+	dut_regex_match "Watching line .*"
+
+	request_release_line $sim0 4
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+4\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+4\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: by symlink" {
+	gpiosim_chip sim0 num_lines=8
+	gpiosim_chip_symlink sim0 .
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner --chip $GPIOSIM_CHIP_LINK 4
+	dut_regex_match "Watching line .*"
+
+	request_release_line $sim0 4
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$GPIOSIM_CHIP_LINK\\s+4\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$GPIOSIM_CHIP_LINK\\s+4\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: by chip and name" {
+	gpiosim_chip sim0 num_lines=8 line_name=4:foo
+	gpiosim_chip sim1 num_lines=8 line_name=2:foo
+
+	local sim1=${GPIOSIM_CHIP_NAME[sim1]}
+
+	dut_run gpiowatch --banner --chip $sim1 foo
+	dut_regex_match "Watching line .*"
+
+	request_release_line $sim1 2
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim1\\s+2\\s+foo\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim1\\s+2\\s+foo\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: first matching named line" {
+	gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
+				      line_name=3:foobar
+	gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
+				      line_name=4:xyz line_name=7:foobar
+	gpiosim_chip sim2 num_lines=16
+
+	dut_run gpiowatch --banner foobar
+	dut_regex_match "Watching line .*"
+
+	request_release_line ${GPIOSIM_CHIP_NAME[sim0]} 3
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+foobar\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+foobar\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: multiple lines" {
+	gpiosim_chip sim0 num_lines=8
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner --chip $sim0 1 2 3 4 5
+	dut_regex_match "Watching lines .*"
+
+	request_release_line $sim0 2
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+2\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+2\\s+.*"
+
+	request_release_line $sim0 3
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+3\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+3\\s+.*"
+
+	request_release_line $sim0 4
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+4\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+4\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: multiple lines by name and offset" {
+	gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner --chip $sim0 bar foo 3
+	dut_regex_match "Watching lines .*"
+
+	request_release_line $sim0 2
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+2\\s+bar\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+2\\s+bar\\s+.*"
+
+	request_release_line $sim0 1
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+1\\s+foo\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+1\\s+foo\\s+.*"
+
+	request_release_line $sim0 3
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+3\\s+unnamed\\s+.*"
+	dut_regex_match \
+"\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+3\\s+unnamed\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: multiple lines across multiple chips" {
+	gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
+	gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+	local sim1=${GPIOSIM_CHIP_NAME[sim1]}
+
+	dut_run gpiowatch --banner baz bar foo xyz
+	dut_regex_match "Watching lines .*"
+
+	request_release_line $sim0 2
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+bar\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+bar\\s+.*"
+
+	request_release_line $sim0 1
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+foo\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+foo\\s+.*"
+
+	request_release_line $sim1 4
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+xyz\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+xyz\\s+.*"
+
+	request_release_line $sim1 0
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+baz\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+baz\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: exit after SIGINT" {
+	gpiosim_chip sim0 num_lines=8
+
+	dut_run gpiowatch --banner --chip ${GPIOSIM_CHIP_NAME[sim0]} 4
+	dut_regex_match "Watching line .*"
+
+	dut_kill -SIGINT
+	dut_wait
+
+	status_is 130
+}
+
+@test "gpiowatch: exit after SIGTERM" {
+	gpiosim_chip sim0 num_lines=8
+
+	dut_run gpiowatch --banner --chip ${GPIOSIM_CHIP_NAME[sim0]} 4
+	dut_regex_match "Watching line .*"
+
+	dut_kill -SIGTERM
+	dut_wait
+
+	status_is 143
+}
+
+@test "gpiowatch: with nonexistent line" {
+	run_tool gpiowatch nonexistent-line
+
+	status_is 1
+	output_regex_match ".*cannot find line nonexistent-line"
+}
+
+@test "gpiowatch: with same line twice" {
+	gpiosim_chip sim0 num_lines=8 line_name=1:foo
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	# by offset
+	run_tool gpiowatch --chip $sim0 0 0
+
+	status_is 1
+	num_lines_is 1
+	output_regex_match ".*lines 0 and 0 are the same"
+
+	# by name
+	run_tool gpiowatch --chip $sim0 foo foo
+
+	status_is 1
+	num_lines_is 1
+	output_regex_match ".*lines foo and foo are the same"
+
+	# by name and offset
+	run_tool gpiowatch --chip $sim0 1 foo
+
+	status_is 1
+	num_lines_is 1
+	output_regex_match ".*lines 1 and foo are the same"
+}
+
+@test "gpiowatch: with strict named line check" {
+	gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
+				      line_name=3:foobar
+	gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
+				      line_name=4:xyz line_name=7:foobar
+	gpiosim_chip sim2 num_lines=16
+
+	run_tool gpiowatch --strict foobar
+
+	status_is 1
+	output_regex_match ".*line foobar is not unique"
+}
+
+@test "gpiowatch: with lines strictly by name" {
+	# not suggesting this setup makes sense
+	# - just test that we can deal with it
+	gpiosim_chip sim0 num_lines=8 line_name=1:42 line_name=6:13
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	dut_run gpiowatch --banner --by-name --chip $sim0 42 13
+	dut_flush
+
+	request_release_line $sim0 1
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+1\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+1\\s+.*"
+
+	request_release_line $sim0 6
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+REQUESTED\\s+$sim0\\s+6\\s+.*"
+	dut_regex_match "\\s*[0-9]+\.[0-9]+\\s+RELEASED\\s+$sim0\\s+6\\s+.*"
+
+	assert_fail dut_readable
+}
+
+@test "gpiowatch: with no arguments" {
+	run_tool gpiowatch
+
+	status_is 1
+	output_regex_match ".*at least one GPIO line must be specified"
+}
+
+@test "gpiowatch: with no line specified" {
+	gpiosim_chip sim0 num_lines=8
+
+	run_tool gpiowatch --chip ${GPIOSIM_CHIP_NAME[sim0]}
+
+	status_is 1
+	output_regex_match ".*at least one GPIO line must be specified"
+}
+
+@test "gpiowatch: with offset out of range" {
+	gpiosim_chip sim0 num_lines=4
+
+	local sim0=${GPIOSIM_CHIP_NAME[sim0]}
+
+	run_tool gpiowatch --chip $sim0 5
+
+	status_is 1
+	output_regex_match ".*offset 5 is out of range on chip $sim0"
+}
Signature · 1 line
2.37.0
#6 lore raw

PATCH v2 6/6 tools: remove gpiofind

In reply to Kent Gibson

Remove the gpiofind tool as its functionality has been absorbed into the other tools.

---
 man/Makefile.am            |   2 +-
 tools/Makefile.am          |   4 +-
 tools/gpio-tools-test.bats |  97 ----------------------
 tools/gpiofind.c           | 163 -------------------------------------
 4 files changed, 2 insertions(+), 264 deletions(-)
 delete mode 100644 tools/gpiofind.c
man/Makefile.am +1 -1
index 3badd3b..032ed4e 100644
@@ -3,7 +3,7 @@
 
 if WITH_MANPAGES
 
-dist_man1_MANS = gpiodetect.man gpioinfo.man gpioget.man gpioset.man gpiofind.man gpiomon.man gpiowatch.man
+dist_man1_MANS = gpiodetect.man gpioinfo.man gpioget.man gpioset.man gpiomon.man gpiowatch.man
 
 %.man: $(top_builddir)/tools/$(*F)
 	help2man $(top_builddir)/tools/$(*F) --include=$(srcdir)/template --output=$(builddir)/$@ --no-info
tools/Makefile.am +1 -3
index 31b7cc9..1097fea 100644
@@ -9,7 +9,7 @@ libtools_common_la_SOURCES = tools-common.c tools-common.h
 
 LDADD = libtools-common.la $(top_builddir)/lib/libgpiod.la $(LIBEDIT_LIBS)
 
-bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon gpiofind gpiowatch
+bin_PROGRAMS = gpiodetect gpioinfo gpioget gpioset gpiomon gpiowatch
 
 gpiodetect_SOURCES = gpiodetect.c
 
@@ -21,8 +21,6 @@ gpioset_SOURCES = gpioset.c
 
 gpiomon_SOURCES = gpiomon.c
 
-gpiofind_SOURCES = gpiofind.c
-
 gpiowatch_SOURCES = gpiowatch.c
 
 EXTRA_DIST = gpio-tools-test gpio-tools-test.bats
tools/gpio-tools-test.bats +0 -97

103 lines not on this page · raw message

tools/gpiofind.c deleted +0 -163

163 lines not on this page · raw message

Signature · 1 line
2.37.0