Skip to content
This repository was archived by the owner on May 6, 2020. It is now read-only.

RISC-V support #3

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
members = [
"async-cortex-m",
"async-embedded",
"cortex-m-udf",
"nrf52",
"panic-udf",
Expand Down
16 changes: 0 additions & 16 deletions async-cortex-m/src/lib.rs

This file was deleted.

17 changes: 14 additions & 3 deletions async-cortex-m/Cargo.toml → async-embedded/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@
authors = ["Jorge Aparicio <[email protected]>"]
edition = "2018"
license = "MIT OR Apache-2.0"
name = "async-cortex-m"
name = "async-embedded"
publish = false
version = "0.0.0-alpha.0"

[dependencies]
cortex-m = "0.6.2"
cortex-m-udf = { path = "../cortex-m-udf" }
generic-array = "0.13.2"
heapless = { git = "https://github.com/japaric/heapless", branch = "slab" }
pin-utils = "0.1.0-alpha.4"
typenum = "1.11.2"

[target.'cfg(target_arch = "arm")'.dependencies]
cortex-m = "0.6.2"
cortex-m-udf = { path = "../cortex-m-udf" }

[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
riscv = "0.5.6"

[features]
default = ["riscv-wait-nop"]
riscv-wait-nop = []
riscv-wait-wfi-single-hart = []
riscv-wait-extern = []
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use core::{
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};

use cortex_m::asm;
use heapless::Vec;
use pin_utils::pin_mut;

Expand Down Expand Up @@ -120,7 +119,7 @@ impl Executor {

// try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
// interrupt ran (regardless of whether it generated a wake-up or not)
asm::wfe();
unsafe { crate::wait_for_event() };
};
self.in_block_on.set(false);
val
Expand Down
102 changes: 102 additions & 0 deletions async-embedded/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//! Proof of Concept async runtime for the Cortex-M architecture

#![deny(missing_docs)]
#![deny(rust_2018_idioms)]
#![deny(warnings)]
#![no_std]

mod alloc;
mod executor;
pub mod task;
pub mod unsync;

#[cfg(target_arch = "arm")]
use cortex_m::asm;


#[cfg(target_arch = "arm")]
pub use cortex_m_udf::udf as abort;

#[cfg(target_arch = "arm")]
#[inline]
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
/// This particular implementation does nothing, since `wait_for_interrupt` never sleeps
pub(crate) unsafe fn signal_event_ready() {
asm::sev();
}

#[cfg(target_arch = "arm")]
#[inline]
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
/// This particular implementation does nothing
pub(crate) unsafe fn wait_for_event() {
asm::wfe();
}

#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
/// This keeps dropping into the debugger and never returns
pub fn abort() -> ! {
loop {
unsafe { riscv::asm::ebreak() }
}
}

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-nop"))]
#[inline]
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
/// This particular implementation does nothing, since `wait_for_interrupt` never sleeps
pub(crate) unsafe fn signal_event_ready() {}

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-nop"))]
#[inline]
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
/// This particular implementation does nothing
pub(crate) unsafe fn wait_for_event() {}

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-extern"))]
extern "C" {
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
/// User is expected to provide an actual implementation, like the one shown below.
///
/// #[no_mangle]
/// pub extern "C" fn signal_event_ready() {
/// unimplemented!();
/// }
pub(crate) fn signal_event_ready();

/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
/// User is expected to provide an actual implementation, like the one shown below.
///
/// #[no_mangle]
/// pub extern "C" fn wait_for_event() {
/// unimplemented!();
/// }
pub(crate) fn wait_for_event();
}

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
static mut TASK_READY: bool = false;

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
#[inline]
/// Prevent next `wait_for_interrupt` from sleeping, wake up other harts if needed.
/// This particular implementation prevents `wait_for_interrupt` from sleeping by setting
/// a global mutable flag
pub(crate) unsafe fn signal_event_ready() {
TASK_READY = true;
}

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), feature = "riscv-wait-wfi-single-hart"))]
#[inline]
/// Wait for an interrupt or until notified by other hart via `signal_task_ready`
/// This particular implementation decides whether to sleep or not by checking
/// a global mutable flag that's set by `signal_task_ready`
pub(crate) unsafe fn wait_for_event() {
if !TASK_READY {
riscv::asm::wfi();
TASK_READY = false;
}
}

/// Maximum number of tasks (TODO this could be user configurable)
type NTASKS = typenum::consts::U8;
4 changes: 1 addition & 3 deletions async-cortex-m/src/task.rs → async-embedded/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;

use crate::executor;

/// Drives the future `f` to completion
Expand Down Expand Up @@ -43,7 +41,7 @@ pub async fn r#yield() {
self.yielded = true;
// wake ourselves
cx.waker().wake_by_ref();
asm::sev();
unsafe { crate::signal_event_ready(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is not required anymore after my fix: https://github.com/ferrous-systems/async-on-embedded/pull/2/files#diff-22ab3da1c5b4e44f95ba9b8000eda448R116
However, sev is required when task is woken from an interrupt context.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, your fix included the sev call so I kept it

Poll::Pending
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;
use generic_array::{typenum::Unsigned, GenericArray};

use super::waker_set::WakerSet;
Expand Down Expand Up @@ -137,7 +136,7 @@ impl<T> Channel<T> {
self.read.set(read.wrapping_add(1));
// notify a sender
self.send_wakers.notify_one();
asm::sev();
crate::signal_event_ready();
Some(val)
} else {
// empty
Expand All @@ -162,7 +161,7 @@ impl<T> Channel<T> {
self.write.set(write.wrapping_add(1));
// notify a receiver
self.recv_wakers.notify_one();
asm::sev();
crate::signal_event_ready();
Ok(())
} else {
// full
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;

use super::waker_set::WakerSet;

/// A mutual exclusion primitive for protecting shared data
Expand Down Expand Up @@ -94,7 +92,7 @@ impl<T> Drop for MutexGuard<'_, T> {
fn drop(&mut self) {
self.0.locked.set(false);
self.0.wakers.notify_any();
asm::wfe();
unsafe { crate::wait_for_event(); }
}
}

Expand Down
2 changes: 1 addition & 1 deletion nrf52/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ panic-semihosting = "0.5.3"
panic-udf = { path = "../panic-udf" }

[dependencies]
async-cortex-m = { path = "../async-cortex-m" }
async-embedded = { path = "../async-embedded" }
cortex-m = "0.6.2"
cortex-m-rt = "0.6.12"
pac = { package = "nrf52840-pac", version = "0.9.0", features = ["rt"] }
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/1-yield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#![no_main]
#![no_std]

use async_cortex_m::task;
use async_embedded::task;
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/2-share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

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

use async_cortex_m::task;
use async_embedded::task;
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/3-mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#![no_main]
#![no_std]

use async_cortex_m::{task, unsync::Mutex};
use async_embedded::{task, unsync::Mutex};
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/4-channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#![no_main]
#![no_std]

use async_cortex_m::{task, unsync::Channel};
use async_embedded::{task, unsync::Channel};
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/5-heartbeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

use core::time::Duration;

use async_cortex_m::task;
use async_embedded::task;
use cortex_m_rt::entry;
use nrf52::{led::Red, timer::Timer};
use panic_udf as _; // panic handler
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/6-hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use core::time::Duration;

use async_cortex_m::task;
use async_embedded::task;
use cortex_m_rt::entry;
use nrf52::{led::Red, serial, timer::Timer};
use panic_udf as _; // panic handler
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/7-echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use core::time::Duration;

use async_cortex_m::task;
use async_embedded::task;
use cortex_m_rt::entry;
use nrf52::{led::Red, serial, timer::Timer};
use panic_udf as _; // panic handler
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/8-sensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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

use async_cortex_m::{task, unsync::Mutex};
use async_embedded::{task, unsync::Mutex};
use cortex_m_rt::entry;
use heapless::{consts, String};
use nrf52::{led::Red, scd30::Scd30, serial, timer::Timer, twim::Twim};
Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/9-clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use core::{
time::Duration,
};

use async_cortex_m::{task, unsync::Mutex};
use async_embedded::{task, unsync::Mutex};
use chrono::{Datelike as _, NaiveDate, NaiveTime};
use cortex_m_rt::entry;
use heapless::{consts, String, Vec};
Expand Down
2 changes: 1 addition & 1 deletion nrf52/src/ds3231.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Reference: DS3231 datasheet (19-5170; Rev 10; 3/15)

use async_cortex_m::unsync::Mutex;
use async_embedded::unsync::Mutex;
use chrono::{Datelike as _, NaiveDate, NaiveDateTime, NaiveTime, Timelike as _};

use crate::twim::{self, Twim};
Expand Down
Loading