我正在将arm-none-eabi工具链与newlib配合使用,以使用ARM Cortex-M0 +(特别是工具链的MCU-on-eclipse版本)定位自定义板。我正在使用-nostartfiles
和--specs=nano.specs
进行编译/链接,并将stdout和stderr分别重新定位为USB和串行端口。我已经为大多数C系统调用创建了实现。
我正在使用带有两个custom clock的chrono库,now()函数获取RTC时间或我的systick定时器。看来这反映了标准stable_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与硬件更好匹配的整个时钟实现?我可以为嵌入式系统重载new和delete(并且应该),所以对于chrono这样做也很好。
答案 0 :(得分:1)
system_clock::now()
使用gettimeofday(&tv, 0);
或clock_gettime(CLOCK_REALTIME, &tp);
或syscall。如果gettimeofday
对您有用,则表示它正在使用它。steady_clock::now()
使用clock_gettime(CLOCK_MONOTONIC, &tp);
。因此,您应该重载clock_gettime
并处理CLOCK_MONOTONIC
参数。_clock_gettime_r
函数,因为gccs libstdc++ chrono.cc中的一个函数会传递newlib的struct reent
。如果要在newlib中处理多线程,最好编写自己的类似包装器来处理_reent->errno
值。但是最好的办法是重载_gettimeofday_r
函数,因为仅针对newlib。答案 1 :(得分:0)
建议不要编写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
的结果。
如果您可以将低级的“现在”转换为某个时期的滴答声,并且可以使用period
将这些滴答声描述为编译时间的一秒,那么您就很好了去。