Is it possible to use a type which does not implement Send trait as the resource in RTIC

The code below has an error that *const (dyn gpio::private::GpioRegExt + 'static) cannot be sent between threads safely. This is caused by the field leds in struct Resources.

Reference to the document, I have known that if you want to use a value in different tasks with different priority, it must implement Send trait to keep the transfer safe. But if you use a value in different tasks with the same priority, there is no need for the value to implement Send trait. In my code, the leds is assigned in init in LateResources struct who has the lowest priority and is used in a task named blinker whose priority is 1.

It seems that I can solve the problem by declaring another task with the same priority with blinker and assigning resources in it. However, I cannot get peripherals handle in tasks without init::LateResources.

#![no_main]
#![no_std]

use panic_semihosting as _;
use rtic::{app, cyccnt::U32Ext};
use stm32f3xx_hal::{
    gpio::{Gpiox, Output, Pin, PushPull, Ux},
    prelude::*,
};

const PERIOD: u32 = 10_000_000;

#[app(device=stm32f3xx_hal::pac,peripherals=true, monotonic=rtic::cyccnt::CYCCNT)]
const APP: () = {
    struct Resources {
        leds: [Pin<Gpiox, Ux, Output<PushPull>>; 8],
        index: u32,
    }

    #[init(schedule = [blinker])]
    fn init(cx: init::Context) -> init::LateResources {
        let mut core = cx.core;
        core.DWT.enable_cycle_counter();

        let dp: stm32f3xx_hal::pac::Peripherals = cx.device;
        let mut rcc = dp.RCC.constrain();

        let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);
        let mut leds = [
            gpioe
                .pe8
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe9
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe10
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe11
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe12
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe13
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe14
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
            gpioe
                .pe15
                .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper)
                .downgrade()
                .downgrade(),
        ];

        cx.schedule.blinker(cx.start + PERIOD.cycles()).unwrap();
        init::LateResources { leds, index: 0 }
    }

    #[task(resources=[leds,index],schedule=[blinker])]
    fn blinker(cx: blinker::Context) {
        let mut index = cx.resources.index;
        cx.resources.leds[*index as usize].toggle().unwrap();
        *index = if *index == 0 { 7 } else { *index + 1 };
        cx.resources.leds[*index as usize].toggle().unwrap();
        cx.schedule.blinker(cx.scheduled + PERIOD.cycles()).unwrap();
    }

    extern "C" {
        fn EXTI0();
    }
}

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.