Skip to content

Commit

Permalink
Put shared buffer into UnsafeCell
Browse files Browse the repository at this point in the history
  • Loading branch information
torfmaster committed May 22, 2020
1 parent b8e8c41 commit c5c8267
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 49 deletions.
37 changes: 23 additions & 14 deletions core/src/shared_memory.rs
Original file line number Diff line number Diff line change
@@ -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<T> {
driver_number: usize,
allow_number: usize,
buffer_to_share: &'a mut [u8],
buffer_to_share: UnsafeCell<T>,
}

impl<'a> SharedMemory<'a> {
pub fn new(
driver_number: usize,
allow_number: usize,
buffer_to_share: &'a mut [u8],
) -> SharedMemory<'a> {
impl<T> SharedMemory<T>
where
T: AsMut<[u8]>,
{
pub fn new(driver_number: usize, allow_number: usize, buffer_to_share: T) -> SharedMemory<T> {
SharedMemory {
driver_number,
allow_number,
buffer_to_share,
buffer_to_share: UnsafeCell::new(buffer_to_share),
}
}

pub fn read_bytes<T: AsMut<[u8]>>(&self, mut destination: T) {
safe_copy(self.buffer_to_share, destination.as_mut());
pub fn read_bytes<D: AsMut<[u8]>>(&self, mut destination: D) {
let buf = unsafe { (*self.buffer_to_share.get()).as_mut() };
safe_copy(buf, destination.as_mut());
}

pub fn write_bytes<T: AsRef<[u8]>>(&mut self, source: T) {
safe_copy(source.as_ref(), self.buffer_to_share);
pub fn write_bytes<S: AsRef<[u8]>>(&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: Sized, F: FnOnce(*mut u8) -> R>(
&self,
func: F,
) -> R {
func((*self.buffer_to_share.get()).as_mut().as_mut_ptr())
}
}

impl<'a> Drop for SharedMemory<'a> {
impl<T> Drop for SharedMemory<T> {
fn drop(&mut self) {
unsafe {
syscalls::raw::allow(self.driver_number, self.allow_number, ptr::null_mut(), 0);
Expand Down
24 changes: 9 additions & 15 deletions core/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,20 @@ pub fn command1_insecure(
}
}

pub fn allow(
pub fn allow<T: AsMut<[u8]>>(
driver_number: usize,
allow_number: usize,
buffer_to_share: &mut [u8],
) -> Result<SharedMemory, AllowError> {
let len = buffer_to_share.len();
mut buffer_to_share: T,
) -> Result<SharedMemory<T>, 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,
Expand Down
2 changes: 1 addition & 1 deletion examples-features/ble_scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<LedCommand>(&payload).ok())
.and_then(|msg| leds_driver.get(msg.nr as usize).ok())
Expand Down
4 changes: 2 additions & 2 deletions examples-features/simple_ble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()?;
Expand Down
4 changes: 2 additions & 2 deletions examples/adc_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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[..]);
Expand Down
15 changes: 10 additions & 5 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -67,13 +73,12 @@ impl<CB: FnMut(usize, usize)> Consumer<CB> for AdcEventConsumer {
}

impl<'a> Adc<'a> {
pub fn init_buffer(&self, buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, &mut buffer.buffer).map_err(Into::into)
pub fn init_buffer(&self, buffer: AdcBuffer) -> TockResult<SharedMemory<AdcBuffer>> {
syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, buffer).map_err(Into::into)
}

pub fn init_alt_buffer(&self, alt_buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> {
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<SharedMemory<AdcBuffer>> {
syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, alt_buffer).map_err(Into::into)
}

/// Return the number of available channels
Expand Down
41 changes: 31 additions & 10 deletions src/simple_ble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<SharedMemory<'a>> {
advertising_buffer: BleAdvertisingBuffer,
) -> TockResult<SharedMemory<BleAdvertisingBuffer>> {
let mut shared_memory = syscalls::allow(
DRIVER_NUMBER,
allow_nr::ALLOW_ADVERTISMENT_BUFFER,
Expand All @@ -86,12 +94,19 @@ impl BleAdvertisingDriver {

struct BleCallback<'a> {
read_value: &'a Cell<Option<ScanBuffer>>,
shared_buffer: SharedMemory<'a>,
shared_buffer: SharedMemory<ScanBuffer>,
}

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;
Expand Down Expand Up @@ -130,13 +145,19 @@ pub struct BleScanningDriver {
read_value: Cell<Option<ScanBuffer>>,
}

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<BleScanningDriverShared> {
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::<TockError>::into)?;
Ok(BleScanningDriverShared {
Expand Down Expand Up @@ -195,7 +216,7 @@ impl<'a> Consumer<Self> 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));
}
}

0 comments on commit c5c8267

Please sign in to comment.