Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Implementing embedded_io:Write trait for STM32G0 HAL usarts
Hey!
I have an application where im using the stm32g0xx_hal crate together with the embedded_io crate.
Im a bit new at embedded rust and im coming from c, so some of the mechanisms in rust are quite new to me.
I want a generic way of using the uarts (TX part only) so i dont have to hardcode the usart with a driver.
I have therefore tried to use the Write trait in the embedded_io crate by creating a wrapper that takes a generic type(but restricted to a set of acceptable USART TX types from the STMG0 HAL crate) and then the wrapper implements the Write trait.
The Wrapper is later passed to a struct(named TerminalData) who then owns it where it will be used from later.
I just cant get it to work, I keep getting the "Bounds not satisfied" error. This is the code:
use embedded_io::Write;
use stm32g0xx_hal::serial::Tx;
pub struct TerminalData
{
terminal_writer: Box<dyn embedded_io::Write<Error = Infallible>>,
}
pub trait UsartInstance {}
impl UsartInstance for hal::pac::USART1 {}
impl UsartInstance for hal::pac::USART2 {}
impl UsartInstance for hal::pac::USART3 {}
impl UsartInstance for hal::pac::USART4 {}
impl embedded_io::ErrorType for TerminalData {
type Error = Infallible; // Define the associated Error type
}
impl<T> ErrorType for TxWrapper<T> {
type Error = Infallible; // Define the associated error type
}
pub struct TxWrapper<T>(hal::serial::Tx<T, hal::serial::FullConfig>);
impl<T> TxWrapper<T>
where
T: UsartInstance, // Restrict T to USART types
{
pub fn new(tx: hal::serial::Tx<T, hal::serial::FullConfig>) -> Self {
TxWrapper(tx)
}
}
impl<T> Write for TxWrapper<T>
where
T: UsartInstance,
hal::serial::Tx<T, hal::serial::FullConfig>: embedded_io::Write<Error = Infallible>,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
// Write the buffer to the terminal writer
self.0.write(buf);
Ok(buf.len())
}
fn flush(&mut self) -> Result<(), Self::Error> {
// Flush the terminal writer
Ok(())
}
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
self.write(buf).map(|_| ())
}
}
impl TerminalData
{
pub fn new<W1>(input_tx: W1) -> Self
where
W1: embedded_io::Write<Error = Infallible> + 'static, // Ensure the writer is 'static
{
Self {
terminal_writer: Box::new(input_tx),
}
}
}
The error comes when I from main.rs create the instance of the Struct "Terminal":
let mut terminal_com_port: Serial<stm32::USART2, FullConfig> = ctx.device.USART2
.usart(
(gpioa.pa2, gpioa.pa3),
FullConfig::default().baudrate(115200.bps()).fifo_enable().rx_fifo_enable_interrupt().rx_fifo_threshold(FifoThreshold::FIFO_1_BYTE),
&mut rcc,
)
.unwrap();
/* split the serial object in TX and RX parts */
let (mut terminal_com_port_tx, mut terminal_com_port_rx) = terminal_com_port.split();
let terminal_com_port_tx_wrapper = TxWrapper::new(terminal_com_port_tx);
let mut local_terminal_instance: terminal::TerminalData = terminal::TerminalData::new(terminal_com_port_tx_wrapper);
Bounds are not satisfied:
error[E0277]: the trait bound `hal::serial::Tx<hal::pac::USART2, hal::serial::FullConfig>: embedded_io::Write` is not satisfied
--> src\main.rs:244:95
|
244 | let mut local_terminal_instance: terminal::TerminalData = terminal::TerminalData::new(terminal_com_port_tx);
| --------------------------- ^^^^^^^^^^^^^^^^^^^^ the trait `embedded_io::Write` is not implemented for `hal::serial::Tx<hal::pac::USART2, hal::serial::FullConfig>`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `embedded_io::Write`:
&mut T
&mut [u8]
terminal::TxWrapper<T>
note: required for `terminal::TxWrapper<hal::pac::USART2>` to implement `embedded_io::Write`
--> src\terminal.rs:97:9
|
97 | impl<T> Write for TxWrapper<T>
| ^^^^^ ^^^^^^^^^^^^
...
100 | hal::serial::Tx<T, hal::serial::FullConfig>: embedded_io::Write<Error = Infallible>,
| -------------------------------------- unsatisfied trait bound introduced here
note: required by a bound in `TerminalData::new`
--> src\terminal.rs:136:13
|
134 | pub fn new<W1>(input_writer: W1) -> Self
| --- required by a bound in this associated function
135 | where
136 | W1: embedded_io::Write<Error = Infallible> + 'static, // Ensure the writer is 'static
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `TerminalData::new`
What am I missing?. Am I way off in how to use these crates and their types?
2 posts - 2 participants
🏷️ rust_feed