rust-embedded / embedded-hal

A Hardware Abstraction Layer (HAL) for embedded systems
Apache License 2.0
1.93k stars 197 forks source link

Tracking issue for timer traits #359

Open eldruin opened 2 years ago

eldruin commented 2 years ago

The timer traits available on the 0.2.x versions have been removed ahead of the 1.0.0 release. See: #357 This issue servers as a tracking issue until we add them back. The open (breaking) problems should be reasonably-well solved and all associated types should have appropriate bounds that enable generic code use.

Timer traits as of the 0.2.7 release:

Relevant issues/PRs:

Please feel free to participate, highlight your current use cases, problems and provide solutions.

niclashoyer commented 2 years ago

Unbounded time constraints are really cumbersome to work with. I'm currently using the timer traits (mainly CountDown) for signal detection (detect pin changes and check time between changes) and generation of such signals using bit banging.

To work around the several different types implemented by peripheral crates I currently use drogue-embedded-timer as a wrapper. My driver crates use embedded-time, which works quite well, but may be a bit overkill to integrate this completely in embedded-hal.

I don't really need all the features in embedded-time. I mainly use timers in us or ms range. It would be really nice if we could get back timer traits with a constrained minimal Duration like type, to express delays (us, ms) or periodic (hz) in a platform independent way.

burrbull commented 2 years ago

To work around the several different types implemented by peripheral crates I currently use drogue-embedded-timer as a wrapper. My driver cartes use embedded-time, which works quite well, but may be a bit overkill to integrate this completely in embedded-hal.

As I can see drogue-embedded-timer forces you to specify precision. Have you thought about using fugit::TimerDuration (specifies precision as const generic frequency) for this instead of embedded-time which is more suitable for dynamic-presicion timers? Disadvantage: you need to add const-generic parameter in your drivers: https://github.com/BlackbirdHQ/atat/blob/73a9830fe9f8084bce118289a460a90c73a8c598/atat/src/client.rs#L59 Advantage: all possible conversions are guarantied to work in compile time: https://github.com/BlackbirdHQ/atat/blob/73a9830fe9f8084bce118289a460a90c73a8c598/atat/src/client.rs#L73 Timer implementation example: https://github.com/stm32-rs/stm32f4xx-hal/blob/master/src/fugit/counter.rs CountDown usage example: https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/timer-periph.rs

niclashoyer commented 2 years ago

Using const generics to handle the conversions at compile time seems very compelling. I'll give that a shot.

Ben-Lichtman commented 2 years ago

IMO time is non-trivial enough that I think something like embedded-time should be integrated into embedded-hal - It's complex, but for a good reason.

dlkj commented 2 years ago

Highlighting a use case.

I'm the owner of usbd-human-interface-device the crate aims to provide a high level library for building USB HID on any embedded-hal/usb-device supported platform.

Implementing the full HID spec functionality requires keeping track of time-outs that are set by the host machine and ensuring that idle responses are sent if the time-out occurs. I'm currently assuming the use of embedded-time as I predominantly use the rp-hal platform for development but I've recently become aware of fugit and that there isn't a consensus among hal implementations. An additional layer of complexity is users using RTIC and wanting ergonomic integration at that level of abstraction.

I'd love a mechanism in hal that either provides a real time clock that can be polled or a mechanism to set timers. Hardware timers aren't really appropriate, I'm interested in knowing if no data has been sent for x ms rather than having a regular interrupt/clock tick.

Currently I'm using embedded_time::clock::Clock - this gives me both a way of getting the current time and setting arbitrary timers. Not requiring ownership of the clock is particularly useful.