From: Bartosz Golaszewski <brgl@bgdev.pl>
To: "Linus Walleij" <linus.walleij@linaro.org>,
"Kent Gibson" <warthog618@gmail.com>,
"Gunnar Thörnqvist" <gunnar@igl.se>
Cc: linux-gpio@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Subject: [libgpiod][PATCH 2/2] tools: allow longer time periods
Date: Tue, 9 Apr 2024 11:33:33 +0200 [thread overview]
Message-ID: <20240409093333.138408-3-brgl@bgdev.pl> (raw)
In-Reply-To: <20240409093333.138408-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
We currently store time as milliseconds in 32-bit integers and allow
seconds as the longest time unit when parsing command-line arguments
limiting the time period possible to specify when passing arguments such
as --hold-period to 35 minutes. Let's use 64-bit integers to vastly
increase that.
Use nanosleep() instead of usleep() to extend the possible sleep time
range.
Reported-by: Gunnar Thörnqvist <gunnar@igl.se>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
configure.ac | 2 ++
tools/gpioget.c | 4 ++--
tools/gpiomon.c | 19 ++++++++++++++-----
tools/gpioset.c | 16 ++++++++--------
tools/tools-common.c | 22 ++++++++++++++++------
tools/tools-common.h | 5 +++--
6 files changed, 45 insertions(+), 23 deletions(-)
diff --git a/configure.ac b/configure.ac
index 3b5bbf2..a2370c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -120,6 +120,8 @@ AS_IF([test "x$with_tools" = xtrue],
AC_CHECK_FUNC([asprintf], [], [FUNC_NOT_FOUND_TOOLS([asprintf])])
AC_CHECK_FUNC([scandir], [], [FUNC_NOT_FOUND_TOOLS([scandir])])
AC_CHECK_FUNC([versionsort], [], [FUNC_NOT_FOUND_TOOLS([versionsort])])
+ AC_CHECK_FUNC([strtoull], [], [FUNC_NOT_FOUND_TOOLS([strtoull])])
+ AC_CHECK_FUNC([nanosleep], [], [FUNC_NOT_FOUND_TOOLS([nanosleep])])
AS_IF([test "x$with_gpioset_interactive" = xtrue],
[PKG_CHECK_MODULES([LIBEDIT], [libedit >= 3.1])])
])
diff --git a/tools/gpioget.c b/tools/gpioget.c
index f611737..bad7667 100644
--- a/tools/gpioget.c
+++ b/tools/gpioget.c
@@ -19,7 +19,7 @@ struct config {
bool unquoted;
enum gpiod_line_bias bias;
enum gpiod_line_direction direction;
- unsigned int hold_period_us;
+ unsigned long long hold_period_us;
const char *chip_id;
const char *consumer;
};
@@ -205,7 +205,7 @@ int main(int argc, char **argv)
die_perror("unable to request lines");
if (cfg.hold_period_us)
- usleep(cfg.hold_period_us);
+ sleep_us(cfg.hold_period_us);
ret = gpiod_line_request_get_values(request, values);
if (ret)
diff --git a/tools/gpiomon.c b/tools/gpiomon.c
index e3abb2d..a8a3302 100644
--- a/tools/gpiomon.c
+++ b/tools/gpiomon.c
@@ -5,6 +5,7 @@
#include <getopt.h>
#include <gpiod.h>
#include <inttypes.h>
+#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,13 +25,13 @@ struct config {
enum gpiod_line_bias bias;
enum gpiod_line_edge edges;
int events_wanted;
- unsigned int debounce_period_us;
+ unsigned long long debounce_period_us;
const char *chip_id;
const char *consumer;
const char *fmt;
enum gpiod_line_clock event_clock;
int timestamp_fmt;
- int timeout;
+ long long timeout;
};
static void print_help(void)
@@ -389,9 +390,17 @@ int main(int argc, char **argv)
if (cfg.active_low)
gpiod_line_settings_set_active_low(settings, true);
- if (cfg.debounce_period_us)
+ if (cfg.debounce_period_us) {
+ if (cfg.debounce_period_us > UINT_MAX)
+ die("invalid debounce period: %llu",
+ cfg.debounce_period_us);
+
gpiod_line_settings_set_debounce_period_us(
- settings, cfg.debounce_period_us);
+ settings, (unsigned long)cfg.debounce_period_us);
+ }
+
+ if (cfg.timeout > INT_MAX)
+ die("invalid idle timeout: %llu", cfg.timeout);
gpiod_line_settings_set_event_clock(settings, cfg.event_clock);
gpiod_line_settings_set_edge_detection(settings, cfg.edges);
@@ -453,7 +462,7 @@ int main(int argc, char **argv)
for (;;) {
fflush(stdout);
- ret = poll(pollfds, resolver->num_chips, cfg.timeout);
+ ret = poll(pollfds, resolver->num_chips, (int)cfg.timeout);
if (ret < 0)
die_perror("error polling for events");
diff --git a/tools/gpioset.c b/tools/gpioset.c
index 863da4a..46dde07 100644
--- a/tools/gpioset.c
+++ b/tools/gpioset.c
@@ -28,8 +28,8 @@ struct config {
enum gpiod_line_bias bias;
enum gpiod_line_drive drive;
int toggles;
- unsigned int *toggle_periods;
- unsigned int hold_period_us;
+ unsigned long long *toggle_periods;
+ unsigned long long hold_period_us;
const char *chip_id;
const char *consumer;
};
@@ -94,10 +94,10 @@ static int parse_drive_or_die(const char *option)
return 0;
}
-static int parse_periods_or_die(char *option, unsigned int **periods)
+static int parse_periods_or_die(char *option, unsigned long long **periods)
{
int i, num_periods = 1;
- unsigned int *pp;
+ unsigned long long *pp;
char *end;
for (i = 0; option[i] != '\0'; i++)
@@ -376,7 +376,7 @@ static void toggle_all_lines(struct line_resolver *resolver)
* and apply the values to the requests.
* offset and values are scratch pads for working.
*/
-static void toggle_sequence(int toggles, unsigned int *toggle_periods,
+static void toggle_sequence(int toggles, unsigned long long *toggle_periods,
struct gpiod_line_request **requests,
struct line_resolver *resolver,
unsigned int *offsets,
@@ -388,7 +388,7 @@ static void toggle_sequence(int toggles, unsigned int *toggle_periods,
return;
for (;;) {
- usleep(toggle_periods[i]);
+ sleep_us(toggle_periods[i]);
toggle_all_lines(resolver);
apply_values(requests, resolver, offsets, values);
@@ -826,7 +826,7 @@ static void interact(struct gpiod_line_request **requests,
printf("invalid period: '%s'\n", words[1]);
goto cmd_ok;
}
- usleep(period_us);
+ sleep_us(period_us);
goto cmd_ok;
}
@@ -981,7 +981,7 @@ int main(int argc, char **argv)
}
if (cfg.hold_period_us)
- usleep(cfg.hold_period_us);
+ sleep_us(cfg.hold_period_us);
#ifdef GPIOSET_INTERACTIVE
if (cfg.interactive)
diff --git a/tools/tools-common.c b/tools/tools-common.c
index 64592d3..500e9a2 100644
--- a/tools/tools-common.c
+++ b/tools/tools-common.c
@@ -112,12 +112,12 @@ int parse_bias_or_die(const char *option)
return GPIOD_LINE_BIAS_DISABLED;
}
-int parse_period(const char *option)
+long long parse_period(const char *option)
{
- unsigned long p, m = 0;
+ unsigned long long p, m = 0;
char *end;
- p = strtoul(option, &end, 10);
+ p = strtoull(option, &end, 10);
switch (*end) {
case 'u':
@@ -147,15 +147,15 @@ int parse_period(const char *option)
}
p *= m;
- if (*end != '\0' || p > INT_MAX)
+ if (*end != '\0' || p > LLONG_MAX)
return -1;
return p;
}
-unsigned int parse_period_or_die(const char *option)
+unsigned long long parse_period_or_die(const char *option)
{
- int period = parse_period(option);
+ long long period = parse_period(option);
if (period < 0)
die("invalid period: %s", option);
@@ -163,6 +163,16 @@ unsigned int parse_period_or_die(const char *option)
return period;
}
+void sleep_us(unsigned long long period)
+{
+ struct timespec spec;
+
+ spec.tv_sec = period / 1000000;
+ spec.tv_nsec = (period % 1000000) * 1000;
+
+ nanosleep(&spec, NULL);
+}
+
int parse_uint(const char *option)
{
unsigned long o;
diff --git a/tools/tools-common.h b/tools/tools-common.h
index c82317a..bc63080 100644
--- a/tools/tools-common.h
+++ b/tools/tools-common.h
@@ -87,8 +87,9 @@ void die(const char *fmt, ...) NORETURN PRINTF(1, 2);
void die_perror(const char *fmt, ...) NORETURN PRINTF(1, 2);
void print_version(void);
int parse_bias_or_die(const char *option);
-int parse_period(const char *option);
-unsigned int parse_period_or_die(const char *option);
+long long parse_period(const char *option);
+unsigned long long parse_period_or_die(const char *option);
+void sleep_us(unsigned long long period);
int parse_uint(const char *option);
unsigned int parse_uint_or_die(const char *option);
void print_bias_help(void);
--
2.40.1
next prev parent reply other threads:[~2024-04-09 9:33 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-09 9:33 [libgpiod][PATCH 0/2] gpio-tools: allow specifying longer time periods Bartosz Golaszewski
2024-04-09 9:33 ` [libgpiod][PATCH 1/2] build: fix configure error messages on missing functions Bartosz Golaszewski
2024-04-10 7:47 ` Bartosz Golaszewski
2024-04-09 9:33 ` Bartosz Golaszewski [this message]
2024-04-09 12:55 ` [libgpiod][PATCH 2/2] tools: allow longer time periods Kent Gibson
2024-04-09 15:59 ` Bartosz Golaszewski
2024-04-09 23:32 ` Kent Gibson
[not found] ` <3f31c7bc-de8a-4552-ba48-4432b335f413@igl.se>
2024-04-09 16:05 ` Kent Gibson
2024-04-09 17:24 ` Bartosz Golaszewski
2024-04-09 23:37 ` Kent Gibson
2024-04-10 7:53 ` Bartosz Golaszewski
2024-04-10 10:19 ` Kent Gibson
2024-04-09 23:52 ` Kent Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240409093333.138408-3-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=bartosz.golaszewski@linaro.org \
--cc=gunnar@igl.se \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=warthog618@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).