Datum in Millisekunden auf OpenWRT auf Arduino YUN

Datum in Millisekunden auf OpenWRT auf Arduino YUN

Ich verwende OpenWRT auf dem Arduino YUN und versuche, das genaue Datum in Millisekunden (TT/MM/JJJJ h:min:sek:ms) zu erhalten, indem ich die Uhrzeit von einem Zeitserver abrufe.

Leider date +%Ngibt es nur zurück %N, aber nicht die Nanosekunden. Ich habe gehört, +%Ndass das Datum nicht im OpenWRT-Datum enthalten ist.

Gibt es also eine Möglichkeit, das Datum (einschließlich Millisekunden) so zu erhalten, wie ich es möchte?

Antwort1

Auf OpenWRT dategibt es busybox, das Einschränkungen hat, aber das ist nicht unbedingt eine davon. Das zugrunde liegende Problem ist, dass die libc (uClibc)unterstützt diese GNU strftime-Erweiterung nicht. (Allerdings gilt dies auch für glibc, mehr dazu weiter unten.)

Das sollte luastandardmäßig der Fall sein, aber daswird nicht helfenohne einige andere nicht standardmäßige Module.

hwclockfordert gettimeofday()zum Vergleichen/Einstellen der RTC (Hardware-Uhr), gibt aber keine Auflösung von unter einer Sekunde aus (der Zugriff auf RTCs kann so langsam sein, dass er ohnehin nicht nützlich sein könnte). Abgesehen davon bietet OpenWRT nur das alte rdate, das nur eine Auflösung von ganzen Sekunden hat.

Es scheint keine einfache Möglichkeit zu geben, direkt von einen genauen Zeitstempel zu erhalten /proc. Der nützlichste Zeitstempel befindet sich in /proc/timer_list(3. Zeile), was die Betriebszeit in Nanosekunden angibt (die Auflösung hängt von der Plattform ab).

Wenn Ihre Busybox mit set erstellt wurde CONFIG_BUSYBOX_CONFIG_ADJTIMEX, sollten Sie in der Lage sein, adjtimexdie Kernel-Uhr zu lesen (beachten Sie jedoch, dass die Busybox-Versionbeideandere Argumente und andere Ausgabe als der Standard-Adjtimex.

Normalversion, adjtimex -pletzte Ausgabezeile:

   raw time:  1416419719s 146628us = 1416419719.146628

Busybox-Version adjtimex(ohne -p!), letzte 3 Zeilen:

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

Goldilocks ist eine gute Lösung, vorausgesetzt, Sie haben Ihr OpenWRT Cross Build Setup (dringend empfohlen!). Ihrcoreutils-datumLösung funktioniert, weil coreutils zwar glibc-fähig ist, aber nicht ausschließlich glibc ist. Es verfügt über eine eigene eigenständige Implementierung von (abgeleitet von glibc) und verwendet diese, um das zugrunde liegende Element (über ) strftimezu verpacken, um verschiedene Erweiterungen zu unterstützen (und greift andernfalls auf die uClibc-Version zurück).strftime_case()strftime

Sogar glibc (bis zur aktuellen Version 2.23) unterstützt nicht , die von der kanonischen glibc-Version abgeleiteten %NCoreutils fügen und und einige andere Änderungen hinzu. Variationen und gepatchte Versionen von gibt es in Hülle und Fülle (einschließlich Versionen in Bash und Gawk).strftime()%N%:zstrftime()

Antwort2

Wenn Sie einen C-Compiler darauf haben und nichts anderes finden können, wird dies beispielsweise melden

> 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;
}  

Kompilieren Sie es einfach mit gcc gcc whatever.c -o millitime. Wenn ein Fehler auftritt (was sehr seltsam wäre), wird er an stderr gemeldet und mit dem Status 1 beendet. Andernfalls wird er an stdout gemeldet und mit 0 beendet.

Die Millisekunden sindabgerundetvon Mikrosekunden.

Antwort3

Tatsächlich gibt es auch ein Paket namens coreutils-date! Davon wusste ich nichts! Dort sind alle Standardfunktionen enthalten!

Antwort4

#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;
}

Dies ist in der Sprache C und funktioniert wie coreutils-date date +%s%3N. Es wird mit OpenWrt-SDK in den OpenWrt-Router kompiliert.

verwandte Informationen