rtic-rs / rtic

Real-Time Interrupt-driven Concurrency (RTIC) framework for ARM Cortex-M microcontrollers
https://rtic.rs
Apache License 2.0
1.75k stars 200 forks source link

`rtfm::Instant` cannot be formatted with the default formatter #150

Closed oni303 closed 5 years ago

oni303 commented 5 years ago

I guess I'm doing something wrong here but I'm out of ideas. I try to print the value of an Instant without using {:?}

The most interesting line is:

--> src/main.rs:202:53 202 let s_count = format!("{},{:>10.2}\r\n",now,*resources.val+5.5); ^^^ rtfm::Instant cannot be formatted with the default formatter

= help: the trait core::fmt::Display is not implemented for rtfm::Instant = note: in format strings you may be able to use {:?} (or {:#?} for pretty-print) instead = note: required by core::fmt::Display::fmt

now is the rtfm::Instant.

I know I could use {:?} but then I would get something like Instant(1163512974), I do not want the Instant and (). Cutting the string does not seem to be the right solution.

TeXitoi commented 5 years ago

There is no better solution now. A new feature for this need would be a fn cycle_count(&self) -> i32 I suppose.

japaric commented 5 years ago

rtfm::Instant is based on std::time::Instant. Both are opaque types that are only mean to be compared or subtracted to produce a Duration.

The Display trait (used by the {} in println!) is for user-facing ("human") representation of a value. There's no such representation for either Instant given that they are opaque types. The Debug trait ({:?}) is a debug representation of a value; it just gives you an idea of the internal representation of a value but you can't rely on it for anything other that visual debugging (e.g. the representation may change in any new patch release).

@oni303 can you say more about why you want to print the internal representation of Instant without the "Instant" part of the string? The value you'll see will happen to be a 32-bit value today but nowhere do we guarantee that will always be the case nor do we want to make promises about its representation.

If you want to track time you should use Duration to print time deltas. We can certainly add a cycles method to make it return a u32 that indicates how many clock cycles the Duration represents. Alternatively, you could use something like itm-tools to profile your application, if that's what you are after.

oni303 commented 5 years ago

I want to measure a sensor and then send it via uart. To make sense of the values I need some thing like a timestamp. During the search for some "system time" I stumbled about Instant and Duration. What is a better solution to timestamp values?

perlindgren commented 5 years ago

The (original) RTFM model has a very clear timing semantics. Each task is associated with a baseline, defining the time of arrival (symmetric to tasks and interrupts). Current implementation of RTFM is a bit blurry to that end (and can be further improved I believe).

Best,

Per


Från: oni303 notifications@github.com Skickat: den 18 februari 2019 08:39:23 Till: japaric/cortex-m-rtfm Kopia: Subscribed Ämne: Re: [japaric/cortex-m-rtfm] rtfm::Instant cannot be formatted with the default formatter (#150)

I want to measure a sensor and then send it via uart. To make sense of the values I need some thing like a timestamp. During the search for some "system time" I stumbled about Instant and Duration. What is a better solution to timestamp values?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/japaric/cortex-m-rtfm/issues/150#issuecomment-464619452, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AD5naN-oXJhWl-6_DSlUUhV396u3fdZkks5vOlirgaJpZM4a904k.

{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/japaric/cortex-m-rtfm","title":"japaric/cortex-m-rtfm","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/japaric/cortex-m-rtfm"}},"updates":{"snippets":[{"icon":"PERSON","message":"@oni303 in #150: I want to measure a sensor and then send it via uart. To make sense of the values I need some thing like a timestamp. During the search for some \"system time\" I stumbled about Instant and Duration. \r\nWhat is a better solution to timestamp values?\r\n"}],"action":{"name":"View Issue","url":"https://github.com/japaric/cortex-m-rtfm/issues/150#issuecomment-464619452"}}} [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/japaric/cortex-m-rtfm/issues/150#issuecomment-464619452", "url": "https://github.com/japaric/cortex-m-rtfm/issues/150#issuecomment-464619452", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]

japaric commented 5 years ago

@oni303

To make sense of the values I need some thing like a timestamp

You can use DWT::get_cycle_count() to get a timestamp.

What is a better solution to timestamp values?

You can serialize (SensorData, Option<Duration>) where the second field is the time delta between measurements and the value of None is used for the first measurement (no delta). If you were to use timestamps the host would have to deal with the wrap around behavior of the timestamp; with deltas the host just has to add them to get a timestamp.

If you are reading the sensor periodically you can omit the deltas and instead have the microcontroller report the period at the start of the transmission. If you expect to miss packets every now and then you can include a count to each packet(e.g. 0, 1, missed, 3, ..).

If you are dealing with infrequent measurements -- deltas in the order of minutes -- then you should use a device specific timer; the Instant / Duration has a high, cycle-accurate resolution and can only represent spans up to one minute (depending on the device clock configuration).

oni303 commented 5 years ago

Well in my case it is possible to derive the time of a measurements form the number of executions and the period of the task but there are many cases where that is not an option e.g. measuring the time between two interrupts.

And even in my case I need to add code complexity to get a less accurate timing. That does not seam like a good option to me.

oni303 commented 5 years ago

@japaric

You can serialize (SensorData, Option<Duration>)

there is no {} for Duration right? So it is the same problem as for Instant.

japaric commented 5 years ago

measuring the time between two interrupts.

For that you can subtract two Instant and get the time span (Duration) back.

there is no {} for Duration right?

No, and we won't implement Display for Duration, but we can add a cycles method to Duration. Then you can serialize the returned value (u32) using a binary format, or format it into a string if you want.

oni303 commented 5 years ago

OK that sounds like a good solution, I will have a look later.

Am 18. Februar 2019 22:20:17 MEZ schrieb Jorge Aparicio notifications@github.com:

measuring the time between two interrupts.

For that you can subtract two Instant and get the time span (Duration) back.

there is no {} for Duration right?

No, and we won't implement Display for Duration, but we can add a cycles method to Duration. Then you can serialize the returned value (u32) using a binary format, or format it into a string if you want.

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/japaric/cortex-m-rtfm/issues/150#issuecomment-464883204

TeXitoi commented 5 years ago

154 add Duration::as_cycle

japaric commented 5 years ago

154 add Duration::as_cycle

Closing. We are not going to implement Debug or Display for the opaque Instant type.