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

Example using teensy4_bsp with rtic? #62

Closed
mitchmindtree opened this issue Jun 22, 2020 · 3 comments · Fixed by #64
Closed

Example using teensy4_bsp with rtic? #62

mitchmindtree opened this issue Jun 22, 2020 · 3 comments · Fixed by #64

Comments

@mitchmindtree
Copy link
Contributor

mitchmindtree commented Jun 22, 2020

Hi! I'm interested in creating a small example that demonstrates how to use teensy4_bsp alongside rtic. Something simple like blinking the on-board LED that demonstrates the basic setup required.

Here's what I have so far:

#![no_std]
#![no_main]

use embedded_hal::digital::v2::OutputPin;
use panic_halt as _;

#[rtic::app(device = teensy4_bsp, peripherals = true)]
const APP: () = {
    #[init]
    fn init(cx: init::Context) {
        // Cortex-M peripherals
        let _core: cortex_m::Peripherals = cx.core;

        // Device specific peripherals
        let device: teensy4_bsp::Peripherals = cx.device;

        let mut led = teensy4_bsp::configure_led(&mut device.gpr, device.pins.p13);
    }
};

I'm just starting with minimum viable project rtic project as described in their guide here, though so far I'm running into this compilation error:

error[E0599]: no function or associated item named `steal` found for struct `teensy4_bsp::Peripherals` in the current scope
 --> morph-fw-module/src/main.rs:7:1
  |
7 | #[rtic::app(device = teensy4_bsp, peripherals = true)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `teensy4_bsp::Peripherals`

One of the first things I'm unsure about is whether or not I'm able to directly specify the teensy4_bsp crate as the rtic::app device parameter as I'm doing above. The book mentions that a crate should be specified that was generated via svd2rust - teensy4-bsp appears to be hand-rolled but I did notice that the imxrt-hal crate has an rtfm feature (the previous moniker for rtic) so perhaps it's a matter of exposing this via a feature?

I'm quite new to both rust-embedded and rtic, so any advice you could offer on how to move ahead with this example would be greatly appreciated! Would also be happy to open a PR up here with the rtic_led.rs example if once complete if you're interested.

Edit: Ahh I just noticed #52 - my understanding is that this would allow creating the teensy4_bsp peripherals from the imxrt peripherals, though it looks like since the PR was opened the pac crate has been deprecated in favour of the new ral crate. Any advice on using the ral alongside rtic?

@mciantyre
Copy link
Owner

RTIC (formerly RTFM) support isn't as straight forward as we'd like. But, it's do-able. We'll show how to turn on the LED from RTIC, then we'll talk about today's biggest limitation.

I've started by prototyping RTIC support in the imxrt-hal crate. I'm starting with the imxrt-hal crate, because it's teensy4-bsp's main dependency. I'd approach this by first adding support in the HAL, then bringing it up to the BSP.

Check out the proto/rtic branch of my imxrt-hal fork. I've added a steal() method to Peripherals. I put together a test crate for Teensy 4 (t4) examples. There's an example, t4-examples/src/rtic.rs, that demonstrates how to turn on the LED through RTIC's initialization:

#![no_std]
#![no_main]

extern crate teensy4_fcb;

use embedded_hal::digital::v2::OutputPin;
use panic_halt as _;

use imxrt_hal::gpio::IntoGpio;

// Note: HAL, not BSP --v
#[rtic::app(device = imxrt_hal, peripherals = true)]
const APP: () = {
    #[init]
    fn init(cx: init::Context) {
        // Cortex-M peripherals
        let _core: cortex_m::Peripherals = cx.core;

        // Device specific peripherals
        let device: imxrt_hal::Peripherals = cx.device;

        // Prepare the LED
        //
        // The LED on the Teensy 4 is driven by pad B0_03.
        let mut led = device.iomuxc.gpio_b0_03.alt5().into_gpio().output();
        led.set_high().unwrap();
    }
    #[idle]
    fn idle(_: idle::Context) -> ! {
        loop {
            core::sync::atomic::spin_loop_hint();
        }
    }
};

The brief README describes how to build and download the example to your Teensy 4.

Limitation: RTIC directly depends on cortex-m-rt. For reasons described in this project's README, we're not using the cortex-m-rt crate. We need the teensy4-rt crate. But, we can't link two runtime crates. There's two short-term workarounds:

  1. Fork RTIC, and change the cortex-m-rt dependency to be the teensy4-rt runtime crate. They're API compatible; it's a drop-in.
  2. By using [patch] directives and a rename of the teensy4-rt crate, trick RTIC into thinking the teensy4-rt crate is the cortex-m-rt crate. They're API compatible; it's a drop-in.

I went with the second approach in this prototype. See the t4-examples/Cargo.toml file for details. There's a corresponding commit in this repo to support the prototype.

This might get us started with RTIC on the Teensy 4. For a longer-term solution, we need to reconcile the runtime crate disparity.

Let me know your thoughts on this, or if anything was unclear!

@mitchmindtree
Copy link
Contributor Author

Thanks so much for such a thorough explanation and putting together this example!

I finally had a chance to compile and run the example in your imxrt-rs fork without issues 👍

For now I think your [patch] workaround makes a lot of sense. I'll also adopt this approach in our project until we can reconcile cortex-m-rt and teensy4-rt. I'm still very new to this space and I'm not sure I'll be able to contribute to this particular custom memory layout issue for a while, but I'd be more than happy to test any progress on cortex-m-rt if it would be useful. I've subscribed to https://github.com/rust-embedded/cortex-m-rt/issues/164 to keep track of progress.

@mitchmindtree
Copy link
Contributor Author

mitchmindtree commented Jun 28, 2020

Update: I've got the teensy4-bsp crate working locally with rtic now too!

I'm planning on opening two PRs:

  1. Some refactoring to make the teensy4-rt crate's use as a temporary patch for cortex-m-rt a little easier.
  2. A follow-up PR that adds an rtic feature with a teensy4_bsp::Peripherals::steal constructor and an rtic-led.rs example.

In the meantime feel free to let me know if you'd prefer I took a different route, otherwise I'll likely open these soon.

mitchmindtree added a commit to mitchmindtree/teensy4-rs that referenced this issue Jun 28, 2020
This adds a `cortex-m-rt-patch` directory that contains a tiny crate
that re-exports `teensy4-rt` in its entirety under the crate name
`cortex-m-rt` to provide a convenient way of patching upstream crates.

The hope is to make workarounds for issues like mciantyre#62 a little easier
pending solving rust-embedded/cortex-m-rt#164 and the reconciliation of
`cortex-m-rt` and `teensy4-rt`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants