From c5c8267ee6e4cb4e77921cd089e75397a7de4ad9 Mon Sep 17 00:00:00 2001 From: torfmaster Date: Sun, 22 Mar 2020 11:58:09 +0100 Subject: [PATCH] Put shared buffer into UnsafeCell --- core/src/shared_memory.rs | 37 +++++++++++++++++----------- core/src/syscalls/mod.rs | 24 +++++++----------- examples-features/ble_scanning.rs | 2 +- examples-features/simple_ble.rs | 4 +-- examples/adc_buffer.rs | 4 +-- src/adc.rs | 15 +++++++---- src/simple_ble.rs | 41 +++++++++++++++++++++++-------- 7 files changed, 78 insertions(+), 49 deletions(-) diff --git a/core/src/shared_memory.rs b/core/src/shared_memory.rs index 76e710e68..d8a821be8 100644 --- a/core/src/shared_memory.rs +++ b/core/src/shared_memory.rs @@ -1,36 +1,45 @@ use crate::syscalls; +use core::cell::UnsafeCell; use core::ptr; #[must_use = "Shared memory risks being dropped too early. Drop it manually."] -pub struct SharedMemory<'a> { +pub struct SharedMemory { driver_number: usize, allow_number: usize, - buffer_to_share: &'a mut [u8], + buffer_to_share: UnsafeCell, } -impl<'a> SharedMemory<'a> { - pub fn new( - driver_number: usize, - allow_number: usize, - buffer_to_share: &'a mut [u8], - ) -> SharedMemory<'a> { +impl SharedMemory +where + T: AsMut<[u8]>, +{ + pub fn new(driver_number: usize, allow_number: usize, buffer_to_share: T) -> SharedMemory { SharedMemory { driver_number, allow_number, - buffer_to_share, + buffer_to_share: UnsafeCell::new(buffer_to_share), } } - pub fn read_bytes>(&self, mut destination: T) { - safe_copy(self.buffer_to_share, destination.as_mut()); + pub fn read_bytes>(&self, mut destination: D) { + let buf = unsafe { (*self.buffer_to_share.get()).as_mut() }; + safe_copy(buf, destination.as_mut()); } - pub fn write_bytes>(&mut self, source: T) { - safe_copy(source.as_ref(), self.buffer_to_share); + pub fn write_bytes>(&mut self, source: S) { + let buf = unsafe { (*self.buffer_to_share.get()).as_mut() }; + safe_copy(source.as_ref(), buf); + } + + pub(crate) unsafe fn operate_on_mut_ptr R>( + &self, + func: F, + ) -> R { + func((*self.buffer_to_share.get()).as_mut().as_mut_ptr()) } } -impl<'a> Drop for SharedMemory<'a> { +impl Drop for SharedMemory { fn drop(&mut self) { unsafe { syscalls::raw::allow(self.driver_number, self.allow_number, ptr::null_mut(), 0); diff --git a/core/src/syscalls/mod.rs b/core/src/syscalls/mod.rs index bae938b10..57cbe4124 100644 --- a/core/src/syscalls/mod.rs +++ b/core/src/syscalls/mod.rs @@ -112,26 +112,20 @@ pub fn command1_insecure( } } -pub fn allow( +pub fn allow>( driver_number: usize, allow_number: usize, - buffer_to_share: &mut [u8], -) -> Result { - let len = buffer_to_share.len(); + mut buffer_to_share: T, +) -> Result, AllowError> { + let len = buffer_to_share.as_mut().len(); + let shared_memory = SharedMemory::new(driver_number, allow_number, buffer_to_share); let return_code = unsafe { - raw::allow( - driver_number, - allow_number, - buffer_to_share.as_mut_ptr(), - len, - ) + shared_memory + .operate_on_mut_ptr(|pointer| raw::allow(driver_number, allow_number, pointer, len)) }; + if return_code == 0 { - Ok(SharedMemory::new( - driver_number, - allow_number, - buffer_to_share, - )) + Ok(shared_memory) } else { Err(AllowError { driver_number, diff --git a/examples-features/ble_scanning.rs b/examples-features/ble_scanning.rs index c6a687360..e6d17798f 100644 --- a/examples-features/ble_scanning.rs +++ b/examples-features/ble_scanning.rs @@ -23,7 +23,7 @@ async fn main() -> TockResult<()> { loop { let value = ble_scanning_driver_scanning.stream_values().await; - ble_parser::find(&value, simple_ble::gap_data::SERVICE_DATA as u8) + ble_parser::find(value.as_ref(), simple_ble::gap_data::SERVICE_DATA as u8) .and_then(|service_data| ble_parser::extract_for_service([91, 79], service_data)) .and_then(|payload| corepack::from_bytes::(&payload).ok()) .and_then(|msg| leds_driver.get(msg.nr as usize).ok()) diff --git a/examples-features/simple_ble.rs b/examples-features/simple_ble.rs index 8dde30958..13a220794 100644 --- a/examples-features/simple_ble.rs +++ b/examples-features/simple_ble.rs @@ -27,7 +27,7 @@ async fn main() -> TockResult<()> { let payload = corepack::to_bytes(LedCommand { nr: 2, st: true }).unwrap(); - let mut buffer = BleAdvertisingDriver::create_advertising_buffer(); + let buffer = BleAdvertisingDriver::create_advertising_buffer(); let mut gap_payload = BlePayload::default(); gap_payload @@ -44,7 +44,7 @@ async fn main() -> TockResult<()> { gap_payload.add_service_payload([91, 79], &payload).unwrap(); - let _handle = ble_advertising_driver.initialize(100, &gap_payload, &mut buffer); + let _handle = ble_advertising_driver.initialize(100, &gap_payload, buffer); loop { led.on()?; diff --git a/examples/adc_buffer.rs b/examples/adc_buffer.rs index 86f94b2f3..25da18e09 100644 --- a/examples/adc_buffer.rs +++ b/examples/adc_buffer.rs @@ -13,10 +13,10 @@ async fn main() -> TockResult<()> { let adc_driver = drivers.adc.init_driver()?; let mut console = drivers.console.create_console(); - let mut adc_buffer = AdcBuffer::default(); + let adc_buffer = AdcBuffer::default(); let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE]; - let adc_buffer = adc_driver.init_buffer(&mut adc_buffer)?; + let adc_buffer = adc_driver.init_buffer(adc_buffer)?; let mut callback = |_, _| { adc_buffer.read_bytes(&mut temp_buffer[..]); diff --git a/src/adc.rs b/src/adc.rs index 7d351dfa3..8d1c31433 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -45,6 +45,12 @@ pub struct AdcBuffer { buffer: [u8; BUFFER_SIZE], } +impl AsMut<[u8]> for AdcBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.buffer + } +} + impl Default for AdcBuffer { fn default() -> Self { AdcBuffer { @@ -67,13 +73,12 @@ impl Consumer for AdcEventConsumer { } impl<'a> Adc<'a> { - pub fn init_buffer(&self, buffer: &'a mut AdcBuffer) -> TockResult { - syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, &mut buffer.buffer).map_err(Into::into) + pub fn init_buffer(&self, buffer: AdcBuffer) -> TockResult> { + syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, buffer).map_err(Into::into) } - pub fn init_alt_buffer(&self, alt_buffer: &'a mut AdcBuffer) -> TockResult { - syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, &mut alt_buffer.buffer) - .map_err(Into::into) + pub fn init_alt_buffer(&self, alt_buffer: AdcBuffer) -> TockResult> { + syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, alt_buffer).map_err(Into::into) } /// Return the number of available channels diff --git a/src/simple_ble.rs b/src/simple_ble.rs index 102b36052..c4786fdcb 100644 --- a/src/simple_ble.rs +++ b/src/simple_ble.rs @@ -53,16 +53,24 @@ impl BleAdvertisingDriverFactory { #[non_exhaustive] pub struct BleAdvertisingDriver; +pub struct BleAdvertisingBuffer([u8; BUFFER_SIZE_ADVERTISE]); + +impl AsMut<[u8]> for BleAdvertisingBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0 + } +} + impl BleAdvertisingDriver { - pub fn create_advertising_buffer() -> [u8; BUFFER_SIZE_ADVERTISE] { - [0; BUFFER_SIZE_ADVERTISE] + pub fn create_advertising_buffer() -> BleAdvertisingBuffer { + BleAdvertisingBuffer([0; BUFFER_SIZE_ADVERTISE]) } pub fn initialize<'a>( &'a mut self, interval: usize, service_payload: &BlePayload, - advertising_buffer: &'a mut [u8; BUFFER_SIZE_ADVERTISE], - ) -> TockResult> { + advertising_buffer: BleAdvertisingBuffer, + ) -> TockResult> { let mut shared_memory = syscalls::allow( DRIVER_NUMBER, allow_nr::ALLOW_ADVERTISMENT_BUFFER, @@ -86,12 +94,19 @@ impl BleAdvertisingDriver { struct BleCallback<'a> { read_value: &'a Cell>, - shared_buffer: SharedMemory<'a>, + shared_buffer: SharedMemory, } -pub(crate) type ScanBuffer = [u8; BUFFER_SIZE_SCAN]; +#[derive(Clone, Copy)] +pub struct ScanBuffer([u8; BUFFER_SIZE_SCAN]); + +impl AsRef<[u8]> for ScanBuffer { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} -const EMPTY_SCAN_BUFFER: ScanBuffer = [0; BUFFER_SIZE_SCAN]; +const EMPTY_SCAN_BUFFER: ScanBuffer = ScanBuffer([0; BUFFER_SIZE_SCAN]); #[non_exhaustive] pub struct BleScanningDriverFactory; @@ -130,13 +145,19 @@ pub struct BleScanningDriver { read_value: Cell>, } +impl AsMut<[u8]> for ScanBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0 + } +} + impl BleScanningDriver { /// Prepare Ble Scanning Driver to share memory with the ble capsule pub fn share_memory(&mut self) -> TockResult { - let shared_buffer: SharedMemory = syscalls::allow( + let shared_buffer = syscalls::allow( DRIVER_NUMBER, allow_nr::ALLOW_SCAN_BUFFER, - &mut self.shared_buffer, + self.shared_buffer, ) .map_err(Into::::into)?; Ok(BleScanningDriverShared { @@ -195,7 +216,7 @@ impl<'a> Consumer for BleCallback<'a> { fn consume(callback: &mut Self, _: usize, _: usize, _: usize) { let mut temporary_buffer: ScanBuffer = EMPTY_SCAN_BUFFER; - callback.shared_buffer.read_bytes(&mut temporary_buffer[..]); + callback.shared_buffer.read_bytes(temporary_buffer.as_mut()); callback.read_value.set(Some(temporary_buffer)); } }