Skip to content

Commit 9695aed

Browse files
async api + example
1 parent a89873e commit 9695aed

File tree

9 files changed

+121
-166
lines changed

9 files changed

+121
-166
lines changed

apis/rng/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
[package]
22
name = "libtock_rng"
33
version = "0.1.0"
4-
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
4+
authors = [
5+
"Tock Project Developers <tock-dev@googlegroups.com>",
6+
"Cosmin Gabriel Georgescu <cosmingg2013@gmail.com>",
7+
]
58
license = "Apache-2.0 OR MIT"
69
edition = "2021"
710
repository = "https://www.github.com/tock/libtock-rs"
811
rust-version.workspace = true
9-
description = "libtock buttons driver"
12+
description = "libtock rng driver"
1013

1114
[dependencies]
1215
libtock_platform = { path = "../../platform" }

apis/rng/src/lib.rs

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
#![no_std]
22

3-
#[cfg(test)]
4-
mod tests;
5-
63
use core::cell::Cell;
7-
use libtock_platform::{share, AllowRw, DefaultConfig, ErrorCode, Subscribe, Syscalls};
8-
9-
const DRIVER_NUM: u32 = 0x40001;
10-
const EXISTS: u32 = 0;
11-
const GET_BYTES: u32 = 1;
4+
use libtock_platform::{
5+
share, subscribe::OneId, AllowRw, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall,
6+
};
127

138
pub struct Rng<S: Syscalls>(S);
149

@@ -18,15 +13,47 @@ impl<S: Syscalls> Rng<S> {
1813
S::command(DRIVER_NUM, EXISTS, 0, 0).to_result()
1914
}
2015

16+
/// Request `n` bytes of randomness in an asynchronous way.
17+
/// Users must first share a buffer slice with the kernel and register an Rng listener
18+
pub fn get_bytes_async(n: u32) -> Result<(), ErrorCode> {
19+
S::command(DRIVER_NUM, GET_BYTES, n, 0).to_result()
20+
}
21+
22+
/// Share a buffer slice with the kernel.
23+
/// Must be used in conjunction with the `share::scope` function
24+
pub fn allow_buffer<'share>(
25+
buf: &'share mut [u8],
26+
allow_rw: share::Handle<AllowRw<'share, S, DRIVER_NUM, 0>>,
27+
) -> Result<(), ErrorCode> {
28+
S::allow_rw::<DefaultConfig, DRIVER_NUM, 0>(allow_rw, buf)
29+
}
30+
31+
pub fn unallow_buffer() {
32+
S::unallow_rw(DRIVER_NUM, 0)
33+
}
34+
35+
/// Register an Rng listener to be called when an upcall is serviced
36+
/// Must be used in conjunction with the `share::scope` function
37+
pub fn register_listener<'share, F: Fn(u32)>(
38+
listener: &'share RngListener<F>,
39+
subscribe: share::Handle<Subscribe<'share, S, DRIVER_NUM, 0>>,
40+
) -> Result<(), ErrorCode> {
41+
S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener)
42+
}
43+
44+
pub fn unregister_listener() {
45+
S::unsubscribe(DRIVER_NUM, 0)
46+
}
47+
2148
/// Ask to fill the provided `buf` with `n` random bytes.
2249
/// If `n > buf.len()`, it will simply fill the whole buffer.
2350
pub fn get_bytes_sync(buf: &mut [u8], n: u32) -> Result<(), ErrorCode> {
2451
let called = Cell::new(false);
2552
share::scope::<(AllowRw<S, DRIVER_NUM, 0>, Subscribe<S, DRIVER_NUM, 0>), _, _>(|handle| {
26-
let (allow_ro, subscribe) = handle.split();
53+
let (allow_rw, subscribe) = handle.split();
2754

2855
// Share the provided buffer with the kernel
29-
S::allow_rw::<DefaultConfig, DRIVER_NUM, 0>(allow_ro, buf)?;
56+
S::allow_rw::<DefaultConfig, DRIVER_NUM, 0>(allow_rw, buf)?;
3057

3158
// Subscribe for an upcall with the kernel
3259
S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, &called)?;
@@ -43,3 +70,24 @@ impl<S: Syscalls> Rng<S> {
4370
})
4471
}
4572
}
73+
74+
/// The provided listener to be called.
75+
/// Interior function operates on the number of random bytes filled into the buffer
76+
pub struct RngListener<F: Fn(u32)>(pub F);
77+
78+
impl<F: Fn(u32)> Upcall<OneId<DRIVER_NUM, 0>> for RngListener<F> {
79+
fn upcall(&self, _: u32, arg1: u32, _: u32) {
80+
(self.0)(arg1)
81+
}
82+
}
83+
84+
// -------------
85+
// DRIVER NUMBER
86+
// -------------
87+
const DRIVER_NUM: u32 = 0x40001;
88+
89+
// ---------------
90+
// COMMAND NUMBERS
91+
// ---------------
92+
const EXISTS: u32 = 0;
93+
const GET_BYTES: u32 = 1;

apis/rng/src/tests.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

examples/rng.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,46 @@
1-
#![no_main]
21
#![no_std]
2+
#![no_main]
33

44
use core::fmt::Write;
5-
use libtock::alarm::Alarm;
5+
use libtock::alarm::{Alarm, Milliseconds};
66
use libtock::console::Console;
77
use libtock::rng::Rng;
88
use libtock::runtime::{set_main, stack_size};
9-
use libtock_alarm::Milliseconds;
109

11-
set_main! {main}
1210
stack_size! {0x300}
11+
set_main! {main}
1312

1413
struct Randomness<'a, const N: usize>(&'a [u8; N]);
1514

1615
impl<'a, const N: usize> core::fmt::Display for Randomness<'a, N> {
17-
fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18-
let mut console_writer = Console::writer();
16+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1917
let mut bytes = self.0.iter();
2018
while let Some(&byte) = bytes.next() {
21-
write!(console_writer, "{byte:02x}")?;
19+
write!(f, "{byte:02x}")?;
2220
}
2321
Ok(())
2422
}
2523
}
2624

2725
fn main() {
2826
if let Err(e) = Rng::exists() {
29-
writeln!(
30-
Console::writer(),
31-
"RNG DRIVER DOESN'T EXIST\nERROR: {e:?}\n"
32-
)
33-
.unwrap();
27+
writeln!(Console::writer(), "RNG DRIVER ERROR: {e:?}").unwrap();
3428
return;
3529
}
3630

31+
let mut console_writer = Console::writer();
3732
let mut buffer: [u8; 32] = Default::default();
3833
let n: u32 = 32;
39-
let mut console_writer = Console::writer();
34+
4035
loop {
4136
match Rng::get_bytes_sync(&mut buffer, n) {
4237
Ok(()) => {
43-
write!(console_writer, "Randomness: {}\n", Randomness(&buffer)).unwrap();
38+
let _ = writeln!(console_writer, "Randomness: {}", Randomness(&buffer));
39+
}
40+
Err(e) => {
41+
let _ = writeln!(console_writer, "Error while getting bytes {e:?}");
4442
}
45-
Err(e) => writeln!(console_writer, "Error while getting bytes {e:?}\n").unwrap(),
4643
}
47-
Alarm::sleep_for(Milliseconds(2000)).unwrap();
44+
let _ = Alarm::sleep_for(Milliseconds(2000));
4845
}
4946
}

examples/rng_async.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use core::fmt::Write;
5+
use libtock::alarm::{Alarm, Milliseconds};
6+
use libtock::rng::RngListener;
7+
use libtock::{console::Console, rng::Rng};
8+
use libtock_platform::{share, Syscalls};
9+
use libtock_runtime::{set_main, stack_size, TockSyscalls};
10+
11+
stack_size! {0x300}
12+
set_main! {main}
13+
14+
fn main() {
15+
if let Err(e) = Rng::exists() {
16+
writeln!(Console::writer(), "RNG DRIVER ERROR: {e:?}").unwrap();
17+
return;
18+
}
19+
20+
let mut console_writer = Console::writer();
21+
let rng_listener = RngListener(|_| write!(Console::writer(), "Randomness: ").unwrap());
22+
let mut buffer: [u8; 32] = Default::default();
23+
let n: u32 = 32;
24+
25+
loop {
26+
share::scope(|allow_rw| {
27+
Rng::allow_buffer(&mut buffer, allow_rw).unwrap();
28+
29+
share::scope(|subscribe| {
30+
Rng::register_listener(&rng_listener, subscribe).unwrap();
31+
32+
Rng::get_bytes_async(n).unwrap();
33+
TockSyscalls::yield_wait();
34+
});
35+
});
36+
37+
buffer.iter().for_each(|&byte| {
38+
let _ = write!(console_writer, "{byte:02x}");
39+
});
40+
let _ = writeln!(console_writer, "");
41+
42+
let _ = Alarm::sleep_for(Milliseconds(2000));
43+
}
44+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub mod proximity {
7272
pub mod rng {
7373
use libtock_rng as rng;
7474
pub type Rng = rng::Rng<super::runtime::TockSyscalls>;
75+
pub use rng::RngListener;
7576
}
7677
pub mod sound_pressure {
7778
use libtock_sound_pressure as sound_pressure;

unittest/src/fake/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ mod leds;
2222
mod low_level_debug;
2323
mod ninedof;
2424
mod proximity;
25-
mod rng;
2625
mod sound_pressure;
2726
mod syscall_driver;
2827
mod syscalls;
@@ -41,7 +40,6 @@ pub use leds::Leds;
4140
pub use low_level_debug::{LowLevelDebug, Message};
4241
pub use ninedof::{NineDof, NineDofData};
4342
pub use proximity::Proximity;
44-
pub use rng::Rng;
4543
pub use sound_pressure::SoundPressure;
4644
pub use syscall_driver::SyscallDriver;
4745
pub use syscalls::Syscalls;

unittest/src/fake/rng/mod.rs

Lines changed: 0 additions & 83 deletions
This file was deleted.

unittest/src/fake/rng/tests.rs

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)