Skip to content

Commit 4caea46

Browse files
authoredMay 7, 2020
Merge pull request #4 from ilya-epifanov/risc-v
RISC-V support
2 parents 3128731 + 231d47c commit 4caea46

24 files changed

+155
-47
lines changed
 

‎Cargo.lock

+21-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
members = [
3-
"async-cortex-m",
3+
"async-embedded",
44
"cortex-m-udf",
55
"nrf52",
66
"panic-udf",

‎async-cortex-m/src/lib.rs

-16
This file was deleted.

‎async-cortex-m/Cargo.toml ‎async-embedded/Cargo.toml

+14-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@
22
authors = ["Jorge Aparicio <jorge.aparicio@ferrous-systems.com>"]
33
edition = "2018"
44
license = "MIT OR Apache-2.0"
5-
name = "async-cortex-m"
5+
name = "async-embedded"
66
publish = false
77
version = "0.0.0-alpha.0"
88

99
[dependencies]
10-
cortex-m = "0.6.2"
11-
cortex-m-udf = { path = "../cortex-m-udf" }
1210
generic-array = "0.13.2"
1311
heapless = { git = "https://github.com/japaric/heapless", branch = "slab" }
1412
pin-utils = "0.1.0-alpha.4"
1513
typenum = "1.11.2"
14+
15+
[target.'cfg(target_arch = "arm")'.dependencies]
16+
cortex-m = "0.6.2"
17+
cortex-m-udf = { path = "../cortex-m-udf" }
18+
19+
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
20+
riscv = "0.5.6"
21+
22+
[features]
23+
default = ["riscv-wait-nop"]
24+
riscv-wait-nop = []
25+
riscv-wait-wfi-single-hart = []
26+
riscv-wait-extern = []
File renamed without changes.

‎async-cortex-m/src/executor.rs ‎async-embedded/src/executor.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use core::{
77
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
88
};
99

10-
use cortex_m::asm;
1110
use heapless::Vec;
1211
use pin_utils::pin_mut;
1312

@@ -120,7 +119,7 @@ impl Executor {
120119

121120
// try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
122121
// interrupt ran (regardless of whether it generated a wake-up or not)
123-
asm::wfe();
122+
unsafe { crate::wait_for_event() };
124123
};
125124
self.in_block_on.set(false);
126125
val

‎async-embedded/src/lib.rs

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! Proof of Concept async runtime for the Cortex-M architecture
2+
3+
#![deny(missing_docs)]
4+
#![deny(rust_2018_idioms)]
5+
#![deny(warnings)]
6+
#![no_std]
7+
8+
mod alloc;
9+
mod executor;
10+
pub mod task;
11+
pub mod unsync;
12+
13+
#[cfg(target_arch = "arm")]
14+
use cortex_m::asm;
15+
16+
17+
#[cfg(target_arch = "arm")]
18+
pub use cortex_m_udf::udf as abort;
19+
20+
#[cfg(target_arch = "arm")]
21+
#[inline]
22+
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
23+
/// This particular implementation does nothing, since `wait_for_interrupt` never sleeps
24+
pub(crate) unsafe fn signal_event_ready() {
25+
asm::sev();
26+
}
27+
28+
#[cfg(target_arch = "arm")]
29+
#[inline]
30+
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
31+
/// This particular implementation does nothing
32+
pub(crate) unsafe fn wait_for_event() {
33+
asm::wfe();
34+
}
35+
36+
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
37+
/// This keeps dropping into the debugger and never returns
38+
pub fn abort() -> ! {
39+
loop {
40+
unsafe { riscv::asm::ebreak() }
41+
}
42+
}
43+
44+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-nop"))]
45+
#[inline]
46+
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
47+
/// This particular implementation does nothing, since `wait_for_interrupt` never sleeps
48+
pub(crate) unsafe fn signal_event_ready() {}
49+
50+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-nop"))]
51+
#[inline]
52+
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
53+
/// This particular implementation does nothing
54+
pub(crate) unsafe fn wait_for_event() {}
55+
56+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-extern"))]
57+
extern "C" {
58+
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
59+
/// User is expected to provide an actual implementation, like the one shown below.
60+
///
61+
/// #[no_mangle]
62+
/// pub extern "C" fn signal_event_ready() {
63+
/// unimplemented!();
64+
/// }
65+
pub(crate) fn signal_event_ready();
66+
67+
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
68+
/// User is expected to provide an actual implementation, like the one shown below.
69+
///
70+
/// #[no_mangle]
71+
/// pub extern "C" fn wait_for_event() {
72+
/// unimplemented!();
73+
/// }
74+
pub(crate) fn wait_for_event();
75+
}
76+
77+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
78+
static mut TASK_READY: bool = false;
79+
80+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
81+
#[inline]
82+
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
83+
/// This particular implementation prevents `wait_for_interrupt` from sleeping by setting
84+
/// a global mutable flag
85+
pub(crate) unsafe fn signal_event_ready() {
86+
TASK_READY = true;
87+
}
88+
89+
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
90+
#[inline]
91+
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
92+
/// This particular implementation decides whether to sleep or not by checking
93+
/// a global mutable flag that's set by `signal_task_ready`
94+
pub(crate) unsafe fn wait_for_event() {
95+
if !TASK_READY {
96+
riscv::asm::wfi();
97+
}
98+
TASK_READY = false;
99+
}
100+
101+
/// Maximum number of tasks (TODO this could be user configurable)
102+
type NTASKS = typenum::consts::U8;

‎async-cortex-m/src/task.rs ‎async-embedded/src/task.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use core::{
66
task::{Context, Poll},
77
};
88

9-
use cortex_m::asm;
10-
119
use crate::executor;
1210

1311
/// Drives the future `f` to completion
@@ -43,7 +41,7 @@ pub async fn r#yield() {
4341
self.yielded = true;
4442
// wake ourselves
4543
cx.waker().wake_by_ref();
46-
asm::sev();
44+
unsafe { crate::signal_event_ready(); }
4745
Poll::Pending
4846
}
4947
}
File renamed without changes.

‎async-cortex-m/src/unsync/channel.rs ‎async-embedded/src/unsync/channel.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use core::{
1212
task::{Context, Poll},
1313
};
1414

15-
use cortex_m::asm;
1615
use generic_array::{typenum::Unsigned, GenericArray};
1716

1817
use super::waker_set::WakerSet;
@@ -137,7 +136,7 @@ impl<T> Channel<T> {
137136
self.read.set(read.wrapping_add(1));
138137
// notify a sender
139138
self.send_wakers.notify_one();
140-
asm::sev();
139+
crate::signal_event_ready();
141140
Some(val)
142141
} else {
143142
// empty
@@ -162,7 +161,7 @@ impl<T> Channel<T> {
162161
self.write.set(write.wrapping_add(1));
163162
// notify a receiver
164163
self.recv_wakers.notify_one();
165-
asm::sev();
164+
crate::signal_event_ready();
166165
Ok(())
167166
} else {
168167
// full

‎async-cortex-m/src/unsync/mutex.rs ‎async-embedded/src/unsync/mutex.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use core::{
88
task::{Context, Poll},
99
};
1010

11-
use cortex_m::asm;
12-
1311
use super::waker_set::WakerSet;
1412

1513
/// A mutual exclusion primitive for protecting shared data
@@ -94,7 +92,7 @@ impl<T> Drop for MutexGuard<'_, T> {
9492
fn drop(&mut self) {
9593
self.0.locked.set(false);
9694
self.0.wakers.notify_any();
97-
asm::sev();
95+
unsafe { crate::signal_event_ready(); }
9896
}
9997
}
10098

File renamed without changes.

‎nrf52/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ panic-semihosting = "0.5.3"
1515
panic-udf = { path = "../panic-udf" }
1616

1717
[dependencies]
18-
async-cortex-m = { path = "../async-cortex-m" }
18+
async-embedded = { path = "../async-embedded" }
1919
cortex-m = "0.6.2"
2020
cortex-m-rt = "0.6.12"
2121
pac = { package = "nrf52840-pac", version = "0.9.0", features = ["rt"] }

‎nrf52/examples/1-yield.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#![no_main]
1616
#![no_std]
1717

18-
use async_cortex_m::task;
18+
use async_embedded::task;
1919
use cortex_m::asm;
2020
use cortex_m_rt::entry;
2121
use cortex_m_semihosting::hprintln;

‎nrf52/examples/2-share.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
use core::cell::{Cell, RefCell};
1919

20-
use async_cortex_m::task;
20+
use async_embedded::task;
2121
use cortex_m::asm;
2222
use cortex_m_rt::entry;
2323
use cortex_m_semihosting::hprintln;

‎nrf52/examples/3-mutex.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#![no_main]
2929
#![no_std]
3030

31-
use async_cortex_m::{task, unsync::Mutex};
31+
use async_embedded::{task, unsync::Mutex};
3232
use cortex_m::asm;
3333
use cortex_m_rt::entry;
3434
use cortex_m_semihosting::hprintln;

‎nrf52/examples/4-channel.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#![no_main]
1717
#![no_std]
1818

19-
use async_cortex_m::{task, unsync::Channel};
19+
use async_embedded::{task, unsync::Channel};
2020
use cortex_m::asm;
2121
use cortex_m_rt::entry;
2222
use cortex_m_semihosting::hprintln;

‎nrf52/examples/5-heartbeat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
use core::time::Duration;
1919

20-
use async_cortex_m::task;
20+
use async_embedded::task;
2121
use cortex_m_rt::entry;
2222
use nrf52::{led::Red, timer::Timer};
2323
use panic_udf as _; // panic handler

‎nrf52/examples/6-hello.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use core::time::Duration;
1212

13-
use async_cortex_m::task;
13+
use async_embedded::task;
1414
use cortex_m_rt::entry;
1515
use nrf52::{led::Red, serial, timer::Timer};
1616
use panic_udf as _; // panic handler

‎nrf52/examples/7-echo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use core::time::Duration;
1212

13-
use async_cortex_m::task;
13+
use async_embedded::task;
1414
use cortex_m_rt::entry;
1515
use nrf52::{led::Red, serial, timer::Timer};
1616
use panic_udf as _; // panic handler

‎nrf52/examples/8-sensor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use core::{cell::Cell, fmt::Write as _, time::Duration};
99

10-
use async_cortex_m::{task, unsync::Mutex};
10+
use async_embedded::{task, unsync::Mutex};
1111
use cortex_m_rt::entry;
1212
use heapless::{consts, String};
1313
use nrf52::{led::Red, scd30::Scd30, serial, timer::Timer, twim::Twim};

‎nrf52/examples/9-clock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use core::{
3131
time::Duration,
3232
};
3333

34-
use async_cortex_m::{task, unsync::Mutex};
34+
use async_embedded::{task, unsync::Mutex};
3535
use chrono::{Datelike as _, NaiveDate, NaiveTime};
3636
use cortex_m_rt::entry;
3737
use heapless::{consts, String, Vec};

‎nrf52/src/ds3231.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
// Reference: DS3231 datasheet (19-5170; Rev 10; 3/15)
44

5-
use async_cortex_m::unsync::Mutex;
5+
use async_embedded::unsync::Mutex;
66
use chrono::{Datelike as _, NaiveDate, NaiveDateTime, NaiveTime, Timelike as _};
77

88
use crate::twim::{self, Twim};

0 commit comments

Comments
 (0)
Failed to load comments.