Ретаргетинг newlib для c ++ chrono - PullRequest
0 голосов
/ 24 марта 2019

Я использую набор инструментов arm-none-eabi с newlib, чтобы нацелиться на пользовательскую плату с ARM Cortex-M0 + (в частности, версия набора инструментов MCU-on-eclipse ). Я компилирую / связываю с -nostartfiles и --specs=nano.specs и переназначил stdout и stderr на USB и последовательный порт соответственно. Я создал реализации для большинства системных вызовов языка C.

Я использую библиотеку хронографа с двумя настраиваемыми часами , функции now () получают время по RTC или таймер моей ручки. Похоже, что это отражает назначение стандартных устойчивых и системных часов, и поэтому я, хотя я мог бы попытаться использовать их.

для этого мне пришлось реализовать системный вызов gettimeofday, который я сделал

// returning a set time of one second just for testing
int _gettimeofday(struct timeval* tv, void* tz) {
    tv->tv_sec  = 1;
    tv->tv_usec = 255;
    return 0;
}

мой основной код выглядит следующим образом:

int main(void)
{
    HWInit();

    static std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
    static std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();
    int64_t count1 = t1.time_since_epoch().count();
    int64_t count2 = t2.time_since_epoch().count();

    printf("Time 1: %lld\n Time 2: %lld\n", count1, count2);
    for(;;){}
    return 0;
}

с помощью отладчика я вижу, что и steady_clock::now(), и sysytem_clock::now() вызывают мою функцию _gettimeofday (), и оба заканчиваются с одинаковым моментом времени.

конечно, если я пытаюсь сделать следующее, я получаю несколько ошибок определения:

using SysClock = std::chrono::system_clock;

SysClock::time_point SysClock::now() noexcept {
    return SysClock::time_point( SysClock::duration(1983) );
}

Так можно ли как-то перегрузить функции now () стандартных хронографических часов? или, может быть, вся реализация часов с моей собственной продолжительностью и типами повторений, которые лучше соответствуют оборудованию? Я могу перегрузить new и delete для моей встроенной системы (и должен), поэтому было бы неплохо сделать это для chrono.

Ответы [ 2 ]

1 голос
/ 24 марта 2019

Из gccs libstdc ++ chrono.cc :

  • system_clock::now() использует gettimeofday(&tv, 0); или clock_gettime(CLOCK_REALTIME, &tp); или системный вызов. Если gettimeofday работает для вас, значит, он его использует.
  • steady_clock::now() использует clock_gettime(CLOCK_MONOTONIC, &tp);. Поэтому вы должны перегрузить clock_gettime и обработать CLOCK_MONOTONIC аргумент.
  • Нет функции _clock_gettime_r, предоставляемой newlib, как в _gettimeofday_t, которая передает newlib struct reent. Если вы хотите обрабатывать многопоточность в newlib, хорошо написать свою собственную подобную оболочку, которая обрабатывает значение _reent->errno. Но ставка будет в том, чтобы перегружать функцию _gettimeofday_r, поскольку вы нацелены только на newlib.
0 голосов
/ 24 марта 2019

Вместо того, чтобы пытаться изменить поведение system_clock и steady_clock, я рекомендую просто написать свои собственные часы и использовать их.Таким образом, вы можете лучше адаптировать их к вашему оборудованию и потребностям.Если у вас есть какой-то способ узнать текущее время, очень просто создать пользовательские chrono часы, чтобы обернуть эту функцию.

class SysClock
{
public:
    // 500MHz, or whatever you need
    using period                    = std::ratio<1, 500'000'000>;
    using rep                       = long long;
    using duration                  = std::chrono::duration<rep, period>;
    using time_point                = std::chrono::time_point<SysClcok>;
    static constexpr bool is_steady = true;

    static time_point now() noexcept
    {
        return time_point{duration{
            /*turn SysTick_getValue() into the number of ticks since epoch*/}};
    }
};

Теперь используйте SysClock::now() в своем коде вместо system_clock::now().Это дает вам SysClock::time_point и chrono::durations результат вычитания двух SysClock::time_point s.

Если вы можете превратить ваш низкий уровень "сейчас" в число тиков против некоторой эпохи, и вы можетеопишите эти тики как доли времени компиляции с period, тогда все готово.

...