Arduino YUN 上 OpenWRT 上的日期(以毫秒为单位)

Arduino YUN 上 OpenWRT 上的日期(以毫秒为单位)

我在 Arduino YUN 上使用 OpenWRT,并尝试通过时间服务器获取时间来获取以毫秒为单位的准确日期 (DD/MM/YYYY h:min:sec:ms)。

不幸的date +%N是只返回%N,而不是纳秒。我听说+%NOpenWRT日期中没有包含。

那么有什么办法可以得到我想要的日期(包括毫秒)呢?

答案1

在 OpenWRT 上,datebusybox,它有局限性,但这并不是严格意义上的局限性之一。根本问题是 libc (uClibc)不支持此 GNU strftime 扩展。 (尽管 glibc 也没有,下面会详细介绍。)

默认情况下你应该有lua,但是没有帮助没有一些其他非默认模块。

hwclock要求gettimeofday()比较/设置 RTC(硬件时钟),但它不会输出亚秒分辨率(访问 RTC 可能会很慢,以至于可能没有用处)。除此之外,OpenWRT 仅提供古老的rdate,只有整秒的分辨率。

似乎没有直接的方法可以直接从 获取准确的时间戳/proc,最有用的时间戳位于/proc/timer_list(第 3 行),它是以纳秒为单位的正常运行时间(分辨率将取决于平台)。

如果你的 busybox 是用 set 构建的CONFIG_BUSYBOX_CONFIG_ADJTIMEX,那么你应该能够使用它adjtimex来读取内核时钟(尽管请注意,busybox 版本有两个都标准 adjtimex 的不同参数和不同输出。

普通版本,adjtimex -p最后一行输出:

   raw time:  1416419719s 146628us = 1416419719.146628

Busybox 版本,adjtimex(没有-p!),最后 3 行:

   [...]
   time.tv_sec:  1416420386
   time.tv_usec: 732653
   return value: 0 (clock synchronized)

Goldilocks 是一个很好的解决方案,假设您有 OpenWRT 交叉构建设置(强烈推荐!)。你的coreutils-日期解决方案之所以有效,是因为虽然 coreutils 能够识别 glibc,但它并不完全是 glibc。它带有自己的独立实现strftime(源自 glibc),并使用它来包装(通过strftime_case())底层strftime,以支持各种扩展(否则会回退到 uClibc 版本)。

即使 glibc(直到当前的 2.23)也不支持,源自规范 glibc 版本的%Ncoreutils添加了和以及其他一些更改。其变体和修补版本比比皆是(包括 bash 和 gawk 中的版本)。strftime()%N%:zstrftime()

答案2

如果你有一个 C 编译器并且找不到其他任何东西,这将报告,例如

> millitime && sleep 1 && millitime
14/11/2014 9:39:49:364
14/11/2014 9:39:50:368
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

int main (void) {
    struct timeval now;
    struct tm *parsed;

    if (gettimeofday(&now, NULL) == -1) {
        fprintf (
            stderr,
            "gettimeofday() failed: %s\n",
            strerror(errno)
        );
        return 1;
    }

    parsed = localtime((const time_t*)&now.tv_sec);
    if (!parsed) {
        fprintf (
            stderr,
            "localtime() failed: %s\n",
            strerror(errno)
        );
        return 1;
    }

    printf (
        "%d/%d/%d %d:%02d:%02d:%03d\n",
        parsed->tm_mday,
        parsed->tm_mon + 1,
        parsed->tm_year + 1900,
        parsed->tm_hour,
        parsed->tm_min,
        parsed->tm_sec,
        now.tv_usec / 1000
    );

    return 0;
}  

用gcc,编译就可以了gcc whatever.c -o millitime。如果出现错误(这会很奇怪),它会向 stderr 报告并以状态 1 退出。否则,它会向 stdout 报告并退出 0。

毫秒是向下舍入从微秒开始。

答案3

其实还有一个包叫coreutils-date!不知道!包含所有标准功能!

答案4

#include <stdio.h>
#include <time.h>
void main (void){
    long            ms; 
    time_t          s; 

    struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
    s  = spec.tv_sec;
    ms = (spec.tv_nsec / 1.0e6); 
    printf("%d%03d\n", s, ms);      
return 0;
}

这在 C 语言中,工作方式类似于 coreutils-date date +%s%3N。使用OpenWrt-SDK编译为OpenWrt路由器。

相关内容