Question: How to share a variable containing lifetime specifier ('a) in RTIC shared struct?

Hi I am fairly new to Rust Embedded development. I am using RTIC for writing a firmware for BluePill (stm32f103). I want to share a struct with 'a lifetime specifier using the RTIC framework's local or shared struct mechanism. When I try to share the struct variable I get the following

error: the #[init] function must have signature fn(init::Context) -> (Shared resources struct, Local resources struct, init::Monotonics)

because I had to use the

fn init<'a>(cx: init::Context) -> (Shared, Local<'a>, init::Monotonics)

in order to share the variable containing lifetime specifier. I could not change the variable lifetime since it is from another library function. Here is the complete code

#![no_std]
#![no_main]

/*
    
    Description:
        Pin Configuration:
            - PA6: Winder Motor Pulse ( Connected to Timer 3 Channel 1)
            - PB12: Winder Motor Direction
            - PA1: Linear Guide Motor Pulse ( Connected to Timer 2 Channel 2)
            - PA15: Linear Guide Motor Direction
            - PA2: Push Button to reverse the direction of Winder Motor
            - PA3: Push Button for Spool Change
            - PB0: Push Button for Fast Forward Winder Motor
            - PB4: Proximity Sensor
            - PB6: I2C SCL
            - PB7: I2C SDA
            - PA11: USB -ve Line
            - PA12: USB +ve Line
*/


use rtic::app;
use panic_semihosting as _;

#[app(device = stm32f1xx_hal::pac, peripherals = true)]
mod app {
    use lcd_lcm1602_i2c::Lcd;
    use stm32f1xx_hal::{
        stm32,
        prelude::*,
        i2c::{BlockingI2c, DutyCycle, Mode},
    };
    use stm32f1xx_hal::gpio::{Alternate, OpenDrain, Pin};
    use stm32f1xx_hal::pac::{I2C1, TIM4};
    use stm32f1xx_hal::pac::rtc::CRL;
    use stm32f1xx_hal::timer ::Delay;


    #[shared]
    struct Shared{

    }

    #[local]
    struct Local<'a> {
        // Declaring Lcd as local variable to be used in the idle task
        lcd: Lcd<'a,BlockingI2c<I2C1, (stm32f1xx_hal::gpio::Pin<Alternate<OpenDrain>, CRL, 'B', 6_u8>, stm32f1xx_hal::gpio::Pin<Alternate<OpenDrain>, CRL, 'B', 7_u8>)>, stm32f1xx_hal::timer::Delay<stm32f1xx_hal::pac::TIM4, 10000_u32>>
    }

    #[init]
    fn init<'a>(cx: init::Context) ->(Shared, Local<'a>, init::Monotonics) {
    // fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
        let mut dp: stm32::Peripherals = cx.device;
        let mut cp: cortex_m::Peripherals = cx.core;

        let mut rcc = dp.RCC.constrain();
        let mut flash = dp.FLASH.constrain();
        let mut afio = dp.AFIO.constrain();

        // Configure the clock
        let clocks = rcc.cfgr
            .use_hse(8.MHz())
            .sysclk(48.MHz())
            .pclk1(24.MHz())
            .freeze(&mut flash.acr);

        // I2C configuration
        let mut gpiob = dp.GPIOB.split();
        let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl);
        let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl);

        const LCD_ADDRESS: u8 = 0x27;
        let mut i2c = BlockingI2c::i2c1(
            dp.I2C1,
            (scl, sda),
            &mut afio.mapr,
            Mode::Fast {
                frequency: 5000.Hz(),
                duty_cycle: DutyCycle::Ratio16to9
            },
            clocks,
            1000,
            10,
            1000,
            1000
        );

        let mut delay = dp.TIM4.delay::<10000>(&clocks);

        let mut lcd = lcd_lcm1602_i2c::Lcd::new(&mut i2c, &mut delay)
            .address(LCD_ADDRESS)
            .cursor_on(true) // no visible cursos
            .rows(2) // two rows
            .init().unwrap();
        lcd.clear().unwrap();
        lcd.set_cursor(0,0).unwrap();


        (Shared{}, Local{lcd}, init::Monotonics())
    }




}

Thank you. Any help is appreciated

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.