-
Notifications
You must be signed in to change notification settings - Fork 767
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
804: Preliminary RISCV support r=Dirbaio a=MabezDev - ~~Moves the default Interrupt implementation into a cortex_m specific module~~ - Adds a RISCV32 executor based on [osobiehl](https://github.com/osobiehl)'s work in [esp32c3 mess work](https://github.com/osobiehl/riscv-embassy-mess-work) (FYI esp implementation of embassy traits etc, is being developed [here](https://github.com/esp-rs/esp-hal/tree/feature/embassy)) [bonus ascii cinema](https://asciinema.org/a/500857 ) Co-authored-by: Scott Mabin <scott@mabez.dev>
- Loading branch information
Showing
4 changed files
with
83 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use core::marker::PhantomData; | ||
use core::ptr; | ||
|
||
use atomic_polyfill::{AtomicBool, Ordering}; | ||
|
||
use super::{raw, Spawner}; | ||
|
||
/// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV | ||
/// | ||
static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); | ||
|
||
/// RISCV32 Executor | ||
pub struct Executor { | ||
inner: raw::Executor, | ||
not_send: PhantomData<*mut ()>, | ||
} | ||
|
||
impl Executor { | ||
/// Create a new Executor. | ||
pub fn new() -> Self { | ||
Self { | ||
// use Signal_Work_Thread_Mode as substitute for local interrupt register | ||
inner: raw::Executor::new( | ||
|_| { | ||
SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); | ||
}, | ||
ptr::null_mut(), | ||
), | ||
not_send: PhantomData, | ||
} | ||
} | ||
|
||
/// Run the executor. | ||
/// | ||
/// The `init` closure is called with a [`Spawner`] that spawns tasks on | ||
/// this executor. Use it to spawn the initial task(s). After `init` returns, | ||
/// the executor starts running the tasks. | ||
/// | ||
/// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
/// for example by passing it as an argument to the initial tasks. | ||
/// | ||
/// This function requires `&'static mut self`. This means you have to store the | ||
/// Executor instance in a place where it'll live forever and grants you mutable | ||
/// access. There's a few ways to do this: | ||
/// | ||
/// - a [Forever](crate::util::Forever) (safe) | ||
/// - a `static mut` (unsafe) | ||
/// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
/// | ||
/// This function never returns. | ||
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
init(self.inner.spawner()); | ||
|
||
loop { | ||
unsafe { | ||
self.inner.poll(); | ||
// we do not care about race conditions between the load and store operations, interrupts | ||
//will only set this value to true. | ||
critical_section::with(|_| { | ||
// if there is work to do, loop back to polling | ||
// TODO can we relax this? | ||
if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) { | ||
SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst); | ||
} | ||
// if not, wait for interrupt | ||
else { | ||
core::arch::asm!("wfi"); | ||
} | ||
}); | ||
// if an interrupt occurred while waiting, it will be serviced here | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters