Hi , I am trying to abstract a layar from another using traits and I get some lifetime error.
#![cfg(not(any(target_os = "none", target_os = "linux")))]
use crate::kline::KlineMessage;
use crate::kline::{KlineHardwareHandshake, KlineHardwareTransmit};
use alloc::format;
use alloc::rc::Rc;
use core::cell::RefCell;
use core::marker::PhantomData;
use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::{InputPin, Output, OutputPin, PinDriver};
use esp_idf_hal::peripheral::Peripheral;
use esp_idf_hal::uart::{config::Config, Uart as Uart_idf, UartDriver};
use protocols::config;
// an abstract layer for uart for my library
pub struct Uart<'d> {
serial: esp_idf_hal::uart::UartDriver<'d>,
_p: PhantomData<&'d mut ()>,
}
impl<'d> Uart<'d> {
pub fn new(serial: esp_idf_hal::uart::UartDriver<'d>) -> Self {
Self {
serial,
_p: PhantomData,
}
}
}
impl<'d> KlineHardwareTransmit for Uart<'d> {
fn transmit(&mut self, frame: &KlineMessage) {
platform::functions::print_string(format!("frame is : {:?}", frame.data));
self.serial.write(&frame.data).expect("could not send");
}
fn read(&self, buf: &mut [u8], delay: u32) -> Result<usize, ()> {
platform::functions::print_string(format!("read frame is : {:?}", buf));
match self.serial.read(buf, delay) {
Ok(size) => Ok(size),
_ => Err(()),
}
}
}
unsafe impl<'d> Send for Uart<'d> {}
pub struct KlinePeripherals<Tx, Rx, U> {
tx: Rc<RefCell<Tx>>,
rx: Rc<RefCell<Rx>>,
uart: Rc<RefCell<U>>,
}
impl<'d, Tx: Peripheral + 'd, Rx: Peripheral + 'd, U: Peripheral + 'd> KlinePeripherals<Tx, Rx, U>
where
Tx::P: OutputPin,
Rx::P: InputPin,
U::P: Uart_idf,
{
pub fn new(tx: Tx, rx: Rx, uart: U) -> Self {
Self {
tx: Rc::new(RefCell::new(tx)),
rx: Rc::new(RefCell::new(rx)),
uart: Rc::new(RefCell::new(uart)),
}
}
pub fn to_uart(&self, config: &Config) -> Result<Uart, ()> {
let serial = Uart::new(
UartDriver::new(
self.uart.borrow_mut(),
self.tx.borrow_mut(),
self.rx.borrow_mut(),
config,
)
.unwrap(),
);
Ok(serial)
}
}
impl<
'd,
Tx: Peripheral + 'd + esp_idf_hal::gpio::OutputPin,
Rx: Peripheral + 'd,
U: Peripheral + 'd,
> crate::kline::ToHandshake<'d, Handshake<'d, Tx>> for KlinePeripherals<Tx, Rx, U>
where
Tx::P: OutputPin,
Rx::P: InputPin,
U::P: Uart_idf,
{
fn to_handshake(&'d mut self) -> Handshake<'d, Tx> {
Handshake {
kline_tx: PinDriver::output(self.tx.borrow_mut()).unwrap(),
_p: PhantomData,
}
}
}
pub struct Handshake<'d, Tx: OutputPin> {
kline_tx: PinDriver<'d, Tx, Output>,
_p: PhantomData<&'d ()>,
}
impl<'d, Tx: OutputPin> KlineHardwareHandshake for Handshake<'d, Tx> {
fn init(&mut self, init_type: config::KlineInitType) {
match init_type {
config::KlineInitType::KLINE_INIT_TYPE_FAST => {
self.kline_tx.set_low();
FreeRtos::delay_ms(25);
self.kline_tx.set_high();
FreeRtos::delay_ms(25);
}
config::KlineInitType::KLINE_INIT_TYPE_5_BAUD => {
self.kline_tx.set_low();
FreeRtos::delay_ms(400);
self.kline_tx.set_high();
FreeRtos::delay_ms(400);
}
}
platform::functions::print_str("handshake");
}
}
this is my code and the error is
error: lifetime may not live long enough
--> modules/ecu/src/kline/mod.rs:118:25
|
78 | impl<'d, U, H, Tx: ToUart<U> + ToHandshake<'d, H>> KlineTransceiver<'d, U, H, Tx>
| -- lifetime `'d` defined here
...
111 | pub fn process(&mut self) {
| - let's call the lifetime of this reference `'1`
...
118 | self.kline_transceiver.to_handshake().init(self.init_type);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'d` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'d`
I should tell the compiler that handshake may live less that the main prephrials. But as it seems I am doing it wrong.