aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-06-22 15:02:09 +0000
committerGitHub <[email protected]>2022-06-22 15:02:09 +0000
commit4a6f69e2d9e1c18ff5999a6aa049c280a6b8dcc4 (patch)
tree256f269ee7798050fba119c105025a55c5b7ca7d
parente3a13a05be9f98a39205265e3dc6f3b894248b9a (diff)
parent5f87a34b6a5cb1efcb6e8059ce80c0b257704e5b (diff)
Merge #805
805: Preliminary Xtensa support r=Dirbaio a=MabezDev Based on the work in #804. I hope non-upstream target support is acceptable :). Co-authored-by: Scott Mabin <[email protected]>
-rw-r--r--embassy/src/executor/arch/xtensa.rs75
-rw-r--r--embassy/src/executor/mod.rs5
-rw-r--r--embassy/src/lib.rs1
3 files changed, 81 insertions, 0 deletions
diff --git a/embassy/src/executor/arch/xtensa.rs b/embassy/src/executor/arch/xtensa.rs
new file mode 100644
index 000000000..20bd7b8a5
--- /dev/null
+++ b/embassy/src/executor/arch/xtensa.rs
@@ -0,0 +1,75 @@
1use core::marker::PhantomData;
2use core::ptr;
3
4use atomic_polyfill::{AtomicBool, Ordering};
5
6use super::{raw, Spawner};
7
8/// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa
9///
10static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
11
12/// Xtensa Executor
13pub struct Executor {
14 inner: raw::Executor,
15 not_send: PhantomData<*mut ()>,
16}
17
18impl Executor {
19 /// Create a new Executor.
20 pub fn new() -> Self {
21 Self {
22 // use Signal_Work_Thread_Mode as substitute for local interrupt register
23 inner: raw::Executor::new(
24 |_| {
25 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
26 },
27 ptr::null_mut(),
28 ),
29 not_send: PhantomData,
30 }
31 }
32
33 /// Run the executor.
34 ///
35 /// The `init` closure is called with a [`Spawner`] that spawns tasks on
36 /// this executor. Use it to spawn the initial task(s). After `init` returns,
37 /// the executor starts running the tasks.
38 ///
39 /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`),
40 /// for example by passing it as an argument to the initial tasks.
41 ///
42 /// This function requires `&'static mut self`. This means you have to store the
43 /// Executor instance in a place where it'll live forever and grants you mutable
44 /// access. There's a few ways to do this:
45 ///
46 /// - a [Forever](crate::util::Forever) (safe)
47 /// - a `static mut` (unsafe)
48 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
49 ///
50 /// This function never returns.
51 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
52 init(self.inner.spawner());
53
54 loop {
55 unsafe {
56 self.inner.poll();
57 // we do not care about race conditions between the load and store operations, interrupts
58 // will only set this value to true.
59 // if there is work to do, loop back to polling
60 // TODO can we relax this?
61 critical_section::with(|_| {
62 if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) {
63 SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst);
64 } else {
65 // waiti sets the PS.INTLEVEL when slipping into sleep
66 // because critical sections in Xtensa are implemented via increasing
67 // PS.INTLEVEL the critical section ends here
68 // take care not add code after `waiti` if it needs to be inside the CS
69 core::arch::asm!("waiti 0"); // critical section ends here
70 }
71 });
72 }
73 }
74 }
75}
diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs
index ca8488a93..758269363 100644
--- a/embassy/src/executor/mod.rs
+++ b/embassy/src/executor/mod.rs
@@ -23,6 +23,11 @@ cfg_if::cfg_if! {
23 mod arch; 23 mod arch;
24 pub use arch::*; 24 pub use arch::*;
25 } 25 }
26 else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] {
27 #[path="arch/xtensa.rs"]
28 mod arch;
29 pub use arch::*;
30 }
26 else if #[cfg(feature="wasm")] { 31 else if #[cfg(feature="wasm")] {
27 #[path="arch/wasm.rs"] 32 #[path="arch/wasm.rs"]
28 mod arch; 33 mod arch;
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index c3b2726aa..c0a0deabf 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -1,5 +1,6 @@
1#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] 1#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
2#![cfg_attr(feature = "nightly", feature(generic_associated_types, type_alias_impl_trait))] 2#![cfg_attr(feature = "nightly", feature(generic_associated_types, type_alias_impl_trait))]
3#![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))]
3#![allow(clippy::new_without_default)] 4#![allow(clippy::new_without_default)]
4#![doc = include_str!("../../README.md")] 5#![doc = include_str!("../../README.md")]
5 6