Skip to content

Commit c5c8267

Browse files
committed
Put shared buffer into UnsafeCell
1 parent b8e8c41 commit c5c8267

File tree

7 files changed

+78
-49
lines changed

7 files changed

+78
-49
lines changed

core/src/shared_memory.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,45 @@
11
use crate::syscalls;
2+
use core::cell::UnsafeCell;
23
use core::ptr;
34

45
#[must_use = "Shared memory risks being dropped too early. Drop it manually."]
5-
pub struct SharedMemory<'a> {
6+
pub struct SharedMemory<T> {
67
driver_number: usize,
78
allow_number: usize,
8-
buffer_to_share: &'a mut [u8],
9+
buffer_to_share: UnsafeCell<T>,
910
}
1011

11-
impl<'a> SharedMemory<'a> {
12-
pub fn new(
13-
driver_number: usize,
14-
allow_number: usize,
15-
buffer_to_share: &'a mut [u8],
16-
) -> SharedMemory<'a> {
12+
impl<T> SharedMemory<T>
13+
where
14+
T: AsMut<[u8]>,
15+
{
16+
pub fn new(driver_number: usize, allow_number: usize, buffer_to_share: T) -> SharedMemory<T> {
1717
SharedMemory {
1818
driver_number,
1919
allow_number,
20-
buffer_to_share,
20+
buffer_to_share: UnsafeCell::new(buffer_to_share),
2121
}
2222
}
2323

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

28-
pub fn write_bytes<T: AsRef<[u8]>>(&mut self, source: T) {
29-
safe_copy(source.as_ref(), self.buffer_to_share);
29+
pub fn write_bytes<S: AsRef<[u8]>>(&mut self, source: S) {
30+
let buf = unsafe { (*self.buffer_to_share.get()).as_mut() };
31+
safe_copy(source.as_ref(), buf);
32+
}
33+
34+
pub(crate) unsafe fn operate_on_mut_ptr<R: Sized, F: FnOnce(*mut u8) -> R>(
35+
&self,
36+
func: F,
37+
) -> R {
38+
func((*self.buffer_to_share.get()).as_mut().as_mut_ptr())
3039
}
3140
}
3241

33-
impl<'a> Drop for SharedMemory<'a> {
42+
impl<T> Drop for SharedMemory<T> {
3443
fn drop(&mut self) {
3544
unsafe {
3645
syscalls::raw::allow(self.driver_number, self.allow_number, ptr::null_mut(), 0);

core/src/syscalls/mod.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -112,26 +112,20 @@ pub fn command1_insecure(
112112
}
113113
}
114114

115-
pub fn allow(
115+
pub fn allow<T: AsMut<[u8]>>(
116116
driver_number: usize,
117117
allow_number: usize,
118-
buffer_to_share: &mut [u8],
119-
) -> Result<SharedMemory, AllowError> {
120-
let len = buffer_to_share.len();
118+
mut buffer_to_share: T,
119+
) -> Result<SharedMemory<T>, AllowError> {
120+
let len = buffer_to_share.as_mut().len();
121+
let shared_memory = SharedMemory::new(driver_number, allow_number, buffer_to_share);
121122
let return_code = unsafe {
122-
raw::allow(
123-
driver_number,
124-
allow_number,
125-
buffer_to_share.as_mut_ptr(),
126-
len,
127-
)
123+
shared_memory
124+
.operate_on_mut_ptr(|pointer| raw::allow(driver_number, allow_number, pointer, len))
128125
};
126+
129127
if return_code == 0 {
130-
Ok(SharedMemory::new(
131-
driver_number,
132-
allow_number,
133-
buffer_to_share,
134-
))
128+
Ok(shared_memory)
135129
} else {
136130
Err(AllowError {
137131
driver_number,

examples-features/ble_scanning.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async fn main() -> TockResult<()> {
2323

2424
loop {
2525
let value = ble_scanning_driver_scanning.stream_values().await;
26-
ble_parser::find(&value, simple_ble::gap_data::SERVICE_DATA as u8)
26+
ble_parser::find(value.as_ref(), simple_ble::gap_data::SERVICE_DATA as u8)
2727
.and_then(|service_data| ble_parser::extract_for_service([91, 79], service_data))
2828
.and_then(|payload| corepack::from_bytes::<LedCommand>(&payload).ok())
2929
.and_then(|msg| leds_driver.get(msg.nr as usize).ok())

examples-features/simple_ble.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ async fn main() -> TockResult<()> {
2727

2828
let payload = corepack::to_bytes(LedCommand { nr: 2, st: true }).unwrap();
2929

30-
let mut buffer = BleAdvertisingDriver::create_advertising_buffer();
30+
let buffer = BleAdvertisingDriver::create_advertising_buffer();
3131
let mut gap_payload = BlePayload::default();
3232

3333
gap_payload
@@ -44,7 +44,7 @@ async fn main() -> TockResult<()> {
4444

4545
gap_payload.add_service_payload([91, 79], &payload).unwrap();
4646

47-
let _handle = ble_advertising_driver.initialize(100, &gap_payload, &mut buffer);
47+
let _handle = ble_advertising_driver.initialize(100, &gap_payload, buffer);
4848

4949
loop {
5050
led.on()?;

examples/adc_buffer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ async fn main() -> TockResult<()> {
1313
let adc_driver = drivers.adc.init_driver()?;
1414
let mut console = drivers.console.create_console();
1515

16-
let mut adc_buffer = AdcBuffer::default();
16+
let adc_buffer = AdcBuffer::default();
1717
let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE];
1818

19-
let adc_buffer = adc_driver.init_buffer(&mut adc_buffer)?;
19+
let adc_buffer = adc_driver.init_buffer(adc_buffer)?;
2020

2121
let mut callback = |_, _| {
2222
adc_buffer.read_bytes(&mut temp_buffer[..]);

src/adc.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ pub struct AdcBuffer {
4545
buffer: [u8; BUFFER_SIZE],
4646
}
4747

48+
impl AsMut<[u8]> for AdcBuffer {
49+
fn as_mut(&mut self) -> &mut [u8] {
50+
&mut self.buffer
51+
}
52+
}
53+
4854
impl Default for AdcBuffer {
4955
fn default() -> Self {
5056
AdcBuffer {
@@ -67,13 +73,12 @@ impl<CB: FnMut(usize, usize)> Consumer<CB> for AdcEventConsumer {
6773
}
6874

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

74-
pub fn init_alt_buffer(&self, alt_buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> {
75-
syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, &mut alt_buffer.buffer)
76-
.map_err(Into::into)
80+
pub fn init_alt_buffer(&self, alt_buffer: AdcBuffer) -> TockResult<SharedMemory<AdcBuffer>> {
81+
syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, alt_buffer).map_err(Into::into)
7782
}
7883

7984
/// Return the number of available channels

src/simple_ble.rs

+31-10
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,24 @@ impl BleAdvertisingDriverFactory {
5353
#[non_exhaustive]
5454
pub struct BleAdvertisingDriver;
5555

56+
pub struct BleAdvertisingBuffer([u8; BUFFER_SIZE_ADVERTISE]);
57+
58+
impl AsMut<[u8]> for BleAdvertisingBuffer {
59+
fn as_mut(&mut self) -> &mut [u8] {
60+
&mut self.0
61+
}
62+
}
63+
5664
impl BleAdvertisingDriver {
57-
pub fn create_advertising_buffer() -> [u8; BUFFER_SIZE_ADVERTISE] {
58-
[0; BUFFER_SIZE_ADVERTISE]
65+
pub fn create_advertising_buffer() -> BleAdvertisingBuffer {
66+
BleAdvertisingBuffer([0; BUFFER_SIZE_ADVERTISE])
5967
}
6068
pub fn initialize<'a>(
6169
&'a mut self,
6270
interval: usize,
6371
service_payload: &BlePayload,
64-
advertising_buffer: &'a mut [u8; BUFFER_SIZE_ADVERTISE],
65-
) -> TockResult<SharedMemory<'a>> {
72+
advertising_buffer: BleAdvertisingBuffer,
73+
) -> TockResult<SharedMemory<BleAdvertisingBuffer>> {
6674
let mut shared_memory = syscalls::allow(
6775
DRIVER_NUMBER,
6876
allow_nr::ALLOW_ADVERTISMENT_BUFFER,
@@ -86,12 +94,19 @@ impl BleAdvertisingDriver {
8694

8795
struct BleCallback<'a> {
8896
read_value: &'a Cell<Option<ScanBuffer>>,
89-
shared_buffer: SharedMemory<'a>,
97+
shared_buffer: SharedMemory<ScanBuffer>,
9098
}
9199

92-
pub(crate) type ScanBuffer = [u8; BUFFER_SIZE_SCAN];
100+
#[derive(Clone, Copy)]
101+
pub struct ScanBuffer([u8; BUFFER_SIZE_SCAN]);
102+
103+
impl AsRef<[u8]> for ScanBuffer {
104+
fn as_ref(&self) -> &[u8] {
105+
&self.0
106+
}
107+
}
93108

94-
const EMPTY_SCAN_BUFFER: ScanBuffer = [0; BUFFER_SIZE_SCAN];
109+
const EMPTY_SCAN_BUFFER: ScanBuffer = ScanBuffer([0; BUFFER_SIZE_SCAN]);
95110

96111
#[non_exhaustive]
97112
pub struct BleScanningDriverFactory;
@@ -130,13 +145,19 @@ pub struct BleScanningDriver {
130145
read_value: Cell<Option<ScanBuffer>>,
131146
}
132147

148+
impl AsMut<[u8]> for ScanBuffer {
149+
fn as_mut(&mut self) -> &mut [u8] {
150+
&mut self.0
151+
}
152+
}
153+
133154
impl BleScanningDriver {
134155
/// Prepare Ble Scanning Driver to share memory with the ble capsule
135156
pub fn share_memory(&mut self) -> TockResult<BleScanningDriverShared> {
136-
let shared_buffer: SharedMemory = syscalls::allow(
157+
let shared_buffer = syscalls::allow(
137158
DRIVER_NUMBER,
138159
allow_nr::ALLOW_SCAN_BUFFER,
139-
&mut self.shared_buffer,
160+
self.shared_buffer,
140161
)
141162
.map_err(Into::<TockError>::into)?;
142163
Ok(BleScanningDriverShared {
@@ -195,7 +216,7 @@ impl<'a> Consumer<Self> for BleCallback<'a> {
195216
fn consume(callback: &mut Self, _: usize, _: usize, _: usize) {
196217
let mut temporary_buffer: ScanBuffer = EMPTY_SCAN_BUFFER;
197218

198-
callback.shared_buffer.read_bytes(&mut temporary_buffer[..]);
219+
callback.shared_buffer.read_bytes(temporary_buffer.as_mut());
199220
callback.read_value.set(Some(temporary_buffer));
200221
}
201222
}

0 commit comments

Comments
 (0)