Make flash syscall interface async
This commit is contained in:
committed by
Julien Cretin
parent
3d4b652e12
commit
ad0605c2fa
@@ -182,10 +182,10 @@ fn main() {
|
|||||||
|
|
||||||
// Results on nrf52840dk_opensk:
|
// Results on nrf52840dk_opensk:
|
||||||
// Pages Overwrite Length Boot Compaction Insert Remove
|
// Pages Overwrite Length Boot Compaction Insert Remove
|
||||||
// 3 no 50 words 4.7 ms 135.5 ms 6.9 ms 2.7 ms
|
// 3 no 50 words 5.3 ms 141.9 ms 8.0 ms 3.3 ms
|
||||||
// 20 no 50 words 16.7 ms 141.7 ms 18.6 ms 8.5 ms
|
// 20 no 50 words 18.7 ms 148.6 ms 21.0 ms 9.8 ms
|
||||||
// 3 yes 1 words 33.7 ms 97.7 ms 9.5 ms 4.8 ms
|
// 3 yes 1 words 37.8 ms 100.2 ms 11.3 ms 5.5 ms
|
||||||
// 20 yes 1 words 338.3 ms 97.7 ms 9.7 ms 4.8 ms
|
// 20 yes 1 words 336.5 ms 100.3 ms 11.5 ms 5.6 ms
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align(x: &str, n: usize) {
|
fn align(x: &str, n: usize) {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ index e0e292a7e..b485a0997 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
index 8e4238018..ebee8704b 100644
|
index 8e4238018..c80732f8d 100644
|
||||||
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
@@ -114,6 +114,11 @@ const NUM_PROCS: usize = 8;
|
@@ -114,6 +114,11 @@ const NUM_PROCS: usize = 8;
|
||||||
@@ -155,7 +155,7 @@ index 8e4238018..ebee8704b 100644
|
|||||||
|
|
||||||
let gpio = components::gpio::GpioComponent::new(
|
let gpio = components::gpio::GpioComponent::new(
|
||||||
board_kernel,
|
board_kernel,
|
||||||
@@ -334,6 +363,14 @@ pub unsafe fn reset_handler() {
|
@@ -334,6 +363,20 @@ pub unsafe fn reset_handler() {
|
||||||
nrf52840::acomp::Comparator
|
nrf52840::acomp::Comparator
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -164,13 +164,19 @@ index 8e4238018..ebee8704b 100644
|
|||||||
+ nrf52840::nvmc::SyscallDriver::new(
|
+ nrf52840::nvmc::SyscallDriver::new(
|
||||||
+ &nrf52840::nvmc::NVMC,
|
+ &nrf52840::nvmc::NVMC,
|
||||||
+ board_kernel.create_grant(&memory_allocation_capability),
|
+ board_kernel.create_grant(&memory_allocation_capability),
|
||||||
|
+ dynamic_deferred_caller,
|
||||||
+ )
|
+ )
|
||||||
+ );
|
+ );
|
||||||
|
+ nvmc.set_deferred_handle(
|
||||||
|
+ dynamic_deferred_caller
|
||||||
|
+ .register(nvmc)
|
||||||
|
+ .expect("no deferred call slot available for nvmc"),
|
||||||
|
+ );
|
||||||
+
|
+
|
||||||
nrf52_components::NrfClockComponent::new().finalize(());
|
nrf52_components::NrfClockComponent::new().finalize(());
|
||||||
|
|
||||||
let platform = Platform {
|
let platform = Platform {
|
||||||
@@ -345,6 +382,7 @@ pub unsafe fn reset_handler() {
|
@@ -345,6 +388,7 @@ pub unsafe fn reset_handler() {
|
||||||
rng,
|
rng,
|
||||||
alarm,
|
alarm,
|
||||||
analog_comparator,
|
analog_comparator,
|
||||||
@@ -179,10 +185,10 @@ index 8e4238018..ebee8704b 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
diff --git a/chips/nrf52/src/nvmc.rs b/chips/nrf52/src/nvmc.rs
|
diff --git a/chips/nrf52/src/nvmc.rs b/chips/nrf52/src/nvmc.rs
|
||||||
index b70162cae..9dcb82b07 100644
|
index b70162cae..9934f3a31 100644
|
||||||
--- a/chips/nrf52/src/nvmc.rs
|
--- a/chips/nrf52/src/nvmc.rs
|
||||||
+++ b/chips/nrf52/src/nvmc.rs
|
+++ b/chips/nrf52/src/nvmc.rs
|
||||||
@@ -3,6 +3,7 @@
|
@@ -3,15 +3,19 @@
|
||||||
//! Used in order read and write to internal flash.
|
//! Used in order read and write to internal flash.
|
||||||
|
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
@@ -190,7 +196,11 @@ index b70162cae..9dcb82b07 100644
|
|||||||
use core::ops::{Index, IndexMut};
|
use core::ops::{Index, IndexMut};
|
||||||
use kernel::common::cells::OptionalCell;
|
use kernel::common::cells::OptionalCell;
|
||||||
use kernel::common::cells::TakeCell;
|
use kernel::common::cells::TakeCell;
|
||||||
@@ -11,7 +12,7 @@ use kernel::common::deferred_call::DeferredCall;
|
use kernel::common::cells::VolatileCell;
|
||||||
|
use kernel::common::deferred_call::DeferredCall;
|
||||||
|
+use kernel::common::dynamic_deferred_call::{
|
||||||
|
+ DeferredCallHandle, DynamicDeferredCall, DynamicDeferredCallClient,
|
||||||
|
+};
|
||||||
use kernel::common::registers::{register_bitfields, ReadOnly, ReadWrite};
|
use kernel::common::registers::{register_bitfields, ReadOnly, ReadWrite};
|
||||||
use kernel::common::StaticRef;
|
use kernel::common::StaticRef;
|
||||||
use kernel::hil;
|
use kernel::hil;
|
||||||
@@ -199,7 +209,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
|
|
||||||
use crate::deferred_call_tasks::DeferredCallTask;
|
use crate::deferred_call_tasks::DeferredCallTask;
|
||||||
|
|
||||||
@@ -141,7 +142,13 @@ register_bitfields! [u32,
|
@@ -141,7 +145,13 @@ register_bitfields! [u32,
|
||||||
static DEFERRED_CALL: DeferredCall<DeferredCallTask> =
|
static DEFERRED_CALL: DeferredCall<DeferredCallTask> =
|
||||||
unsafe { DeferredCall::new(DeferredCallTask::Nvmc) };
|
unsafe { DeferredCall::new(DeferredCallTask::Nvmc) };
|
||||||
|
|
||||||
@@ -213,7 +223,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
|
|
||||||
/// This is a wrapper around a u8 array that is sized to a single page for the
|
/// This is a wrapper around a u8 array that is sized to a single page for the
|
||||||
/// nrf. Users of this module must pass an object of this type to use the
|
/// nrf. Users of this module must pass an object of this type to use the
|
||||||
@@ -219,6 +226,11 @@ impl Nvmc {
|
@@ -219,6 +229,11 @@ impl Nvmc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +235,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
/// Configure the NVMC to allow writes to flash.
|
/// Configure the NVMC to allow writes to flash.
|
||||||
pub fn configure_writeable(&self) {
|
pub fn configure_writeable(&self) {
|
||||||
let regs = &*self.registers;
|
let regs = &*self.registers;
|
||||||
@@ -234,7 +246,7 @@ impl Nvmc {
|
@@ -234,7 +249,7 @@ impl Nvmc {
|
||||||
let regs = &*self.registers;
|
let regs = &*self.registers;
|
||||||
regs.config.write(Configuration::WEN::Een);
|
regs.config.write(Configuration::WEN::Een);
|
||||||
while !self.is_ready() {}
|
while !self.is_ready() {}
|
||||||
@@ -234,7 +244,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
while !self.is_ready() {}
|
while !self.is_ready() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +338,7 @@ impl Nvmc {
|
@@ -326,7 +341,7 @@ impl Nvmc {
|
||||||
// Put the NVMC in write mode.
|
// Put the NVMC in write mode.
|
||||||
regs.config.write(Configuration::WEN::Wen);
|
regs.config.write(Configuration::WEN::Wen);
|
||||||
|
|
||||||
@@ -243,7 +253,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
let word: u32 = (data[i + 0] as u32) << 0
|
let word: u32 = (data[i + 0] as u32) << 0
|
||||||
| (data[i + 1] as u32) << 8
|
| (data[i + 1] as u32) << 8
|
||||||
| (data[i + 2] as u32) << 16
|
| (data[i + 2] as u32) << 16
|
||||||
@@ -394,3 +406,180 @@ impl hil::flash::Flash for Nvmc {
|
@@ -394,3 +409,236 @@ impl hil::flash::Flash for Nvmc {
|
||||||
self.erase_page(page_number)
|
self.erase_page(page_number)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,6 +279,7 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+///
|
+///
|
||||||
+/// # Syscalls
|
+/// # Syscalls
|
||||||
+///
|
+///
|
||||||
|
+/// - SUBSCRIBE(0, done): The callback for COMMAND(2) and COMMAND(3).
|
||||||
+/// - COMMAND(0): Check the driver.
|
+/// - COMMAND(0): Check the driver.
|
||||||
+/// - COMMAND(1, 0): Get the word size (always 4).
|
+/// - COMMAND(1, 0): Get the word size (always 4).
|
||||||
+/// - COMMAND(1, 1): Get the page size (always 4096).
|
+/// - COMMAND(1, 1): Get the page size (always 4096).
|
||||||
@@ -287,28 +298,45 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+pub struct SyscallDriver {
|
+pub struct SyscallDriver {
|
||||||
+ nvmc: &'static Nvmc,
|
+ nvmc: &'static Nvmc,
|
||||||
+ apps: Grant<App>,
|
+ apps: Grant<App>,
|
||||||
|
+ waiting: OptionalCell<AppId>,
|
||||||
|
+ deferred_caller: &'static DynamicDeferredCall,
|
||||||
|
+ deferred_handle: OptionalCell<DeferredCallHandle>,
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+pub const DRIVER_NUM: usize = 0x50003;
|
+pub const DRIVER_NUM: usize = 0x50003;
|
||||||
+
|
+
|
||||||
+#[derive(Default)]
|
+#[derive(Default)]
|
||||||
+pub struct App {
|
+pub struct App {
|
||||||
|
+ /// The callback for COMMAND(2) and COMMAND(3).
|
||||||
|
+ callback: Option<Callback>,
|
||||||
+ /// The allow slice for COMMAND(2).
|
+ /// The allow slice for COMMAND(2).
|
||||||
+ slice: Option<AppSlice<Shared, u8>>,
|
+ slice: Option<AppSlice<Shared, u8>>,
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+impl SyscallDriver {
|
|
||||||
+ pub fn new(nvmc: &'static Nvmc, apps: Grant<App>) -> SyscallDriver {
|
|
||||||
+ SyscallDriver { nvmc, apps }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+fn is_write_needed(old: u32, new: u32) -> bool {
|
+fn is_write_needed(old: u32, new: u32) -> bool {
|
||||||
+ // No need to write if it would not modify the current value.
|
+ // No need to write if it would not modify the current value.
|
||||||
+ old & new != old
|
+ old & new != old
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+impl SyscallDriver {
|
+impl SyscallDriver {
|
||||||
|
+ pub fn new(
|
||||||
|
+ nvmc: &'static Nvmc,
|
||||||
|
+ apps: Grant<App>,
|
||||||
|
+ deferred_caller: &'static DynamicDeferredCall,
|
||||||
|
+ ) -> SyscallDriver {
|
||||||
|
+ SyscallDriver {
|
||||||
|
+ nvmc,
|
||||||
|
+ apps,
|
||||||
|
+ waiting: OptionalCell::empty(),
|
||||||
|
+ deferred_caller,
|
||||||
|
+ deferred_handle: OptionalCell::empty(),
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pub fn set_deferred_handle(&self, handle: DeferredCallHandle) {
|
||||||
|
+ self.deferred_handle.replace(handle);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ /// Writes a word-aligned slice at a word-aligned address.
|
+ /// Writes a word-aligned slice at a word-aligned address.
|
||||||
+ ///
|
+ ///
|
||||||
+ /// Words are written only if necessary, i.e. if writing the new value would change the current
|
+ /// Words are written only if necessary, i.e. if writing the new value would change the current
|
||||||
@@ -342,6 +370,8 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+ }
|
+ }
|
||||||
+ while !self.nvmc.is_ready() {}
|
+ while !self.nvmc.is_ready() {}
|
||||||
+ self.nvmc.configure_readonly();
|
+ self.nvmc.configure_readonly();
|
||||||
|
+ self.deferred_handle
|
||||||
|
+ .map(|handle| self.deferred_caller.set(*handle));
|
||||||
+ ReturnCode::SUCCESS
|
+ ReturnCode::SUCCESS
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@@ -358,13 +388,41 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+ }
|
+ }
|
||||||
+ self.nvmc.erase_page_helper(ptr / PAGE_SIZE);
|
+ self.nvmc.erase_page_helper(ptr / PAGE_SIZE);
|
||||||
+ self.nvmc.configure_readonly();
|
+ self.nvmc.configure_readonly();
|
||||||
|
+ self.deferred_handle
|
||||||
|
+ .map(|handle| self.deferred_caller.set(*handle));
|
||||||
+ ReturnCode::SUCCESS
|
+ ReturnCode::SUCCESS
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+impl DynamicDeferredCallClient for SyscallDriver {
|
||||||
|
+ fn call(&self, _handle: DeferredCallHandle) {
|
||||||
|
+ self.waiting.take().map(|appid| {
|
||||||
|
+ self.apps.enter(appid, |app, _| {
|
||||||
|
+ app.callback.map(|mut cb| {
|
||||||
|
+ cb.schedule(0, 0, 0);
|
||||||
|
+ });
|
||||||
|
+ })
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
+impl Driver for SyscallDriver {
|
+impl Driver for SyscallDriver {
|
||||||
+ fn subscribe(&self, _: usize, _: Option<Callback>, _: AppId) -> ReturnCode {
|
+ fn subscribe(
|
||||||
+ ReturnCode::ENOSUPPORT
|
+ &self,
|
||||||
|
+ subscribe_num: usize,
|
||||||
|
+ callback: Option<Callback>,
|
||||||
|
+ appid: AppId,
|
||||||
|
+ ) -> ReturnCode {
|
||||||
|
+ match subscribe_num {
|
||||||
|
+ 0 => self
|
||||||
|
+ .apps
|
||||||
|
+ .enter(appid, |app, _| {
|
||||||
|
+ app.callback = callback;
|
||||||
|
+ ReturnCode::SUCCESS
|
||||||
|
+ })
|
||||||
|
+ .unwrap_or_else(|err| err.into()),
|
||||||
|
+ _ => ReturnCode::ENOSUPPORT,
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ fn command(&self, cmd: usize, arg0: usize, arg1: usize, appid: AppId) -> ReturnCode {
|
+ fn command(&self, cmd: usize, arg0: usize, arg1: usize, appid: AppId) -> ReturnCode {
|
||||||
@@ -391,6 +449,10 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+ if len != slice.len() {
|
+ if len != slice.len() {
|
||||||
+ return ReturnCode::EINVAL;
|
+ return ReturnCode::EINVAL;
|
||||||
+ }
|
+ }
|
||||||
|
+ if self.waiting.is_some() {
|
||||||
|
+ return ReturnCode::EBUSY;
|
||||||
|
+ }
|
||||||
|
+ self.waiting.set(appid);
|
||||||
+ self.write_slice(ptr, slice.as_ref())
|
+ self.write_slice(ptr, slice.as_ref())
|
||||||
+ })
|
+ })
|
||||||
+ .unwrap_or_else(|err| err.into()),
|
+ .unwrap_or_else(|err| err.into()),
|
||||||
@@ -399,6 +461,10 @@ index b70162cae..9dcb82b07 100644
|
|||||||
+ if len != PAGE_SIZE {
|
+ if len != PAGE_SIZE {
|
||||||
+ return ReturnCode::EINVAL;
|
+ return ReturnCode::EINVAL;
|
||||||
+ }
|
+ }
|
||||||
|
+ if self.waiting.is_some() {
|
||||||
|
+ return ReturnCode::EBUSY;
|
||||||
|
+ }
|
||||||
|
+ self.waiting.set(appid);
|
||||||
+ self.erase_page(ptr)
|
+ self.erase_page(ptr)
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ index b485a0997..f5d29d025 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
index ebee8704b..6a2f8715b 100644
|
index c80732f8d..41047a390 100644
|
||||||
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
@@ -104,6 +104,17 @@ pub mod io;
|
@@ -104,6 +104,17 @@ pub mod io;
|
||||||
@@ -215,8 +215,8 @@ index ebee8704b..6a2f8715b 100644
|
|||||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
||||||
_ => f(None),
|
_ => f(None),
|
||||||
}
|
}
|
||||||
@@ -371,6 +388,21 @@ pub unsafe fn reset_handler() {
|
@@ -377,6 +394,21 @@ pub unsafe fn reset_handler() {
|
||||||
)
|
.expect("no deferred call slot available for nvmc"),
|
||||||
);
|
);
|
||||||
|
|
||||||
+ // Enable power events to be sent to USB controller
|
+ // Enable power events to be sent to USB controller
|
||||||
@@ -237,7 +237,7 @@ index ebee8704b..6a2f8715b 100644
|
|||||||
nrf52_components::NrfClockComponent::new().finalize(());
|
nrf52_components::NrfClockComponent::new().finalize(());
|
||||||
|
|
||||||
let platform = Platform {
|
let platform = Platform {
|
||||||
@@ -383,6 +415,7 @@ pub unsafe fn reset_handler() {
|
@@ -389,6 +421,7 @@ pub unsafe fn reset_handler() {
|
||||||
alarm,
|
alarm,
|
||||||
analog_comparator,
|
analog_comparator,
|
||||||
nvmc,
|
nvmc,
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ index f5d29d025..051943867 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
index 6a2f8715b..7898562dd 100644
|
index 41047a390..05e19b821 100644
|
||||||
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
@@ -163,6 +163,7 @@ pub struct Platform {
|
@@ -163,6 +163,7 @@ pub struct Platform {
|
||||||
@@ -149,7 +149,7 @@ index 6a2f8715b..7898562dd 100644
|
|||||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
||||||
_ => f(None),
|
_ => f(None),
|
||||||
}
|
}
|
||||||
@@ -403,6 +405,14 @@ pub unsafe fn reset_handler() {
|
@@ -409,6 +411,14 @@ pub unsafe fn reset_handler() {
|
||||||
)
|
)
|
||||||
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ index 6a2f8715b..7898562dd 100644
|
|||||||
nrf52_components::NrfClockComponent::new().finalize(());
|
nrf52_components::NrfClockComponent::new().finalize(());
|
||||||
|
|
||||||
let platform = Platform {
|
let platform = Platform {
|
||||||
@@ -416,6 +426,7 @@ pub unsafe fn reset_handler() {
|
@@ -422,6 +432,7 @@ pub unsafe fn reset_handler() {
|
||||||
analog_comparator,
|
analog_comparator,
|
||||||
nvmc,
|
nvmc,
|
||||||
usb,
|
usb,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ index daaeaedc7..c4b0afee9 100644
|
|||||||
|
|
||||||
// Static reference to chip for panic dumps
|
// Static reference to chip for panic dumps
|
||||||
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
diff --git a/boards/nordic/nrf52840dk_opensk/src/main.rs b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
index 7898562dd..2443cae8a 100644
|
index 05e19b821..47b27bf0a 100644
|
||||||
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
--- a/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
+++ b/boards/nordic/nrf52840dk_opensk/src/main.rs
|
||||||
@@ -128,6 +128,7 @@ static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROC
|
@@ -128,6 +128,7 @@ static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROC
|
||||||
|
|||||||
@@ -15,11 +15,16 @@
|
|||||||
use super::helper::{find_slice, is_aligned, ModRange};
|
use super::helper::{find_slice, is_aligned, ModRange};
|
||||||
use super::upgrade_storage::UpgradeStorage;
|
use super::upgrade_storage::UpgradeStorage;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use libtock_core::syscalls;
|
use core::cell::Cell;
|
||||||
|
use libtock_core::{callback, syscalls};
|
||||||
use persistent_store::{Storage, StorageError, StorageIndex, StorageResult};
|
use persistent_store::{Storage, StorageError, StorageIndex, StorageResult};
|
||||||
|
|
||||||
const DRIVER_NUMBER: usize = 0x50003;
|
const DRIVER_NUMBER: usize = 0x50003;
|
||||||
|
|
||||||
|
mod subscribe_nr {
|
||||||
|
pub const DONE: usize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mod command_nr {
|
mod command_nr {
|
||||||
pub const GET_INFO: usize = 1;
|
pub const GET_INFO: usize = 1;
|
||||||
pub mod get_info_nr {
|
pub mod get_info_nr {
|
||||||
@@ -63,6 +68,31 @@ fn memop(nr: u32, arg: usize) -> StorageResult<usize> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_command(driver: usize, cmd: usize, arg1: usize, arg2: usize) -> StorageResult<()> {
|
||||||
|
let done = Cell::new(None);
|
||||||
|
let mut alarm = |status| done.set(Some(status));
|
||||||
|
let subscription = syscalls::subscribe::<callback::Identity1Consumer, _>(
|
||||||
|
DRIVER_NUMBER,
|
||||||
|
subscribe_nr::DONE,
|
||||||
|
&mut alarm,
|
||||||
|
);
|
||||||
|
if subscription.is_err() {
|
||||||
|
return Err(StorageError::CustomError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let code = syscalls::command(driver, cmd, arg1, arg2);
|
||||||
|
if code.is_err() {
|
||||||
|
return Err(StorageError::CustomError);
|
||||||
|
}
|
||||||
|
|
||||||
|
libtock_drivers::util::yieldk_for(|| done.get().is_some());
|
||||||
|
if done.get().unwrap() == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(StorageError::CustomError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn write_slice(ptr: usize, value: &[u8]) -> StorageResult<()> {
|
fn write_slice(ptr: usize, value: &[u8]) -> StorageResult<()> {
|
||||||
let code = unsafe {
|
let code = unsafe {
|
||||||
syscalls::raw::allow(
|
syscalls::raw::allow(
|
||||||
@@ -78,20 +108,11 @@ fn write_slice(ptr: usize, value: &[u8]) -> StorageResult<()> {
|
|||||||
return Err(StorageError::CustomError);
|
return Err(StorageError::CustomError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = syscalls::command(DRIVER_NUMBER, command_nr::WRITE_SLICE, ptr, value.len());
|
block_command(DRIVER_NUMBER, command_nr::WRITE_SLICE, ptr, value.len())
|
||||||
if code.is_err() {
|
|
||||||
return Err(StorageError::CustomError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn erase_page(ptr: usize, page_length: usize) -> StorageResult<()> {
|
fn erase_page(ptr: usize, page_length: usize) -> StorageResult<()> {
|
||||||
let code = syscalls::command(DRIVER_NUMBER, command_nr::ERASE_PAGE, ptr, page_length);
|
block_command(DRIVER_NUMBER, command_nr::ERASE_PAGE, ptr, page_length)
|
||||||
if code.is_err() {
|
|
||||||
return Err(StorageError::CustomError);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SyscallStorage {
|
pub struct SyscallStorage {
|
||||||
|
|||||||
Reference in New Issue
Block a user