Arduino YUN 上の OpenWRT でのミリ秒単位の日付

Arduino YUN 上の OpenWRT でのミリ秒単位の日付

私は Arduino YUN で OpenWRT を使用しており、タイムサーバーで時間を取得して、正確な日付をミリ秒単位 (DD/MM/YYYY h:min:sec:ms) で取得しようとしています。

残念ながら、ナノ秒date +%Nは返されません。OpenWRTの日付には含まれていないと聞きました。%N+%N

それで、私が望む日付(ミリ秒を含む)を取得する方法はあるのでしょうか?

答え1

OpenWRTでは、制限がありdateますbusyboxが、これは厳密にはその1つではありません。根本的な問題は、libc(uClibc)このGNU strftime拡張をサポートしていません(glibc も同様ですが、これについては後述します。)

luaデフォルトでそうするべきですが、役に立たない他のデフォルト以外のモジュールなし。

hwclockRTC (ハードウェア クロック) の比較/設定を呼び出しますgettimeofday()が、1 秒未満の解像度は出力されません (RTC へのアクセスは十分に遅いため、いずれにしても役に立たない可能性があります)。それ以外では、OpenWRT はrdate、1 秒単位の解像度しかない古い のみを提供します。

から直接正確なタイムスタンプを取得する簡単な方法はないようですが/proc、最も有用なタイムスタンプは/proc/timer_list(3 行目) にあり、これはナノ秒単位の稼働時間です (解像度はプラットフォームによって異なります)。

もしbusyboxがset付きでビルドされていたら、カーネルクロックを読むためにCONFIG_BUSYBOX_CONFIG_ADJTIMEX使用できるはずです(ただしbusyboxのバージョンにはadjtimex両方標準の 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 専用ではないためです。coreutils には独自のスタンドアロン実装 (glibc から派生) が付属しており、それを使用して ( を介して) 基盤strftimeをラップし、さまざまな拡張機能をサポートします (それ以外の場合は uClibc バージョンにフォールバックします)。strftime_case()strftime

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 ルーターにコンパイルされます。

関連情報