Data em milissegundos no OpenWRT no Arduino YUN

3

Estou usando o OpenWRT no Arduino YUN e estou tentando obter a data exata em milissegundos (DD / MM / AAAA h: min: seg: ms) obtendo a hora em um servidor de horário.

Infelizmente date +%N apenas retorna %N , mas não os nanossegundos. Ouvi +%N não está incluído na data do OpenWRT.

Então, há alguma maneira de obter a data (incluindo milissegundos) como eu quero?

    
por Tschwen 14.11.2014 / 14:10

5 respostas

2

Na verdade, existe também um pacote chamado coreutils-date ! Não sabia disso! Existe toda a funcionalidade padrão incluída!

    
por 16.11.2014 / 15:47
8

No OpenWRT, date é busybox , que possui limitações, mas isso não é estritamente uma delas. O problema subjacente é que a libc (uClibc) não suporta esta extensão GNU strftime . (Embora nem o glibc, mais sobre isso abaixo.)

Você deve ter lua por padrão, mas não ajudará sem alguns outros módulos não padrão.

hwclock chamadas gettimeofday() para comparar / definir o RTC (relógio de hardware), mas não produzirá resolução de sub-segundo (acessar RTCs pode ser lento o suficiente para não ser útil de qualquer maneira). Além disso, o OpenWRT fornece apenas o antigo rdate , que tem apenas resolução de segundo inteiro.

Parece não haver nenhuma maneira direta de obter um registro de tempo exato diretamente de /proc , o carimbo de data mais útil é em /proc/timer_list (terceira linha), que é o tempo de atividade em nanossegundos (a resolução dependerá da plataforma ).

Se o seu busybox foi construído com CONFIG_BUSYBOX_CONFIG_ADJTIMEX set, então você poderá usar adjtimex para ler o relógio do kernel (embora note que a versão do busybox tem ambos argumentos diferentes e saída diferente para o adjtimex padrão.

Versão normal, adjtimex -p , última linha de saída:

   raw time:  1416419719s 146628us = 1416419719.146628

Versão do Busybox, adjtimex (sem -p !), últimas 3 linhas:

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

Cachinhos Dourados é uma ótima solução, supondo que você tenha sua configuração de construção cruzada do OpenWRT (altamente recomendada!). Sua solução coreutils-date funciona porque, embora o coreutils esteja ciente, ele não é exclusivo da glibc. Ele vem com sua própria implementação independente de strftime (derivada da glibc), e usa isso para finalizar (via strftime_case() ) o strftime subjacente de modo a suportar várias extensões (e voltar para a versão uClibc) .

Mesmo o glibc (até o atual 2.23) não suporta %N , o coreutils strftime() derivado da versão glibc canônica adiciona %N e %:z e algumas outras alterações. Variações e versões corrigidas de strftime() são abundantes (incluindo versões no bash e gawk).

    
por 19.11.2014 / 19:15
4

Se você tiver um compilador C e não conseguir encontrar mais nada, isso informará, por exemplo,

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

Com o gcc, apenas compile gcc whatever.c -o millitime . Se houver um erro (o que seria muito estranho), ele será reportado para stderr e sairá com um status de 1. Caso contrário, ele será reportado como stdout e sairá de 0.

Os milissegundos são arredondados para baixo em microssegundos.

    
por 14.11.2014 / 15:48
0
#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;
}

Isso na linguagem C e funciona como coreutils-date date +%s%3N . É compilado para o roteador OpenWrt com o OpenWrt-SDK.

    
por 26.09.2016 / 23:43
0

A solução adjtimex não funcionou para mim porque recebo adjtimex: Operation not permitted (estou usando um contêiner docker alpino). Mas eu encontrei outra solução bizarra, mas livre de dependência, usando nmeter , que pode exibir até microssegundos.

#-d0 means print every 0 seconds ie immediately
# head -n1 makes sure it only does it once
nmeter -d0 '%3t' | head -n1

Combinando isso com o comando date:

date -u +%FT$(nmeter -d0 '%3t' | head -n1)Z
# 2017-05-03T04:10:57.863Z

Obtemos uma string de data e hora UTC rfc3339 com milissegundos!

    
por 03.05.2017 / 06:12