为c ++ chrono重新定位newlib

问题描述 投票:0回答:2

我正在使用带有newlib的arm-none-eabi工具链来定位带有ARM Cortex-M0 +的定制板(特别是工具链的MCU-on-eclipse版本)。我正在编译/链接-nostartfiles--specs=nano.specs,并分别将stdout和stderr重新定位到USB和串行端口。我已经为大多数C系统调用创建了实现。

我正在使用带有两个custom clock的chrono库,now()函数获取RTC时间或我的systick计时器。这似乎反映了标准的steady_clock和system_clock的目的,所以尽管我可以尝试使用它们。

这样做我必须实现我做的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()函数吗?或者整个时钟实现与我自己的持续时间和rep typedef更好地匹配硬件?我可以为我的嵌入式系统重载新的和删除(并且应该),所以对chrono这样做也会很好。

c++ chrono cortex-m newlib
2个回答
1
投票

来自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参数。
  • newlib没有提供_clock_gettime_r函数,就像_gettimeofday_t中传递newlib的struct reent一样。如果你想在newlib中处理多线程,那么编写你自己的处理_reent->errno值的类似包装是很好的。但是,当你只针对newlib时,赌注是重载_gettimeofday_r函数。

0
投票

我建议只编写自己的自定义时钟并使用它们,而不是试图改变system_clocksteady_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_pointchrono::durations结果减去两个SysClock::time_points。

如果您可以将低级别“now”转换为针对某个时期的刻度计数,并且您可以使用period将这些刻度描述为一秒的编译时间分数,那么您很高兴。

© www.soinside.com 2019 - 2024. All rights reserved.