-
Notifications
You must be signed in to change notification settings - Fork 35
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
async API #52
Conversation
Crazy idea: async |
blink I'm going to need to brush up on Futures and get back to you! |
Something else to think about: error handling. The real |
And |
cc @jamesmunns This may also interest you. A futures-based nonblocking API for timers and serial (UART). BTW, do you know if the teensy C library has a nonblocking API that can I can look at for inspiration? |
UpdateEverything has been updated to use futures: Timers, Serial, I2C, SPI and the sensors. cc @istankovic There's a "session types" based I2C "concrete" (no traits) API. See the i2c module. It ended looking quite different from what I sketched before; the main reason is that, at least on the stm32f303 microcontroller, (a) along START you have to send the slave address and wheter you'll be reading/writing bytes across the wire and (b) you have to declare how many bytes you are going to read/write before you send START. The implication of all this is that you can't have and call a |
Do you have a plan to get Future::wait to not spin tightly? |
Definitely interesting! I'll try and look more in depth ASAP. @thejpster I haven't had my morning coffee yet, but basically the choices for wait would be:
Probably the best implementation of |
I don't intent to change Future::wait behavior as it's the simplest and cheapest (code size wise) way to transform async functions into blocking functions, which make sense to use in e.g. initialization code. (I might change its name to busy_wait though) To avoid busy waiting at all in the main loop, I'm going to look into WFI to sleep when there's nothing to do. I'm hoping that the final API usage will look like this: loop {
let mut progress = false;
// Try to advance tasks
progress |= task1.advance(); // returns false if no progress was made
progress |= task2.advance();
(..)
// If no task progressed
if !progress {
// call WFI and wait until an interrupt unblocks progress on some task
sleep();
}
} I might have to change enum Async<T> {
/// Done
Ready(T),
/// Made some progress
Progressed,
Blocked,
} |
☔ The latest upstream changes (presumably ccba1d3) made this pull request unmergeable. Please resolve the merge conflicts. |
@japaric I really like this: loop {
let mut progress = false;
// Try to advance tasks
progress |= task1.advance(); // returns false if no progress was made
progress |= task2.advance();
(..)
// If no task progressed
if !progress {
// call WFI and wait until an interrupt unblocks progress on some task
sleep();
}
} |
All the API is nonblocking now. You can use the RTFM framework to do multitasking. |
Update
Everything has been updated to use futures: Timers, Serial, I2C, SPI and the sensors.
Documentation
this deprecates the delay module as the new Timer API can easily
replicate the delay::ms functionality.
I want to try a few more complicated peripherals like I2C before deciding whether this makes sense or not. Probably will do an async version of the API of one the sensors as well.
cc @thejpster This may interest you. You can start by looking at the examples.