I am using arm-none-eabi toolchain with newlib to target a custom board with an ARM Cortex-M0+ (specifically the MCU-on-eclipse version of the toolchain). I am compiling/linking with -nostartfiles
and --specs=nano.specs
and have re-targeted stdout and stderr to USB and a serial port respectively. I have created implementations for most of the C system calls.
I am using the chrono library with two custom clock, the now() functions get RTC time or my systick timer. It seems like this mirrors the purpose of the standard steady_clock and system_clock and so I though I could try using them.
to do so I had to implement the gettimeofday syscall which I did
// 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;
}
my main code is as follows:
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;
}
using the debugger I can see that both steady_clock::now()
and sysytem_clock::now()
call my _gettimeofday() function and both end up with the exact same time-point.
of course if I try to do the following I get multiple definition errors:
using SysClock = std::chrono::system_clock;
SysClock::time_point SysClock::now() noexcept {
return SysClock::time_point( SysClock::duration(1983) );
}
So can I somehow overload the now() functions of the standard chrono clocks? or maybe the entire clock implementation with my own duration and rep typedefs that match the hardware better? I can overload new and delete for my embedded system (and should), so doing this for chrono would also be nice.
From gccs libstdc++ chrono.cc:
system_clock::now()
uses gettimeofday(&tv, 0);
or clock_gettime(CLOCK_REALTIME, &tp);
or syscall. If gettimeofday
works for you, that means it uses it.steady_clock::now()
uses clock_gettime(CLOCK_MONOTONIC, &tp);
. So you should overload clock_gettime
and handle CLOCK_MONOTONIC
argument._clock_gettime_r
function provided by newlib, as one in _gettimeofday_t
that passes newlib's struct reent
around. If you want to handle multithreading within newlib, it's good to write your own similar wrapper that handles _reent->errno
value. But the bet would be to overload _gettimeofday_r
function as you aim only at newlib.