Arduino YUN의 OpenWRT 날짜(밀리초)

Arduino YUN의 OpenWRT 날짜(밀리초)

저는 Arduino YUN에서 OpenWRT를 사용하고 있으며 밀리초(DD/MM/YYYY h:min:sec:ms) 단위의 정확한 날짜를 얻기 위해 시간 서버를 통해 시간을 얻으려고 합니다.

불행하게도 나노초가 아닌 date +%N나노초만 반환됩니다 %N. +%NOpenWRT 날짜는 포함되지 않는다고 들었습니다 .

그렇다면 내가 원하는 날짜(밀리초 포함)를 얻을 수 있는 방법이 있나요?

답변1

OpenWRT에서는 date그렇습니다 busybox. 제한 사항이 있지만 엄밀히 말하면 그 중 하나는 아닙니다. 근본 문제는 libc(uClibc)입니다.이 GNU strftime 확장은 지원되지 않습니다.. (glibc도 마찬가지지만 이에 대해서는 아래에서 자세히 설명합니다.)

기본적으로 가 있어야 lua하지만도움이 안돼기본이 아닌 다른 모듈도 있습니다.

hwclockRTC(하드웨어 시계)를 비교/설정 해야 gettimeofday()하지만 1초 미만의 해상도를 출력하지 않습니다(RTC에 액세스하는 것이 너무 느려서 유용하지 않을 수 있음). 그 외에도 OpenWRT는 고대의 rdate1초 단위 해상도만 제공합니다.

에서 직접 정확한 타임스탬프를 얻을 수 있는 직접적인 방법은 없는 것 같습니다 /proc. 가장 유용한 타임스탬프는 /proc/timer_list나노초 단위의 가동 시간인 (라인 3)입니다(해상도는 플랫폼에 따라 다름).

비지박스가 set 으로 구축된 경우 CONFIG_BUSYBOX_CONFIG_ADJTIMEX이를 사용하여 커널 시계를 읽을 수 있어야 합니다 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는 아니기 때문에 솔루션이 작동합니다. 이는 자체적인 독립적 구현(glibc에서 파생됨)과 함께 제공되며 이를 사용하여 기본 레이어를 strftime래핑(통과 ) 하여 다양한 확장을 지원합니다(그렇지 않으면 uClibc 버전으로 대체됨).strftime_case()strftime

glibc(현재 2.23까지)가 이를 지원하지 않더라도 %N정식 glibc 버전에서 파생된 coreutils는 몇 가지 다른 변경 사항을 추가합니다. 변종과 패치 버전이 많습니다(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 라우터로 컴파일합니다.

관련 정보