diff --git a/core/src/shared_memory.rs b/core/src/shared_memory.rs index 76e710e6..6739093c 100644 --- a/core/src/shared_memory.rs +++ b/core/src/shared_memory.rs @@ -1,11 +1,12 @@ 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> { driver_number: usize, allow_number: usize, - buffer_to_share: &'a mut [u8], + buffer_to_share: UnsafeCell<&'a mut [u8]>, } impl<'a> SharedMemory<'a> { @@ -17,20 +18,24 @@ impl<'a> SharedMemory<'a> { 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) { + self.operate_on_mut(|buf| 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) { + self.operate_on_mut(|buf| safe_copy(source.as_ref(), buf)); + } + + pub(crate) fn operate_on_mut R>(&self, func: F) -> R { + unsafe { func(&mut *self.buffer_to_share.get()) } } } -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 bae938b1..6c6193d7 100644 --- a/core/src/syscalls/mod.rs +++ b/core/src/syscalls/mod.rs @@ -116,22 +116,17 @@ pub fn allow( driver_number: usize, allow_number: usize, buffer_to_share: &mut [u8], -) -> Result { - let len = buffer_to_share.len(); +) -> 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(|buffer| { + raw::allow(driver_number, allow_number, buffer.as_mut_ptr(), 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 c6a68736..e6d17798 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/src/adc.rs b/src/adc.rs index 7d351dfa..63f0fdc2 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,11 +73,11 @@ impl Consumer for AdcEventConsumer { } impl<'a> Adc<'a> { - pub fn init_buffer(&self, buffer: &'a mut AdcBuffer) -> TockResult { + 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_alt_buffer(&self, alt_buffer: &'a mut AdcBuffer) -> TockResult { + 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) } diff --git a/src/hmac.rs b/src/hmac.rs index e5475cce..f5b0280b 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -58,10 +58,34 @@ impl Default for HmacKeyBuffer { } } +impl AsRef<[u8]> for HmacKeyBuffer { + fn as_ref(&self) -> &[u8] { + &self.buffer + } +} + +impl AsMut<[u8]> for HmacKeyBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.buffer + } +} + pub struct HmacDataBuffer { pub buffer: [u8; DATA_BUFFER_SIZE], } +impl AsRef<[u8]> for HmacDataBuffer { + fn as_ref(&self) -> &[u8] { + &self.buffer + } +} + +impl AsMut<[u8]> for HmacDataBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.buffer + } +} + impl Default for HmacDataBuffer { fn default() -> Self { HmacDataBuffer { @@ -74,6 +98,18 @@ pub struct HmacDestBuffer { buffer: [u8; DEST_BUFFER_SIZE], } +impl AsRef<[u8]> for HmacDestBuffer { + fn as_ref(&self) -> &[u8] { + &self.buffer + } +} + +impl AsMut<[u8]> for HmacDestBuffer { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.buffer + } +} + impl Default for HmacDestBuffer { fn default() -> Self { HmacDestBuffer { @@ -87,15 +123,15 @@ pub struct HmacDriver<'a> { } impl<'a> HmacDriver<'a> { - pub fn init_key_buffer(&self, buffer: &'a mut HmacKeyBuffer) -> TockResult { + pub fn init_key_buffer(&self, buffer: &'a mut HmacKeyBuffer) -> TockResult> { syscalls::allow(DRIVER_NUMBER, allow_nr::KEY, &mut buffer.buffer).map_err(Into::into) } - pub fn init_data_buffer(&self, buffer: &'a mut HmacDataBuffer) -> TockResult { + pub fn init_data_buffer(&self, buffer: &'a mut HmacDataBuffer) -> TockResult> { syscalls::allow(DRIVER_NUMBER, allow_nr::DATA, &mut buffer.buffer).map_err(Into::into) } - pub fn init_dest_buffer(&self, buffer: &'a mut HmacDestBuffer) -> TockResult { + pub fn init_dest_buffer(&self, buffer: &'a mut HmacDestBuffer) -> TockResult> { syscalls::allow(DRIVER_NUMBER, allow_nr::DEST, &mut buffer.buffer).map_err(Into::into) } diff --git a/src/simple_ble.rs b/src/simple_ble.rs index 102b3605..a24e6a95 100644 --- a/src/simple_ble.rs +++ b/src/simple_ble.rs @@ -53,20 +53,28 @@ 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>( + pub fn initialize<'a, 'b>( &'a mut self, interval: usize, service_payload: &BlePayload, - advertising_buffer: &'a mut [u8; BUFFER_SIZE_ADVERTISE], - ) -> TockResult> { + advertising_buffer: &'b mut BleAdvertisingBuffer, + ) -> TockResult> { let mut shared_memory = syscalls::allow( DRIVER_NUMBER, allow_nr::ALLOW_ADVERTISMENT_BUFFER, - advertising_buffer, + &mut advertising_buffer.0, )?; shared_memory.write_bytes(service_payload); Self::start_advertising(gap_flags::BLE_DISCOVERABLE, interval)?; @@ -89,9 +97,16 @@ struct BleCallback<'a> { shared_buffer: SharedMemory<'a>, } -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, + &mut self.shared_buffer.0, ) .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)); } }