tools: gpiomon: add initial-state option
PATCH v3 1/1 tools: gpiomon: add initial-state option
From: Shaarang Tyagi <[email protected]>
Add a gpiomon initial-state command line option to display initial line states, this is diplayed before waiting for events. And factoring out the gpioget line status printing code into tools-common.
---
Changes in v2:
- allocation of "values" moved to if block.
- existing variable pollfds was freed.
- option -S changed to -I.
- Added to the unit test.
- Reuse of print_line_vals()
Changes in v3:
- Addition of -N/--numeric switch.
- Dropped "Initial line state(s):" text.
- Unit test now using dut_run and dut_kill.
- Dropped freeing of existing variable pollfds.
--- tests/scripts/gpiod-bash-test-helper.inc | 0 tools/gpio-tools-test.bash | 13 ++++++++++ tools/gpioget.c | 18 +------------- tools/gpiomon.c | 30 +++++++++++++++++++++++- tools/tools-common.c | 21 +++++++++++++++++ tools/tools-common.h | 2 ++ 6 files changed, 66 insertions(+), 18 deletions(-) mode change 100644 => 100755 tests/scripts/gpiod-bash-test-helper.inc
tests/scripts/gpiod-bash-test-helper.inc +0 -0
tools/gpio-tools-test.bash +13 -0
@@ -2235,6 +2235,19 @@ test_gpiomon_with_custom_format_unknown_specifier() { output_is "%x" } +test_gpiomon_with_initial_state() { + 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 + local sim0=${GPIOSIM_CHIP_NAME[sim0]} + + dut_run gpiomon --initial-state --chip "$sim0" 0 1 2 3 4 5 6 7 + dut_read + dut_kill + output_is "\"0\"=inactive \"1\"=inactive \"2\"=active \"3\"=active \"4\"=inactive \"5\"=active \"6\"=inactive \"7\"=active" +} # # gpionotify test cases #
tools/gpioget.c +1 -17
@@ -139,12 +139,10 @@ int main(int argc, char **argv)struct gpiod_line_config *line_cfg;struct line_resolver *resolver;enum gpiod_line_value *values; -struct resolved_line *line;struct gpiod_chip *chip;unsigned int *offsets;int i, num_lines, ret;struct config cfg; -const char *fmt;set_prog_name (argv[0 ]); i =parse_config (argc, argv, &cfg);
@@ -216,21 +214,7 @@ int main(int argc, char **argv)gpiod_line_request_release (request);gpiod_chip_close (chip); } - - fmt = cfg.unquoted ?"%s=%s" :"\"%s\"=%s" ; - -for (i =0 ; i < resolver->num_lines; i++) { - line = &resolver->lines[i]; -if (cfg.numeric) -printf ("%d" , line->value); -else -printf (fmt, line->id, - line->value ?"active" :"inactive" ); - -if (i != resolver->num_lines -1 ) -printf (" " ); - } -printf ("\n" ); +print_line_vals (resolver, cfg.unquoted, cfg.numeric);free_line_resolver (resolver);gpiod_request_config_free (req_cfg);
tools/gpiomon.c +29 -1
@@ -32,6 +32,8 @@ struct config {enum gpiod_line_clock event_clock;int timestamp_fmt;long long idle_timeout; +bool initial_state; +bool numeric; };static void print_help (void )
@@ -69,6 +71,8 @@ static void print_help(void)printf (" -p, --debounce-period <period>\n" );printf ("\t\t\tdebounce the line(s) with the specified period\n" );printf (" -q, --quiet\t\tdon't generate any output\n" ); +printf (" -I, --initial-state\t\tprint initial states of the lines\n" ); +printf (" -N, --numeric\t\tdisplay line values as '0' (inactive) or '1' (active)\n" );printf (" -s, --strict\t\tabort if requested line names are not unique\n" );printf (" --unquoted\tdon't quote line or consumer names\n" );printf (" --utc\t\tformat event timestamps as UTC (default for 'realtime')\n" );
@@ -113,7 +117,7 @@ static int parse_event_clock_or_die(const char *option)static int parse_config (int argc,char **argv,struct config *cfg) { -static const char *const shortopts ="+b:c:C:e:E:hF:ln:p:qshv" ; +static const char *const shortopts ="+b:c:C:e:E:hF:ln:p:qshvIN" ;const struct option longopts[] = { {"active-low" , no_argument,NULL ,'l' },
@@ -136,6 +140,8 @@ static int parse_config(int argc, char **argv, struct config *cfg) { "unquoted", no_argument, NULL, 'Q' }, { "utc", no_argument, &cfg->timestamp_fmt, 1 }, { "version", no_argument, NULL, 'v' }, + { "initial-state", no_argument, NULL, 'I' }, + { "numeric", no_argument, NULL, 'N' }, { GETOPT_NULL_LONGOPT }, };
@@ -197,6 +203,12 @@ static int parse_config(int argc, char **argv, struct config *cfg)case 's' : cfg->strict = true;break ; +case 'I' : + cfg->initial_state = true; +break ; +case 'N' : + cfg->numeric = true; +break ;case 'h' :print_help ();exit (EXIT_SUCCESS );
@@ -363,6 +375,7 @@ int main(int argc, char **argv)int num_lines, events_done =0 ;struct gpiod_edge_event *event;struct line_resolver *resolver; +enum gpiod_line_value *values;struct timespec idle_timeout;struct gpiod_chip *chip;struct pollfd *pollfds;
@@ -423,6 +436,7 @@ int main(int argc, char **argv) requests =calloc (resolver->num_chips,sizeof (*requests)); pollfds =calloc (resolver->num_chips,sizeof (*pollfds)); offsets =calloc (resolver->num_lines,sizeof (*offsets)); +if (!requests || !pollfds || !offsets)die ("out of memory" );
@@ -445,6 +459,20 @@ int main(int argc, char **argv)die_perror ("unable to request lines on chip %s" , resolver->chips[i].path); +if (cfg.initial_state) { + values =calloc (resolver->num_lines,sizeof (*values)); +if (!values) +die ("out of memory" ); + + ret =gpiod_line_request_get_values (requests[i], values); +if (ret) +die_perror ("unable to read GPIO line values" ); + +set_line_values (resolver, i, values); +print_line_vals (resolver, cfg.unquoted, cfg.numeric); +free (values); + } + pollfds[i].fd =gpiod_line_request_get_fd (requests[i]); pollfds[i].events =POLLIN ;gpiod_chip_close (chip);
tools/tools-common.c +21 -0
@@ -402,6 +402,27 @@ void print_line_id(struct line_resolver *resolver, int chip_num,printf (fmt, lname); } +void print_line_vals (struct line_resolver *resolver,bool is_unquoted, +bool is_numeric) +{ +int i; +const char *fmt = is_unquoted ?"%s=%s" :"\"%s\"=%s" ; + +for (i =0 ; i < resolver->num_lines; i++) { +struct resolved_line *line = &resolver->lines[i]; + +if (is_numeric) +printf ("%d" , line->value); +else +printf (fmt, line->id, + line->value ?"active" :"inactive" ); + +if (i != resolver->num_lines -1 ) +printf (" " ); + } +printf ("\n" ); +} +static int chip_dir_filter (const struct dirent *entry) {struct stat sb;
tools/tools-common.h +2 -0
@@ -99,6 +99,8 @@ void print_event_time(uint64_t evtime, int format);void print_line_attributes (struct gpiod_line_info *info,bool unquoted_strings);void print_line_id (struct line_resolver *resolver,int chip_num,unsigned int offset,const char *chip_id,bool unquoted); +void print_line_vals (struct line_resolver *resolver,bool is_unquoted, +bool is_numeric);bool chip_path_lookup (const char *id,char **path_ptr);int chip_paths (const char *id,char ***paths_ptr);int all_chip_paths (char ***paths_ptr);
Bartosz Golaszewski
AppliedQuoted 5 lines · On Thu, 29 Jan 2026 22:01:39 +0530, [email protected] wrote:
Add a gpiomon initial-state command line option to display initial line states, this is diplayed before waiting for events. And factoring out the gpioget line status printing code into tools-common.
Applied, thanks!
[1/1] tools: gpiomon: add initial-state option
commit: caf0bff354c8b03eaf070404ccb833265d50c019
Best regards,
Signature · 1 line
Bartosz Golaszewski <[email protected]>