embedded-trainings-2020/down-the-stack-book/src/building_common_abstractions.md
Jonathan Pallant (Ferrous Systems) b6aaf36f30
Renamed a file and removed a topic
2023-03-23 09:20:02 +00:00

1.9 KiB

Building Common Abstractions


These things are different

  • STM32F030 UART Driver
  • nRF52840 UART Driver
  • But I want to write a library which is generic!
    • e.g. an AT Command Parser

How does Rust allow generic behaviour?

  • Generics!
  • where T: SomeTrait

Traits

trait GenericSerial {
    type Error;
    fn read(&mut self, buffer: &mut [u8]) -> Result<usize, Error>;
    fn write(&mut self, buffer: &[u8]) -> Result<usize, Error>;
}

My Library...

struct AtCommandParser<T> {
    uart: T,
    ...
}

impl<T> AtCommandParser<T> where T: GenericSerial {
    fn new(uart: T) -> AtCommandParser<T> { ... }
    fn get_command(&mut self) -> Result<Option<AtCommand>, Error> { ... }
}

Note how AtCommandParser owns the object which meets the GenericSerial trait.


My Application

let uart = stm32_hal::Uart::new(...);
let at_parser = at_library::AtCommandParser::new(uart);
while let Some(cmd) = at_parser.get_command().unwrap() {
    ...
}

My Application (2)

let uart = nrf52_hal::Uart::new(...);
let at_parser = at_library::AtCommandParser::new(uart);
while let Some(cmd) = at_parser.get_command().unwrap() {
    ...
}

How do we agree on the traits?

  • The Rust Embedded Working Group has developed some traits
  • They are called the Embedded HAL
  • See https://docs.rs/embedded-hal/
  • All HAL implementations should implement these traits

Blocking vs Non-blocking

  • Should a trait API stall your CPU until the data is ready?
  • Or should it return early, saying "not yet ready"
    • So you can go an do something else in the mean time?
    • Or sleep?
  • embedded_hal::blocking::serial::Write, vs
  • embedded_hal::serial::Write

Trade-offs

  • Some MCUs have more features than others
  • The trait design has an inherent trade-off
    • Flexibility/Performance vs Portability