|
81 | 81 | //!
|
82 | 82 | //! The `nb::Result` enum is used to add a [`WouldBlock`] variant to the errors
|
83 | 83 | //! of the serial interface. As explained in the documentation of the `nb` crate this single API,
|
84 |
| -//! when paired with the macros in the `nb` crate, can operate in a blocking manner, or in a |
85 |
| -//! non-blocking manner compatible with `futures` and with the `await!` operator. |
| 84 | +//! when paired with the macros in the `nb` crate, can operate in a blocking manner, or be adapted |
| 85 | +//! to other asynchronous execution schemes. |
86 | 86 | //!
|
87 | 87 | //! [`WouldBlock`]: https://docs.rs/nb/0.1.0/nb/enum.Error.html
|
88 | 88 | //!
|
|
223 | 223 | //! # }
|
224 | 224 | //! ```
|
225 | 225 | //!
|
226 |
| -//! ### `futures` |
227 |
| -//! |
228 |
| -//! An example of running two tasks concurrently. First task: blink a LED every |
229 |
| -//! second. Second task: loop back data over the serial interface. The target |
230 |
| -//! must provide the `libstd` in order to be able to use `futures`, which is not |
231 |
| -//! the case for many embedded targets. |
232 |
| -//! |
233 |
| -//! ```no_run |
234 |
| -//! use embedded_hal as hal; |
235 |
| -//! use crate::hal::prelude::*; |
236 |
| -//! use futures::{ |
237 |
| -//! future::{self, Loop}, |
238 |
| -//! Async, |
239 |
| -//! Future, |
240 |
| -//! }; |
241 |
| -//! use nb; |
242 |
| -//! use stm32f1xx_hal::{Led, Serial1, Timer6}; |
243 |
| -//! use core::convert::Infallible; |
244 |
| -//! |
245 |
| -//! /// `futures` version of `CountDown.try_wait` |
246 |
| -//! /// |
247 |
| -//! /// This returns a future that must be polled to completion |
248 |
| -//! fn wait<T>(mut timer: T) -> impl Future<Item = T, Error = T::Error> |
249 |
| -//! where |
250 |
| -//! T: hal::timer::CountDown, |
251 |
| -//! { |
252 |
| -//! let mut timer = Some(timer); |
253 |
| -//! future::poll_fn(move || { |
254 |
| -//! match timer.as_mut().unwrap().try_wait() { |
255 |
| -//! Err(nb::Error::Other(e)) => return Err(e), |
256 |
| -//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady), |
257 |
| -//! Ok(_) => (), |
258 |
| -//! }; |
259 |
| -//! |
260 |
| -//! Ok(Async::Ready(timer.take().unwrap())) |
261 |
| -//! }) |
262 |
| -//! } |
263 |
| -//! |
264 |
| -//! /// `futures` version of `Serial.read` |
265 |
| -//! /// |
266 |
| -//! /// This returns a future that must be polled to completion |
267 |
| -//! fn read<S>(mut serial: S) -> impl Future<Item = (S, u8), Error = S::Error> |
268 |
| -//! where |
269 |
| -//! S: hal::serial::Read<u8>, |
270 |
| -//! { |
271 |
| -//! let mut serial = Some(serial); |
272 |
| -//! future::poll_fn(move || { |
273 |
| -//! let byte = match serial.as_mut().unwrap().try_read() { |
274 |
| -//! Err(nb::Error::Other(e)) => return Err(e), |
275 |
| -//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady), |
276 |
| -//! Ok(x) => x, |
277 |
| -//! }; |
278 |
| -//! |
279 |
| -//! Ok(Async::Ready((serial.take().unwrap(), byte))) |
280 |
| -//! }) |
281 |
| -//! } |
282 |
| -//! |
283 |
| -//! /// `futures` version of `Serial.write` |
284 |
| -//! /// |
285 |
| -//! /// This returns a future that must be polled to completion |
286 |
| -//! fn write<S>(mut serial: S, byte: u8) -> impl Future<Item = S, Error = S::Error> |
287 |
| -//! where |
288 |
| -//! S: hal::serial::Write<u8>, |
289 |
| -//! { |
290 |
| -//! let mut serial = Some(serial); |
291 |
| -//! future::poll_fn(move || { |
292 |
| -//! match serial.as_mut().unwrap().try_write(byte) { |
293 |
| -//! Err(nb::Error::Other(e)) => return Err(e), |
294 |
| -//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady), |
295 |
| -//! Ok(_) => (), |
296 |
| -//! }; |
297 |
| -//! |
298 |
| -//! Ok(Async::Ready(serial.take().unwrap())) |
299 |
| -//! }) |
300 |
| -//! } |
301 |
| -//! |
302 |
| -//! fn main() { |
303 |
| -//! // HAL implementers |
304 |
| -//! let timer: Timer6 = { |
305 |
| -//! // .. |
306 |
| -//! # Timer6 |
307 |
| -//! }; |
308 |
| -//! let serial: Serial1 = { |
309 |
| -//! // .. |
310 |
| -//! # Serial1 |
311 |
| -//! }; |
312 |
| -//! let led: Led = { |
313 |
| -//! // .. |
314 |
| -//! # Led |
315 |
| -//! }; |
316 |
| -//! |
317 |
| -//! // Tasks |
318 |
| -//! let mut blinky = future::loop_fn::<_, (), _, _>( |
319 |
| -//! (led, timer, true), |
320 |
| -//! |(mut led, mut timer, state)| { |
321 |
| -//! wait(timer).map(move |timer| { |
322 |
| -//! if state { |
323 |
| -//! led.on(); |
324 |
| -//! } else { |
325 |
| -//! led.off(); |
326 |
| -//! } |
327 |
| -//! |
328 |
| -//! Loop::Continue((led, timer, !state)) |
329 |
| -//! }) |
330 |
| -//! }); |
331 |
| -//! |
332 |
| -//! let mut loopback = future::loop_fn::<_, (), _, _>(serial, |mut serial| { |
333 |
| -//! read(serial).and_then(|(serial, byte)| { |
334 |
| -//! write(serial, byte) |
335 |
| -//! }).map(|serial| { |
336 |
| -//! Loop::Continue(serial) |
337 |
| -//! }) |
338 |
| -//! }); |
339 |
| -//! |
340 |
| -//! // Event loop |
341 |
| -//! loop { |
342 |
| -//! blinky.poll().unwrap(); // NOTE(unwrap) E = Infallible |
343 |
| -//! loopback.poll().unwrap(); |
344 |
| -//! # break; |
345 |
| -//! } |
346 |
| -//! } |
347 |
| -//! |
348 |
| -//! # mod stm32f1xx_hal { |
349 |
| -//! # use crate::hal; |
350 |
| -//! # use core::convert::Infallible; |
351 |
| -//! # pub struct Timer6; |
352 |
| -//! # impl hal::timer::CountDown for Timer6 { |
353 |
| -//! # type Error = Infallible; |
354 |
| -//! # type Time = (); |
355 |
| -//! # |
356 |
| -//! # fn try_start<T>(&mut self, _: T) -> Result<(), Infallible> where T: Into<()> { Ok(()) } |
357 |
| -//! # fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } |
358 |
| -//! # } |
359 |
| -//! # |
360 |
| -//! # pub struct Serial1; |
361 |
| -//! # impl hal::serial::Read<u8> for Serial1 { |
362 |
| -//! # type Error = Infallible; |
363 |
| -//! # fn try_read(&mut self) -> ::nb::Result<u8, Infallible> { Err(::nb::Error::WouldBlock) } |
364 |
| -//! # } |
365 |
| -//! # impl hal::serial::Write<u8> for Serial1 { |
366 |
| -//! # type Error = Infallible; |
367 |
| -//! # fn try_flush(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } |
368 |
| -//! # fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } |
369 |
| -//! # } |
370 |
| -//! # |
371 |
| -//! # pub struct Led; |
372 |
| -//! # impl Led { |
373 |
| -//! # pub fn off(&mut self) {} |
374 |
| -//! # pub fn on(&mut self) {} |
375 |
| -//! # } |
376 |
| -//! # } |
377 |
| -//! ``` |
378 |
| -//! |
379 | 226 | //! ## Generic programming and higher level abstractions
|
380 | 227 | //!
|
381 | 228 | //! The core of the HAL has been kept minimal on purpose to encourage building **generic** higher
|
382 | 229 | //! level abstractions on top of it. Some higher level abstractions that pick an asynchronous model
|
383 | 230 | //! or that have blocking behavior and that are deemed useful to build other abstractions can be
|
384 |
| -//! found in the `blocking` module and, in the future, in the `futures` and `async` modules. |
| 231 | +//! found in the `blocking` module. |
385 | 232 | //!
|
386 | 233 | //! Some examples:
|
387 | 234 | //!
|
|
0 commit comments