-
Notifications
You must be signed in to change notification settings - Fork 220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unify DelayUs and DelayMs to DelayUs for v1.0 #312
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eldruin (or someone else) soon. Please see the contribution instructions for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add an entry to the changelog?
Sorry, one last thing, could you also squash this into one commit? |
Context: Do you have any objections @ryankurte ? |
damnit almindor you beat me (my fault for not looking first 🤦 ) here's the summary I wrote: Quick summary of discussions in #177 and in today's REWG meeting:
The compromise found to unblock 1.0 while mitigating the issues is:
Why:
The name When the final |
I'm somewhat against the situation where we have only |
The main problem with two traits is that if a HAL doesn't implement one of them it blocks Drivers that use the other one from being used. The idea here is to avoid such cul-de-sacs. A proper solution is to introduce a new Time type and figure out all the nuances of delays and then introduce |
Perhaps the docs should specify "delays for at least X us, but may delay for longer, if for example the implementation doesn't have enough precision"? Delaying for shorter could break drivers that need to wait for at least X us for some chip to do some operation, delaying for longer usually doesn't. This would require HALs to round up instead of down if there's not enough precision, and warn driver authors to not rely on it for extremely precise timing. |
I like this approach, @Disasm what do you think? |
Yes, this is one of the solutions. I still don't understand why it's better than the "best effort" solution when the provided delay tries to work with a good precision. We can't guarantee this precision of course, but type system provides a way to define it at least on some level by defining two separate traits, and this PR removes the difference between old DelayMs and DelayUs. Imagine that we have a Pin trait instead of all the other pin traits which sometimes doesn't work as expected. Driver wants to use it as output, but if user configured it as input, it will not work. Same here: if the user took a bad delay source, it will not work in a situations when you need a microsecond delay. If you need to toggle GPIO fast enough, but with a tiny delay, you would use delay_us for this, but if this delay gives you 2+ms delay each time, you will not get what you expect. |
The problem is that if the HAL decides to implement only one for whatever reason, it locks out many drivers that might expect the other. This happened on the I don't think we can prevent precision issues/force proper precision on implementors until we have a better type around the delays defined. |
Well, that's how traits work. If your implementation has some functionality, it implements a trait, otherwise it doesn't. If the delay from e310x-hal doesn't implement DelayUs, it's only because it's a bad delay and we need a better delay instead of making a fake DelayUs implementation for the bad one. |
Many places where you need a delay are fine with "delay for at least X" and don't break if the delay is longer than requested. Stuff like "after deasserting RST wait for at least 500us before sending commands". I'd argue this is the majority of DelayMs/DelayUs uses today. For use cases that do break when the impl delays for longer, DelayMs/DelayUs isn't a good choice anyway. The code can be preempted and arbitrarily delayed anyway by interrupts, it should be interrupt-driven, not blocking. The advantage of documenting that DelayUs does "delay for at least X" is that it solves the compatibility problem: all HALs will be capable of implementing it, so drivers using it will work everywhere. The disadvantage is the "precision delay" use case is left unsolved, but we can address that with the "fancy" Duration trait we'll add in the future. |
this all seems pretty reasonable to me. we do need a basic delay function like this for constructing drivers (and i suspect this is the majority of existing uses), i certainly wouldn't want it removed without an equivalent replacement.
at least with linux users, subject to the whims of the scheduler, this is already the case. documenting it as "delay for at least X" sounds great. this trait is never going to do a great job for bit-bashing, that said, if you need more accuracy you can switch to a delay implementation able to provide it, we're just not guaranteeing it at the abstract HAL level. |
Extended comments to include @ryankurte @Dirbaio @Disasm @eldruin @adamgreig would it make sense to also return the value actually used? E.g. turn it into |
My first thought is that measuring that accurately could add a lot of complexity to HAL impls, and I don't think many use cases would benefit from finding out (i.e. they'd probably just ignore the number, as usually there's nothing to be done about it if the delay was longer than expected after it's already happened). Maybe it would be a neat feature to add to a future Delay trait as an option? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me as-is, thanks!
Some last-minute bikeshedding 😅 If the trait has methods
|
Even though it sounds a bit weird, but |
The 'precision' of the impl can be whatever, there'll probably be impls using a 32khz low-frequency clock or whatever. It was just a random thought anyway, wanted to share to see what other people think. I'm OK with DelayUs too. |
It's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As agreed, let's get this merged.
bors r+
Implements a unified
DelayUs
usingu32
only for v1.0 of embedded-hal to prevent confusion.Keeps
Delay
open for future, better abstractions.