Why is Timer's "read_ms" method deprecated in the upcoming Mbed OS 6?

Hello,

I thought C++ was invented to make programmer’s life easier. However, I have noticed that in the upcoming Mbed OS 6 the Timer’s easy to remember read_ms method is deprecated and we suppose to call a hard to remember:

duration_cast<milliseconds>(elapsed_time()).count()

What is the idea behind such modification to the Timer’s interface? Why isn’t it possible to keep also the human friendly read_ms method name?

My guess is that OS6 wants us to use std::chrono API instead.

http://rachelnertia.github.io/programming/2018/01/07/intro-to-std-chrono/

3 Likes

Hello Kentaro,

Thank you for the explanation. I think you are right. That’s most likely why.

Best regards,

Zoltan

The example in version 6 Doc’s need to be updated then?

https://os.mbed.com/docs/mbed-os/v6.0/apis/timer.html

timer.read();
timer.read_ms();
timer.read_us();

example:

printf ("Timer time: %d\n", timer.read());
printf ("Timer time: %d\n", timer.read_ms());
printf ("Timer time: %d\n", timer.read_us());

How would I replace these for OS6?

You can do something like this.

int main() {
    Timer t;
    t.start();
    ThisThread::sleep_for(1s);
    t.stop();
    auto f = chrono::duration<float>(t.elapsed_time()).count();
    auto s = chrono::duration_cast<chrono::seconds>(t.elapsed_time()).count();
    auto ms = chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count();
    auto us = t.elapsed_time().count();
    printf ("Timer time: %f s\n", f);
    printf ("Timer time: %llu s\n", s);
    printf ("Timer time: %llu ms\n", ms);
    printf ("Timer time: %llu us\n", us);
}

// Timer time: 1.002245 s
// Timer time: 1 s
// Timer time: 1002 ms
// Timer time: 1002245 us

Thank you Kentaro, perfect example!!

To save time, make the source code more readable and avoid frustration with typos, for larger programs one can define macros for example as follows:

#include "mbed.h"

#define timer_read_f(x)     chrono::duration<float>((x).elapsed_time()).count()
#define timer_read_s(x)     chrono::duration_cast<chrono::seconds>((x).elapsed_time()).count();
#define timer_read_ms(x)    chrono::duration_cast<chrono::milliseconds>((x).elapsed_time()).count()
#define timer_read_us(x)    (x).elapsed_time().count()

int main() {
    Timer t;
    t.start();
    ThisThread::sleep_for(1s);
    t.stop();
    auto f = timer_read_f(t);
    auto s = timer_read_s(t);
    auto ms = timer_read_ms(t);
    auto us = timer_read_us(t);
    printf ("Timer time: %f s\n", f);
    printf ("Timer time: %llu s\n", s);
    printf ("Timer time: %llu ms\n", ms);
    printf ("Timer time: %llu us\n", us);
}
3 Likes

I can understand adding these UNIX standard functions, why not add these defines to the Timer.h file for simplicity for Mbed Rapid Prototyping.

1 Like

If all you want to do is to print, it makes sense to define timer_read_ms, timer_read_s, etc… But if you compare duration or pass it to a function, maybe you don’t always want to cast it to an integer because doing so breaks type safety.

1 Like

I fully agree. In those cases it’s sufficient to call the elapsed_time() method.

there is another good document about the Mbed clocks:
https://github.com/ARMmbed/mbed-os/blob/master/docs/design-documents/platform/clocks/clocks.md

for checking elapsed time, it is not necessary to use a Timer instance. With this snippet from the document it is easy:

//Measuring elapsed time via the RTOS

auto start = Kernel::Clock::now(); // type will be Kernel::Clock::time_point
do_operation();
milliseconds elapsed_time = Kernel::Clock::now() - start;
printf("elapsed time = %d ms\n", int(elapsed_time.count()));

or checking the timepoint:

  if (Kernel::Clock::now() - start < 100ms)
    return;

chrono is great stuff, but like a landslide in Mbed :slight_smile:
There are plenty of interfaces that are still using legacy integers.

2 Likes

That’s really good to know! Thank you Johannes.

This is great, thank you.
It should be the official documentation example, which still uses read() !