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 signaturefn(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