embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.34k stars 738 forks source link

Compatibility with ATMEGA architecture #2453

Open chuckberrypi opened 8 months ago

chuckberrypi commented 8 months ago

The docs say that this project maintains hal crates for various architectures (RP2040, STM, NRF), but that "you can still use HALs from other projects with Embassy." Does this mean that I can use embassy with an ATMEGA32u4 microcontroller I have, or can I only use it with the architectures listed on the embassy-executor documentation? If I can use it with the ATMEGA32u4 chip, any tips on getting rid of the error I am getting:

| #[embassy_executor::main]
|                     ^^^^ could not find \`main\` in \`embassy_executor\`
enbyted commented 8 months ago

Embassy-executor has some platform-dependent code required to support it, kind of like any embedded operating system.

Arguably it should not be very difficult to create a thread-mode (i.e. endless loop in main function) executor for AVR.

Regarding the error you're getting - the main macro is only defined if you select a valid architecture --> that's because it needs to know which platform-specific executor to use.

I'm not an embassy expert (just started using it a couple weeks ago on a toy project actually), but to me it looks like to add basic AVR support you'd need at least:

The simplest executor you can make is one that will do:

pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
    init(self.inner.spawner());
    loop { unsafe {self.iner.pool(); } }
}

For testing you can just start with using embassy_executor::raw::Executor (docs)

I did not even try to compile below code (never tried rust on AVR), but you could try something along those lines:

use embassy_executor::raw;
use static_cell::StaticCell;

static EXECUTOR: raw::Executor = StaticCell::new();

#[export_name = "__pender"]
/// Required by raw::Executor, but can do nothing
fn pender(_context: *mut ()) {}

pub fn main()
{
  let executor = EXECUTOR.init(raw::Executor::new(ptr::null_mut()));
  let _spawner = executor.spawner();

  loop { 
    unsafe { executor.pool(); } 
  }
}
jamesmunns commented 8 months ago

Note that there is a PR open to add some support for AVR: https://github.com/embassy-rs/embassy/pull/2273