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 退出。

毫秒是向下舍入從微秒開始。

答案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路由器。

相關內容