We have a time command to record the delta of get_time_ns() to time
command execution, but have no command to just print get_time_ns().

Such a command can be useful to debug clocksources or to verify that a
system is still running and hasn't been reset by a yet unhandled
watchdog in-between.

Make development a bit easier by providing a new uptime command.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
v1 -> v2:
  - use getopt (Sascha)
  - drop other patches
---
 commands/Kconfig  | 13 ++++++++
 commands/Makefile |  1 +
 commands/uptime.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)
 create mode 100644 commands/uptime.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 2ce990b5616a..a59616ad1474 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2289,6 +2289,19 @@ config CMD_TIME
          Note: This command depends on COMMAND being interruptible,
          otherwise the timer may overrun resulting in incorrect results
 
+config CMD_UPTIME
+       bool "uptime"
+       help
+         uptime - Tell how long barebox has been running
+
+         Usage: uptime [-n]
+
+         This command formats the number of elapsed nanoseconds
+         as measured with the current clocksource.
+
+         Options:
+           -n          output elapsed time in nanoseconds
+
 config CMD_STATE
        tristate
        depends on STATE
diff --git a/commands/Makefile b/commands/Makefile
index 68d0d05365a5..cac1d4f2535b 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_CMD_WD)          += wd.o
 obj-$(CONFIG_CMD_LED_TRIGGER)  += trigger.o
 obj-$(CONFIG_CMD_USB)          += usb.o
 obj-$(CONFIG_CMD_TIME)         += time.o
+obj-$(CONFIG_CMD_UPTIME)       += uptime.o
 obj-$(CONFIG_CMD_OFTREE)       += oftree.o
 obj-$(CONFIG_CMD_OF_DIFF)      += of_diff.o
 obj-$(CONFIG_CMD_OF_PROPERTY)  += of_property.o
diff --git a/commands/uptime.c b/commands/uptime.c
new file mode 100644
index 000000000000..a9a8c650b698
--- /dev/null
+++ b/commands/uptime.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <command.h>
+#include <clock.h>
+#include <getopt.h>
+#include <linux/math64.h>
+
+#define NSEC_PER_MINUTE        (NSEC_PER_SEC * 60LL)
+#define NSEC_PER_HOUR  (NSEC_PER_MINUTE * 60LL)
+#define NSEC_PER_DAY   (NSEC_PER_HOUR * 24LL)
+#define NSEC_PER_WEEK  (NSEC_PER_DAY * 7LL)
+
+static bool print_with_unit(u64 val, const char *unit, bool comma)
+{
+       if (!val)
+               return comma;
+
+       printf("%s%llu %s%s", comma ? ", " : "", val, unit, val > 1 ? "s" : "");
+       return true;
+}
+
+static int do_uptime(int argc, char *argv[])
+{
+       u64 timestamp, weeks, days, hours, minutes;
+       bool comma = false;
+       int opt;
+
+       timestamp = get_time_ns();
+
+       while((opt = getopt(argc, argv, "n")) > 0) {
+               switch(opt) {
+               case 'n':
+                       printf("up %lluns\n", timestamp);
+                       return 0;
+               default:
+                       return COMMAND_ERROR_USAGE;
+               }
+       }
+
+       if (optind != argc)
+               return COMMAND_ERROR_USAGE;
+
+       printf("up ");
+
+       weeks = div64_u64_rem(timestamp, NSEC_PER_WEEK, &timestamp);
+       days = div64_u64_rem(timestamp, NSEC_PER_DAY, &timestamp);
+       hours = div64_u64_rem(timestamp, NSEC_PER_HOUR, &timestamp);
+       minutes = div64_u64_rem(timestamp, NSEC_PER_MINUTE, &timestamp);
+
+       comma = print_with_unit(weeks, "week", false);
+       comma = print_with_unit(days, "day", comma);
+       comma = print_with_unit(hours, "hour", comma);
+       comma = print_with_unit(minutes, "minute", comma);
+
+       if (!comma) {
+               u64 seconds = div64_u64_rem(timestamp, NSEC_PER_SEC, 
&timestamp);
+               print_with_unit(seconds, "second", false);
+       }
+
+       printf("\n");
+
+       return 0;
+}
+
+BAREBOX_CMD_HELP_START(uptime)
+BAREBOX_CMD_HELP_TEXT("This command formats the number of elapsed nanoseconds")
+BAREBOX_CMD_HELP_TEXT("as measured with the current clocksource")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-n",     "output elapsed time in nanoseconds")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(uptime)
+       .cmd            = do_uptime,
+       BAREBOX_CMD_DESC("Tell how long barebox has been running")
+       BAREBOX_CMD_OPTS("[-n]")
+       BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+       BAREBOX_CMD_HELP(cmd_uptime_help)
+BAREBOX_CMD_END
-- 
2.30.2


Reply via email to