Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssd1306 with rtic 1.0.0 #164

Open
pdgilbert opened this issue Feb 7, 2022 · 7 comments
Open

ssd1306 with rtic 1.0.0 #164

pdgilbert opened this issue Feb 7, 2022 · 7 comments

Comments

@pdgilbert
Copy link

(some relationship with #162.)

  • Version of ssd1306 in use: recent git
  • MCU/other hardware in use: blackpill 411 using a recent git version of stm32f4xx_hal (no-std)
  • Display resolution and interface:128x64 I2C shared-bus

Description of the problem/feature request/other

I am trying to use ssd1306 with rtic v1.0.0 and am stuck on two errors. One is a trait problem with the draw method trying to write on the display

Click to expand
 Compiling test-example v0.1.0 (/home/paul/githubClones/rust-integration-testing/dev-testing)
error[E0599]: the method `draw` exists for struct `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>`, but its trait bounds were not satisfied
   --> examples/zzdisplay_stuff_rtic.rs:123:15
    |
123 |             ).draw(&mut cx.local.display).unwrap();
    |               ^^^^ method cannot be called on `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>` due to unsatisfied trait bounds
    |
   ::: /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-0.7.1/src/text/text.rs:23:1
    |
23  | pub struct Text<'a, S> {
    | ----------------------
    | |
    | doesn't satisfy `<_ as Iterator>::Item = Pixel<_>`
    | doesn't satisfy `_: Iterator`
    | doesn't satisfy `_: embedded_graphics::Drawable`
    | doesn't satisfy `_: embedded_graphics::iterator::PixelIteratorExt<_>`
    |
    = note: the following trait bounds were not satisfied:
            `<Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>> as Iterator>::Item = Pixel<_>`
            which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`
            `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator`
            which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`
            `<&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>> as Iterator>::Item = Pixel<_>`
            which is required by `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`
            `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator`
            which is required by `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`
            `&mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>: TextRenderer`
            which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::Drawable`
            `<&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>> as Iterator>::Item = Pixel<_>`
            which is required by `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`
            `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator`
            which is required by `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>`

The other is a problem with something not being thread safe.

Click to expand
error[E0277]: `(dyn GlyphMapping + 'static)` cannot be shared between threads safely
   --> examples/zzdisplay_stuff_rtic.rs:15:35
    |
15  | #[cfg_attr(feature = "stm32f4xx", app(device = stm32f4xx_hal::pac,   dispatchers = [TIM2, TIM3]))]
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn GlyphMapping + 'static)` cannot be shared between threads safely
    |
    = help: within `MonoFont<'static>`, the trait `Sync` is not implemented for `(dyn GlyphMapping + 'static)`
    = note: required because it appears within the type `&'static (dyn GlyphMapping + 'static)`
    = note: required because it appears within the type `MonoFont<'static>`
    = note: required because of the requirements on the impl of `Send` for `&'static MonoFont<'static>`
    = note: required because it appears within the type `embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>`
note: required by a bound in `assert_send`
   --> /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rtic-1.0.0/src/export.rs:107:8
    |
107 |     T: Send,
    |        ^^^^ required by this bound in `assert_send`
    = note: this error originates in the attribute macro `app` (in Nightly builds, run with -Z macro-backtrace for more info)

I do have a similar non-rtic example working with stm32f4xx_hal , so this is an rtic specific problem.

Test case

Click to expand code
//! Display the word "stuff" on OLED with i2c.   Using stm32f4xx_hal

#![deny(unsafe_code)]
#![no_std]
#![no_main]

#[cfg(debug_assertions)]
use panic_semihosting as _;

#[cfg(not(debug_assertions))]
use panic_halt as _;

use rtic::app;

#[cfg_attr(feature = "stm32f4xx", app(device = stm32f4xx_hal::pac,   dispatchers = [TIM2, TIM3]))]

mod app {
    //use cortex_m_semihosting::{debug, hprintln};
    use cortex_m_semihosting::{hprintln};

    use core::fmt::Write;

    use embedded_graphics::{
        mono_font::{iso_8859_1::FONT_10X20, MonoTextStyleBuilder, MonoTextStyle},  //FONT_6X10  FONT_8X13
        pixelcolor::BinaryColor,
        prelude::*,
        text::{Baseline, Text},
    };

    use ssd1306::{mode::BufferedGraphicsMode, prelude::*, I2CDisplayInterface, Ssd1306};

    use systick_monotonic::*;    

    const MONOTICK: u32 = 100;
    const READ_INTERVAL: u64 = 10;  // used as seconds

    use shared_bus::{I2cProxy};
    use core::cell::RefCell;
    use cortex_m::interrupt::Mutex;


    use stm32f4xx_hal::{
        gpio::{Alternate, OpenDrain, 
        gpiob::{PB8, PB9, },
        },
        i2c::I2c,
        pac::{Peripherals, I2C1},
        prelude::*,
    };

    pub type I2c1Type = I2c<I2C1, (PB8<Alternate<OpenDrain, 4u8>>, PB9<Alternate<OpenDrain, 4u8>>)>;

    const MONOCLOCK: u32 = 16_000_000; //should be set for board not for HAL

    fn setup(dp: Peripherals) -> I2c1Type {
       let rcc = dp.RCC.constrain();
       let clocks = rcc.cfgr.freeze();

       let gpiob = dp.GPIOB.split();

       let scl = gpiob.pb8.into_alternate_open_drain(); 
       let sda = gpiob.pb9.into_alternate_open_drain(); 

       let i2c = I2c::new(dp.I2C1, (scl, sda), 400.khz(), &clocks);

       i2c
    }

    #[monotonic(binds = SysTick, default = true)]
    type MyMono = Systick<MONOTICK>;

    #[init]
    fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
       let mono = Systick::new(cx.core.SYST, MONOCLOCK);

       let i2c = setup(cx.device);

       let manager: &'static _ = shared_bus::new_cortexm!(I2c1Type = i2c).unwrap();
       let interface = I2CDisplayInterface::new(manager.acquire_i2c());

       let text_style = MonoTextStyleBuilder::new().font(&FONT_10X20).text_color(BinaryColor::On).build();

       let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
          .into_buffered_graphics_mode();

       display.init().unwrap();
       hprintln!("display.init",).unwrap();

       Text::with_baseline("Display initialized ...", Point::zero(), text_style, Baseline::Top, )
          .draw(&mut display).unwrap();

       display_stuff::spawn().unwrap();

       (Shared {}, Local { display, text_style }, init::Monotonics(mono))
    }

    #[shared]
    struct Shared {}

    #[local]
    struct Local {
        display:  Ssd1306<I2CInterface<I2cProxy<'static, Mutex<RefCell<I2c1Type>>>>, 
                     ssd1306::prelude::DisplaySize128x64, 
                     BufferedGraphicsMode<DisplaySize128x64>>,
        text_style: MonoTextStyle<'static, BinaryColor>,
    }

    #[task(shared = [], local = [display, text_style,], capacity=2)]
    fn display_stuff(cx: display_stuff::Context) {

        let mut lines: [heapless::String<32>; 1] = [ heapless::String::new(), ];
       
        write!(lines[0], "stuff").unwrap();
     
        cx.local.display.clear();
        for i in 0..lines.len() {
            // start from 0 requires that the top is used for font baseline
            Text::with_baseline(
                &lines[i],
                Point::new(0, i as i32 * 12), //with font 6x10, 12 = 10 high + 2 space
                cx.local.text_style,
                Baseline::Top,
            ).draw(&mut cx.local.display).unwrap();
        }
        cx.local.display.flush().unwrap();
          
        display_stuff::spawn_after(READ_INTERVAL.secs()).unwrap();
    }
}
Click to expand Cargo.toml
[package]
authors = ["Paul"]
categories = ["embedded", "no-std"]
description = "test example"
keywords = ["driver", "i2c", "spi", "example"]
license = "MIT OR Apache-2.0"
name = "test-example"
version = "0.1.0"
edition = "2021"

[dependencies]

stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal", optional = true } 

ssd1306         = { git = "https://github.com/jamwaffles/ssd1306"  }  

cortex-m-rtic = ">=1.0" 
#cortex-m-rtic = { git = "https://github.com/rtic-rs/cortex-m-rtic" }
systick-monotonic = {version = "1.0.0", optional = true }
#systick-monotonic = { git = "https://github.com/rtic-rs/systick-monotonic.git", optional = true }

#dwt-systick-monotonic = "1.0"   # this seems to be needed for adc_dma_rtic fiddling


embedded-hal = {version = "^0.2.4" }
#embedded-hal = { version = "1.0.0-alpha.6,<1.0.0-alpha.7", package = "embedded-hal" }  

embedded-graphics = ">=0.7"
#shared-bus = { version = "0.2.2", features = ["cortex-m"] } 
shared-bus = {  git = "https://github.com/Rahix/shared-bus", features = ["cortex-m"] } 
heapless = "0.7"
nb = ">=0.1.2"
libm = "0.2"
cortex-m = ">=0.7"
cortex-m-rt = ">=0.7.0"

cortex-m-semihosting = { version = "0.3.7" }
panic-semihosting    = { version = ">=0.5.2" }
panic-reset          = { version = ">=0.1.0" }
panic-halt           = { version = ">=0.2.0" }

[features]
stm32f4xx = ["stm32f4xx-hal/rt", "systick-monotonic"]
stm32f411     = ["stm32f4xx-hal/stm32f411"  ] 
@jamwaffles
Copy link
Collaborator

Thanks for the detailed issue! I don't have much spare time at the moment but I'll look at reproducing your issue when I can :)

@afternoon
Copy link

afternoon commented Oct 17, 2022

I'm trying to do something similar to the above code. The problem seems to come from passing the embedded_graphics MonoFontStyle value as a resource, which isn't an issue with this crate.

A workaround is to build the text style in the task itself.

@pdgilbert
Copy link
Author

Thanks @afternoon for pointing out this workaround. I have now re-enabled ssd1306 code in several examples and all are compiling. I'll get around to testing on hardware sometime soon.

@snorkman88
Copy link

@pdgilbert I am also using the Blackpill board which is based on that STM32F411CEU6 and RTIC v2.0.
Have you managed to make it work? Can you share a sample code?

@pdgilbert
Copy link
Author

I have made this work with RTIC v1 (cortex-m-rtic = ">=1.0"). I have several examples at https://github.com/pdgilbert/rust-integration-testing. See directory examples/. I have just started playing with RTIC v2 but am running into problems compiling rtic with embedded-hal 1.0.0-rc.2. See rtic-rs/rtic#862.

@pdgilbert
Copy link
Author

I have now compiled examples using RTIC v2 and stm32f4xx_hal with both embedded-hal 1.0.0-rc2 and a fork using rc3. These are in the eh-1-rc2 and eh-1-rc3 branches at https://github.com/pdgilbert/rust-integration-testing. (See the CI testing in Actions.) I have also run tested one example on hardware. This all uses the stm32f4xx_hal dual support for embedded-hal 1.0.0 as well as an older version. That means user code and rtic can use embedded-hal 1.0.0 while ssd1306 uses embedded-hal 0.2.7. The tree for this is pretty ugly. I think it must be considered a transition solution and I look forward to an ssd1306 crate based on embedded-hal 1.0.0 .

@pdgilbert
Copy link
Author

It seems likely that rtic v1.x.x will be abandoned with the release of embedded-hal 1.0.0. Users really should convert to rtic v2. (This needs to be emphasized given this old issue title "ssd1306 with rtic 1.0.0".)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants