rust-embedded-community / ssd1306

SSD1306 OLED driver
Apache License 2.0
300 stars 68 forks source link

memchr does not declare `#![no_std]` #162

Closed pdgilbert closed 1 year ago

pdgilbert commented 2 years ago

Description of the problem/feature request/other

I forked to check how difficult it will be to convert rtic examples to recent release cortex-m-rtic v1.0.0. (I'm expecting some updating will be needed so if anyone has already done this then please point the way.) The very first thing I've hit is a problem which must be trivial but I don't understand. Changing only Cargo.toml line cortex-m-rtic = "0.5.6" to cortex-m-rtic = "1.0.0" I get

$ cargo build  --example rtic_dvd
  Compiling memchr v2.3.4
error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv7m-none-eabi` target may not support the standard library
  = note: `std` is required by `memchr` because it does not declare `#![no_std]`

Cargo update after the change gave

    Updating crates.io index
      Adding aho-corasick v0.7.15
      Adding atomic-polyfill v0.1.5
      Adding bare-metal v1.0.0
      Adding bit_field v0.10.1
      Adding cfg-if v1.0.0
    Updating cortex-m-rtic v0.5.9 -> v1.0.0
    Updating cortex-m-rtic-macros v0.5.3 -> v1.0.0
      Adding critical-section v0.2.5
    Updating hash32 v0.1.1 -> v0.2.1
    Updating heapless v0.6.1 -> v0.7.9
      Adding lazy_static v1.4.0
      Adding lock_api v0.4.5
      Adding proc-macro-error v1.0.4
      Adding proc-macro-error-attr v1.0.4
      Adding regex v1.4.6
      Adding regex-syntax v0.6.25
      Adding riscv v0.7.0
      Adding riscv-target v0.1.2
    Updating rtic-core v0.3.1 -> v1.0.0
      Adding rtic-monotonic v1.0.0
    Updating rtic-syntax v0.4.0 -> v1.0.0
      Adding scopeguard v1.1.0
      Adding spin v0.9.2

so it looks like there is no change to memchr. If I add [dependencies] memchr = { version = "2", default-features = false } it makes no difference. The memchr documentation suggests it is no_std, and in any case I do not see why the change in version of cortex-m-rtic affects this.

Any hints?

jamwaffles commented 2 years ago

I've reproduce this locally which is good. Looks like tinybmp and it's older nom dependency is the culprit:

memchr v2.3.4
└── nom v6.2.1
    └── tinybmp v0.3.1
        [dev-dependencies]
        └── ssd1306 v0.7.0 (/Users/james/Repositories/ssd1306)

I'll do some fiddling in tinybmp and see what I can do there.

jamwaffles commented 2 years ago

Looks like the dependency issue is fixed by using edition = "2021" in Cargo.toml. I want to do the same with tinybmp anyway, so this would be a good opportunity to upgrade (and open the door to some shinier new features perhaps).

pdgilbert commented 2 years ago

Ok, that solves the dependency issue. FWIW, copied below is example rtic_dvd with the gross syntax/renaming/etc of cortex-m-rtic v1.0.0. It gets as far as locking issues and de-referencing problems that are a bit beyond me. I've possibly added some unneeded things and maybe clobbered things that are needed.

//! Bounce a DVD player logo around the screen
//!
//! Like this, but with no color changing: https://bouncingdvdlogo.com/
//!
//! For best results, run with the `--release` flag.

#![no_std]
#![no_main]

use panic_halt as _;
use rtic::app;

#[rtic::app(device = stm32f1xx_hal::pac,   dispatchers = [TIM1_UP, EXTI0])]

mod app {

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

    use systick_monotonic::*;
    // secs() and millis() methods from https://docs.rs/fugit/latest/fugit/trait.ExtU32.html#tymethod.secs

    use fugit::TimerDuration;

    const MONOTICK: u32 = 100;
    const CLOCK: u32 = 8_000_000; 

    use stm32f1xx_hal::{
        delay::Delay,
        gpio,
        pac::{self, SPI1},
        prelude::*,
        spi::{self, Mode, Phase, Polarity, Spi},
        timer::{CountDownTimer, Event, Timer},
    };
    use tinybmp::Bmp;

    type Display = Ssd1306<
        SPIInterfaceNoCS<
            spi::Spi<
                SPI1,
                spi::Spi1NoRemap,
                (
                    gpio::gpioa::PA5<gpio::Alternate<gpio::PushPull>>,
                    gpio::gpioa::PA6<gpio::Input<gpio::Floating>>,
                    gpio::gpioa::PA7<gpio::Alternate<gpio::PushPull>>,
                ),
                u8,
            >,
            gpio::gpiob::PB1<gpio::Output<gpio::PushPull>>,
        >,
        DisplaySize128x64,
        BufferedGraphicsMode<DisplaySize128x64>,
    >;

    use display_interface_spi::SPIInterfaceNoCS;
    use embedded_graphics::{
        geometry::Point,
        image::Image,
        pixelcolor::{BinaryColor, Rgb565},
        prelude::*,
        primitives::{PrimitiveStyle, Rectangle},
    };

   #[shared]
   struct Shared {
        display: Display,
        timer: CountDownTimer<pac::TIM1>,
        top_left: Point,
        velocity: Point,
        bmp: Bmp<Rgb565, 'static>,
    }

    #[local]
    struct Local {}

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

    #[init]
    fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
        let dp = cx.device;
        let core = cx.core;

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

        let clocks = rcc
            .cfgr
            .use_hse(8.mhz())
            .sysclk(72.mhz())
            .pclk1(36.mhz())
            .freeze(&mut flash.acr);

        let mut afio = dp.AFIO.constrain(&mut rcc.apb2);

        let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
        let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);

        // SPI1
        let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl);
        let miso = gpioa.pa6;
        let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);

        let mut delay = Delay::new(core.SYST, clocks);

        let mut rst = gpiob.pb0.into_push_pull_output(&mut gpiob.crl);
        let dc = gpiob.pb1.into_push_pull_output(&mut gpiob.crl);

        let spi = Spi::spi1(
            dp.SPI1,
            (sck, miso, mosi),
            &mut afio.mapr,
            Mode {
                polarity: Polarity::IdleLow,
                phase: Phase::CaptureOnFirstTransition,
            },
            8.mhz(),
            clocks,
            &mut rcc.apb2,
        );

        let interface = display_interface_spi::SPIInterfaceNoCS::new(spi, dc);
        let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate180)
            .into_buffered_graphics_mode();

        display.reset(&mut rst, &mut delay).unwrap();
        display.init().unwrap();

        // Update framerate
        let fps = 20;

        let mut timer = Timer::tim1(dp.TIM1, &clocks, &mut rcc.apb2).start_count_down(fps.hz());

        timer.listen(Event::Update);

        let bmp = Bmp::from_slice(include_bytes!("dvd.bmp")).unwrap();

       let mono = Systick::new(cx.core.SYST, CLOCK);

        (Shared { timer, display, top_left: Point::new(5, 3),velocity: Point::new(1, 1), bmp }, 
         Local {}, 
         init::Monotonics(mono))
    }

    // just guessing on capacity
    #[task(shared = [timer, display, top_left, velocity, bmp], capacity=2)]
    fn update(cx: update::Context) {
        //   let update::Resources {
        //       display,
        //       top_left,
        //       velocity,
        //       timer,
        //       bmp,
        //       ..
        //   } = cx.resources;

        let bottom_right = *cx.shared.top_left + cx.shared.bmp.bounding_box().size;

        // Erase previous image position with a filled black rectangle
        Rectangle::with_corners(*cx.shared.top_left, bottom_right)
            .into_styled(PrimitiveStyle::with_fill(BinaryColor::Off))
            .draw(cx.shared.display)
            .unwrap();

        // Check if the image collided with a screen edge
        {
            if bottom_right.x > cx.shared.display.size().width as i32 || cx.shared.top_left.x < 0 {
                cx.shared.velocity.x = -cx.shared.velocity.x;
            }

            if bottom_right.y > cx.shared.display.size().height as i32 || cx.shared.top_left.y < 0 {
                cx.shared.velocity.y = -cx.shared.velocity.y;
            }
        }

        // Move the image
        *cx.shared.top_left += *cx.shared.velocity;

        // Draw image at new position
        Image::new(cx.shared.bmp, *cx.shared.top_left)
            .draw(&mut cx.shared.display.color_converted())
            .unwrap();

        // Write changes to the display
        cx.shared.display.flush().unwrap();

        // Clears the update flag
        cx.shared.timer.clear_update_interrupt_flag();
    }
}
pdgilbert commented 1 year ago

I think this has been resolved.