2023-04-03 01:18:27 +02:00
|
|
|
#[cfg(feature = "executor-interrupt")]
|
|
|
|
compile_error!("`executor-interrupt` is not supported with `arch-riscv32`.");
|
2022-06-08 15:54:18 +02:00
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
#[cfg(feature = "thread-context")]
|
|
|
|
compile_error!("`thread-context` is not supported with `arch-riscv32`.");
|
|
|
|
|
2023-04-03 01:18:27 +02:00
|
|
|
#[cfg(feature = "executor-thread")]
|
|
|
|
pub use thread::*;
|
|
|
|
#[cfg(feature = "executor-thread")]
|
|
|
|
mod thread {
|
|
|
|
use core::marker::PhantomData;
|
|
|
|
use core::sync::atomic::{AtomicBool, Ordering};
|
2022-06-08 15:54:18 +02:00
|
|
|
|
2023-04-11 14:59:38 +02:00
|
|
|
#[cfg(feature = "nightly")]
|
|
|
|
pub use embassy_macros::main_riscv as main;
|
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
use crate::raw::OpaqueThreadContext;
|
|
|
|
use crate::thread::ThreadContext;
|
2022-06-08 15:54:18 +02:00
|
|
|
|
2023-04-03 01:18:27 +02:00
|
|
|
/// 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);
|
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
#[export_name = "__thread_mode_pender"]
|
|
|
|
fn __thread_mode_pender(_core_id: OpaqueThreadContext) {
|
|
|
|
SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
|
2023-04-03 01:18:27 +02:00
|
|
|
}
|
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
/// TODO
|
|
|
|
// Name pending
|
|
|
|
#[derive(Default)] // Default enables Executor::new
|
|
|
|
pub struct RiscVThreadContext {
|
|
|
|
_not_send: PhantomData<*mut ()>,
|
|
|
|
}
|
2023-04-03 01:18:27 +02:00
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
impl ThreadContext for RiscVThreadContext {
|
|
|
|
fn context(&self) -> OpaqueThreadContext {
|
|
|
|
OpaqueThreadContext(())
|
|
|
|
}
|
2022-06-08 15:54:18 +02:00
|
|
|
|
2023-08-12 16:00:18 +02:00
|
|
|
fn wait(&mut self) {
|
|
|
|
// 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);
|
2023-04-03 01:18:27 +02:00
|
|
|
}
|
2023-08-12 16:00:18 +02:00
|
|
|
// if not, wait for interrupt
|
|
|
|
else {
|
|
|
|
unsafe {
|
|
|
|
core::arch::asm!("wfi");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// if an interrupt occurred while waiting, it will be serviced here
|
2022-06-08 15:54:18 +02:00
|
|
|
}
|
|
|
|
}
|
2023-08-12 16:00:18 +02:00
|
|
|
|
|
|
|
/// TODO
|
|
|
|
// Type alias for backwards compatibility
|
|
|
|
pub type Executor = crate::thread::ThreadModeExecutor<RiscVThreadContext>;
|
2022-06-08 15:54:18 +02:00
|
|
|
}
|