diff --git a/Cargo.toml b/Cargo.toml index aefbca93..ffbdf0ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ libtock_low_level_debug = { path = "apis/low_level_debug" } libtock_platform = { path = "platform" } libtock_runtime = { path = "runtime" } libtock_temperature = { path = "apis/temperature" } +libtock_humidity = { path = "apis/humidity" } [profile.dev] panic = "abort" @@ -38,6 +39,7 @@ members = [ "apis/gpio", "apis/buttons", "apis/console", + "apis/humidity", "apis/leds", "apis/low_level_debug", "apis/temperature", diff --git a/apis/humidity/Cargo.toml b/apis/humidity/Cargo.toml new file mode 100644 index 00000000..acf1ff14 --- /dev/null +++ b/apis/humidity/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "libtock_humidity" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libtock_platform = { path = "../../platform" } + +[dev-dependencies] +libtock_unittest = { path = "../../unittest" } \ No newline at end of file diff --git a/apis/humidity/src/lib.rs b/apis/humidity/src/lib.rs new file mode 100644 index 00000000..26eb1b35 --- /dev/null +++ b/apis/humidity/src/lib.rs @@ -0,0 +1,81 @@ +#![no_std] + +use core::cell::Cell; +use libtock_platform::{ + share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, +}; + +pub struct Humidity(S); + +impl Humidity { + /// Returns Ok() if the driver was present.This does not necessarily mean + /// that the driver is working. + pub fn exists() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() + } + + /// Initiate a humidity measurement. + /// + /// This function is used both for synchronous and asynchronous readings + pub fn read_humidity() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, READ_HUM, 0, 0).to_result() + } + + /// Register an events listener + pub fn register_listener<'share, F: Fn(i32)>( + listener: &'share HumidityListener, + subscribe: share::Handle>, + ) -> Result<(), ErrorCode> { + S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) + } + + /// Unregister the events listener + pub fn unregister_listener() { + S::unsubscribe(DRIVER_NUM, 0) + } + + /// Initiate a synchronous humidity measurement. + /// Returns Ok(humidity_value) if the operation was successful + /// humidity_value is returned in hundreds of centigrades + pub fn read_humidity_sync() -> Result { + let humidity_cell: Cell> = Cell::new(None); + let listener = HumidityListener(|hum_val| { + humidity_cell.set(Some(hum_val)); + }); + share::scope(|subscribe| { + if let Ok(()) = Self::register_listener(&listener, subscribe) { + if let Ok(()) = Self::read_humidity() { + while humidity_cell.get() == None { + S::yield_wait(); + } + } + } + }); + + match humidity_cell.get() { + None => Err(ErrorCode::Busy), + Some(hum_val) => Ok(hum_val), + } + } +} + +pub struct HumidityListener(pub F); +impl Upcall> for HumidityListener { + fn upcall(&self, hum_val: u32, _arg1: u32, _arg2: u32) { + self.0(hum_val as i32) + } +} + +#[cfg(test)] +mod tests; + +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x60001; + +// Command IDs + +const EXISTS: u32 = 0; +const READ_HUM: u32 = 1; diff --git a/apis/humidity/src/tests.rs b/apis/humidity/src/tests.rs new file mode 100644 index 00000000..f7af706e --- /dev/null +++ b/apis/humidity/src/tests.rs @@ -0,0 +1,81 @@ +use core::cell::Cell; +use libtock_platform::{share, ErrorCode, Syscalls, YieldNoWaitReturn}; +use libtock_unittest::fake; + +type Humidity = super::Humidity; + +#[test] +fn no_driver() { + let _kernel = fake::Kernel::new(); + assert_eq!(Humidity::exists(), Err(ErrorCode::NoDevice)); +} + +#[test] +fn driver_check() { + let kernel = fake::Kernel::new(); + let driver = fake::Humidity::new(); + kernel.add_driver(&driver); + + assert_eq!(Humidity::exists(), Ok(())); +} + +#[test] +fn read_humidity() { + let kernel = fake::Kernel::new(); + let driver = fake::Humidity::new(); + kernel.add_driver(&driver); + + assert_eq!(Humidity::read_humidity(), Ok(())); + assert!(driver.is_busy()); + + assert_eq!(Humidity::read_humidity(), Err(ErrorCode::Busy)); + assert_eq!(Humidity::read_humidity_sync(), Err(ErrorCode::Busy)); +} + +#[test] +fn register_unregister_listener() { + let kernel = fake::Kernel::new(); + let driver = fake::Humidity::new(); + kernel.add_driver(&driver); + + let humidity_cell: Cell> = Cell::new(None); + let listener = crate::HumidityListener(|hum_val| { + humidity_cell.set(Some(hum_val)); + }); + share::scope(|subscribe| { + assert_eq!(Humidity::read_humidity(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + + assert_eq!(Humidity::register_listener(&listener, subscribe), Ok(())); + assert_eq!(Humidity::read_humidity(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(humidity_cell.get(), Some(100)); + + Humidity::unregister_listener(); + assert_eq!(Humidity::read_humidity(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + }); +} + +#[test] +fn read_humidity_sync() { + let kernel = fake::Kernel::new(); + let driver = fake::Humidity::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(1000); + assert_eq!(Humidity::read_humidity_sync(), Ok(1000)); +} + +#[test] +fn negative_value() { + let kernel = fake::Kernel::new(); + let driver = fake::Humidity::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(-1000); + assert_eq!(Humidity::read_humidity_sync(), Ok(-1000)); +} diff --git a/examples/humidity.rs b/examples/humidity.rs new file mode 100644 index 00000000..138997a3 --- /dev/null +++ b/examples/humidity.rs @@ -0,0 +1,41 @@ +//! A simple libtock-rs example. Checks for humidity driver +//! and samples the sensor every 2 seconds. + +#![no_main] +#![no_std] + +use core::fmt::Write; +use libtock::console::Console; + +use libtock::alarm::{Alarm, Milliseconds}; +use libtock::humidity::Humidity; +use libtock::runtime::{set_main, stack_size}; + +set_main! {main} +stack_size! {0x200} + +fn main() { + match Humidity::exists() { + Ok(()) => writeln!(Console::writer(), "humidity driver available").unwrap(), + Err(_) => { + writeln!(Console::writer(), "humidity driver unavailable").unwrap(); + return; + } + } + + loop { + match Humidity::read_humidity_sync() { + Ok(hum_val) => writeln!( + Console::writer(), + "Humidity: {}{}.{}*C\n", + if hum_val > 0 { "" } else { "-" }, + i32::abs(hum_val) / 100, + i32::abs(hum_val) % 100 + ) + .unwrap(), + Err(_) => writeln!(Console::writer(), "error while reading humidity",).unwrap(), + } + + Alarm::sleep_for(Milliseconds(2000)).unwrap(); + } +} diff --git a/log.log b/log.log new file mode 100644 index 00000000..8de839cb --- /dev/null +++ b/log.log @@ -0,0 +1,969 @@ + Finished release [optimized + debuginfo] target(s) in 0.03s + Finished release [optimized + debuginfo] target(s) in 0.02s + Finished dev [unoptimized + debuginfo] target(s) in 0.05s + Checking libtock_platform v0.1.0 (/home/alex/myfork/libtock-rs/platform) + Compiling libtock_runtime v0.1.0 (/home/alex/myfork/libtock-rs/runtime) + Checking ufmt-write v0.1.0 (/home/alex/myfork/libtock-rs/ufmt/write) +error[E0463]: can't find crate for `core` + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `compiler_builtins` + +error[E0412]: cannot find type `Result` in this scope + --> ufmt/write/src/lib.rs:22:41 + | +22 | fn write_str(&mut self, s: &str) -> Result<(), Self::Error>; + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> ufmt/write/src/lib.rs:29:42 + | +29 | fn write_char(&mut self, c: char) -> Result<(), Self::Error> { + | ^^^^^^ not found in this scope + +error: requires `receiver` lang_item + --> ufmt/write/src/lib.rs:22:18 + | +22 | fn write_str(&mut self, s: &str) -> Result<(), Self::Error>; + | ^^^^^^^^^ + +error: requires `receiver` lang_item + --> ufmt/write/src/lib.rs:29:19 + | +29 | fn write_char(&mut self, c: char) -> Result<(), Self::Error> { + | ^^^^^^^^^ + +Some errors have detailed explanations: E0412, E0463. +For more information about an error, try `rustc --explain E0412`. +error: could not compile `ufmt-write` due to 6 previous errors +warning: build failed, waiting for other jobs to finish... +error[E0463]: can't find crate for `core` + --> platform/src/allow_ro.rs:3:5 + | +3 | use core::marker::PhantomData; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/allow_rw.rs:3:5 + | +3 | use core::marker::PhantomData; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/share/handle.rs:2:5 + | +2 | use core::marker::PhantomData; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/command_return.rs:3:5 + | +3 | use core::mem::transmute; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/error_code.rs:1:5 + | +1 | use core::{convert::TryFrom, fmt, mem::transmute}; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error: cannot find attribute `derive` in this scope + --> platform/src/command_return.rs:62:3 + | +62 | #[derive(Clone, Copy, Debug)] + | ^^^^^^ + +error: cannot find attribute `derive` in this scope + --> platform/src/error_code.rs:9:3 + | +9 | #[derive(Clone, Copy, PartialEq, Eq)] + | ^^^^^^ + +error: cannot find attribute `derive` in this scope + --> platform/src/error_code.rs:240:3 + | +240 | #[derive(PartialEq, Eq, Debug)] + | ^^^^^^ + +error: cannot find macro `write` in this scope + --> platform/src/error_code.rs:269:24 + | +269 | Some(s) => write!(f, "{}", s), + | ^^^^^ + +error: cannot find macro `write` in this scope + --> platform/src/error_code.rs:270:21 + | +270 | None => write!(f, "code {}", *self as u16), + | ^^^^^ + +error: cannot find attribute `derive` in this scope + --> platform/src/register.rs:9:3 + | +9 | #[derive(Clone, Copy, Debug)] + | ^^^^^^ + +error: cannot find attribute `derive` in this scope + --> platform/src/return_variant.rs:8:3 + | +8 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] + | ^^^^^^ + +error: cannot find attribute `derive` in this scope + --> platform/src/yield_types.rs:10:3 + | +10 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] + | ^^^^^^ + +error[E0463]: can't find crate for `core` + --> platform/src/allow_ro.rs:31:25 + | +31 | _share: PhantomData>, + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/allow_rw.rs:31:25 + | +31 | _share: PhantomData>, + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/exit_on_drop.rs:15:43 + | +15 | pub struct ExitOnDrop(core::marker::PhantomData); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/exit_on_drop.rs:19:20 + | +19 | ExitOnDrop(core::marker::PhantomData) + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/register.rs:92:18 + | +92 | type Error = core::num::TryFromIntError; + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/register.rs:94:52 + | +94 | fn try_from(register: Register) -> Result { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:13:16 + | +13 | _syscalls: core::marker::PhantomData, + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:25:13 + | +25 | _scope: core::marker::PhantomData>, + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:25:39 + | +25 | _scope: core::marker::PhantomData>, + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:90:24 + | +90 | impl Upcall for core::cell::Cell { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:99:24 + | +99 | impl Upcall for core::cell::Cell> { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:106:24 + | +106 | impl Upcall for core::cell::Cell> { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:113:24 + | +113 | impl Upcall for core::cell::Cell> { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/subscribe.rs:120:24 + | +120 | impl Upcall for core::cell::Cell> { + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:15:24 + | +15 | let mut flag = core::mem::MaybeUninit::::uninit(); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:65:13 + | +65 | core::mem::forget(exit); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:121:37 + | +121 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:234:37 + | +234 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:321:37 + | +321 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:370:13 + | +370 | core::hint::unreachable_unchecked() + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0463]: can't find crate for `core` + --> platform/src/syscalls_impl.rs:382:13 + | +382 | core::hint::unreachable_unchecked() + | ^^^^ can't find crate + | + = note: the `thumbv7em-none-eabi` target may not be installed + = help: consider downloading the target with `rustup target add thumbv7em-none-eabi` + +error[E0405]: cannot find trait `Default` in this scope + --> platform/src/allow_ro.rs:37:73 + | +37 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const BUFFER_NUM: u32> Default + | ^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Drop` in this scope + --> platform/src/allow_ro.rs:48:73 + | +48 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const BUFFER_NUM: u32> Drop + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `Default` in this scope + --> platform/src/allow_rw.rs:37:73 + | +37 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const BUFFER_NUM: u32> Default + | ^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Drop` in this scope + --> platform/src/allow_rw.rs:48:73 + | +48 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const BUFFER_NUM: u32> Drop + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:138:34 + | +138 | pub fn get_failure(&self) -> Option { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:140:20 + | +140 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:147:38 + | +147 | pub fn get_failure_u32(&self) -> Option<(ErrorCode, u32)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:149:20 + | +149 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:156:40 + | +156 | pub fn get_failure_2_u32(&self) -> Option<(ErrorCode, u32, u32)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:158:20 + | +158 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:165:38 + | +165 | pub fn get_failure_u64(&self) -> Option<(ErrorCode, u64)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:167:20 + | +167 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:176:38 + | +176 | pub fn get_success_u32(&self) -> Option { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:178:20 + | +178 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:184:40 + | +184 | pub fn get_success_2_u32(&self) -> Option<(u32, u32)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:186:20 + | +186 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:192:38 + | +192 | pub fn get_success_u64(&self) -> Option { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:194:20 + | +194 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:200:40 + | +200 | pub fn get_success_3_u32(&self) -> Option<(u32, u32, u32)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:202:20 + | +202 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/command_return.rs:209:42 + | +209 | pub fn get_success_u32_u64(&self) -> Option<(u32, u64)> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/command_return.rs:211:20 + | +211 | return None; + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/command_return.rs:235:37 + | +235 | pub fn to_result(self) -> Result + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/error_code.rs:245:24 + | +245 | fn as_str(self) -> Option<&'static str> { + | ^^^^^^ not found in this scope + +error[E0425]: cannot find value `None` in this scope + --> platform/src/error_code.rs:261:18 + | +261 | _ => None, + | ^^^^ not found in this scope + +error[E0531]: cannot find tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:269:13 + | +269 | Some(s) => write!(f, "{}", s), + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/error_code.rs:278:32 + | +278 | fn try_from(value: u32) -> Result { + | ^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Default` in this scope + --> platform/src/exit_on_drop.rs:17:26 + | +17 | impl Default for ExitOnDrop { + | ^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Drop` in this scope + --> platform/src/exit_on_drop.rs:23:26 + | +23 | impl Drop for ExitOnDrop { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `Sized` in this scope + --> platform/src/raw_syscalls.rs:66:31 + | +66 | pub unsafe trait RawSyscalls: Sized { + | ^^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:17:6 + | +17 | impl From for Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:23:6 + | +23 | impl From for Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:29:6 + | +29 | impl From for Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:35:9 + | +35 | impl From<*mut T> for Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:41:9 + | +41 | impl From<*const T> for Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:66:6 + | +66 | impl From for usize { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:72:9 + | +72 | impl From for *mut T { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/register.rs:78:9 + | +78 | impl From for *const T { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `TryFrom` in this scope + --> platform/src/register.rs:91:6 + | +91 | impl TryFrom for u32 { + | ^^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/register.rs:94:40 + | +94 | fn try_from(register: Register) -> Result { + | ^^^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/return_variant.rs:11:6 + | +11 | impl From for ReturnVariant { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/return_variant.rs:17:6 + | +17 | impl From for crate::Register { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `From` in this scope + --> platform/src/return_variant.rs:23:6 + | +23 | impl From for u32 { + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `Clone` in this scope + --> platform/src/share/handle.rs:25:24 + | +25 | impl<'handle, L: List> Clone for Handle<'handle, L> { + | ^^^^^ not found in this scope + +error[E0405]: cannot find trait `Copy` in this scope + --> platform/src/share/handle.rs:31:24 + | +31 | impl<'handle, L: List> Copy for Handle<'handle, L> {} + | ^^^^ not found in this scope + +error[E0405]: cannot find trait `FnOnce` in this scope + --> platform/src/share/mod.rs:10:34 + | +10 | pub fn scope) -> Output>(fcn: F) -> Output { + | ^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Default` in this scope + --> platform/src/share/mod.rs:21:17 + | +21 | pub trait List: Default {} + | ^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Default` in this scope + --> platform/src/subscribe.rs:31:76 + | +31 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const SUBSCRIBE_NUM: u32> Default + | ^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Drop` in this scope + --> platform/src/subscribe.rs:42:76 + | +42 | impl<'share, S: Syscalls, const DRIVER_NUM: u32, const SUBSCRIBE_NUM: u32> Drop + | ^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/subscribe.rs:99:41 + | +99 | impl Upcall for core::cell::Cell> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/subscribe.rs:106:41 + | +106 | impl Upcall for core::cell::Cell> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/subscribe.rs:113:41 + | +113 | impl Upcall for core::cell::Cell> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Option` in this scope + --> platform/src/subscribe.rs:120:41 + | +120 | impl Upcall for core::cell::Cell> { + | ^^^^^^ not found in this scope + +error[E0405]: cannot find trait `Sized` in this scope + --> platform/src/syscalls.rs:9:35 + | +9 | pub trait Syscalls: RawSyscalls + Sized { + | ^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls.rs:38:10 + | +38 | ) -> Result<(), ErrorCode>; + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls.rs:58:10 + | +58 | ) -> Result<(), ErrorCode>; + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls.rs:73:10 + | +73 | ) -> Result<(), ErrorCode>; + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:52:10 + | +52 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:81:14 + | +81 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:191:10 + | +191 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:201:14 + | +201 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:275:10 + | +275 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/syscalls_impl.rs:288:14 + | +288 | ) -> Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0412]: cannot find type `Result` in this scope + --> platform/src/termination.rs:16:22 + | +16 | impl Termination for Result<(), ErrorCode> { + | ^^^^^^ not found in this scope + +error[E0531]: cannot find tuple struct or tuple variant `Ok` in this scope + --> platform/src/termination.rs:19:13 + | +19 | Ok(()) => 0, + | ^^ not found in this scope + +error[E0531]: cannot find tuple struct or tuple variant `Err` in this scope + --> platform/src/termination.rs:20:13 + | +20 | Err(ec) => ec as u32, + | ^^^ not found in this scope + +error[E0433]: failed to resolve: use of undeclared type `Default` + --> platform/src/share/mod.rs:11:16 + | +11 | let list = Default::default(); + | ^^^^^^^ use of undeclared type `Default` + +error[E0433]: failed to resolve: use of undeclared type `Default` + --> platform/src/subscribe.rs:36:24 + | +36 | _syscalls: Default::default(), + | ^^^^^^^ use of undeclared type `Default` + +error[E0433]: failed to resolve: use of undeclared type `Default` + --> platform/src/subscribe.rs:37:21 + | +37 | _scope: Default::default(), + | ^^^^^^^ use of undeclared type `Default` + +error[E0433]: failed to resolve: use of undeclared type `Default` + --> platform/src/syscalls_impl.rs:62:53 + | +62 | let exit: exit_on_drop::ExitOnDrop = Default::default(); + | ^^^^^^^ use of undeclared type `Default` + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:142:9 + | +142 | Some(unsafe { transmute(self.r1) }) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:151:9 + | +151 | Some((unsafe { transmute(self.r1) }, self.r2)) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:160:9 + | +160 | Some((unsafe { transmute(self.r1) }, self.r2, self.r3)) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:169:9 + | +169 | Some(( + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:180:9 + | +180 | Some(self.r1) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:188:9 + | +188 | Some((self.r1, self.r2)) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:196:9 + | +196 | Some(self.r1 as u64 + ((self.r2 as u64) << 32)) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:204:9 + | +204 | Some((self.r1, self.r2, self.r3)) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/command_return.rs:213:9 + | +213 | Some((self.r1, self.r2 as u64 + ((self.r3 as u64) << 32))) + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope + --> platform/src/command_return.rs:242:20 + | +242 | return Ok(T::from_raw_values(r1, r2, r3)); + | ^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Err` in this scope + --> platform/src/command_return.rs:253:9 + | +253 | Err(E::from_raw_values(ec, r2, r3)) + | ^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:247:27 + | +247 | Self::Fail => Some("FAIL"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:248:27 + | +248 | Self::Busy => Some("BUSY"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:249:30 + | +249 | Self::Already => Some("ALREADY"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:250:26 + | +250 | Self::Off => Some("OFF"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:251:30 + | +251 | Self::Reserve => Some("RESERVE"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:252:30 + | +252 | Self::Invalid => Some("INVALID"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:253:27 + | +253 | Self::Size => Some("SIZE"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:254:29 + | +254 | Self::Cancel => Some("CANCEL"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:255:28 + | +255 | Self::NoMem => Some("NOMEM"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:256:32 + | +256 | Self::NoSupport => Some("NOSUPPORT"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:257:31 + | +257 | Self::NoDevice => Some("NODEVICE"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:258:34 + | +258 | Self::Uninstalled => Some("UNINSTALLED"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:259:28 + | +259 | Self::NoAck => Some("NOACK"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/error_code.rs:260:30 + | +260 | Self::BadRVal => Some("BADRVAL"), + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope + --> platform/src/error_code.rs:280:13 + | +280 | Ok(unsafe { transmute(value) }) + | ^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Err` in this scope + --> platform/src/error_code.rs:282:13 + | +282 | Err(NotAnErrorCode) + | ^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/subscribe.rs:101:18 + | +101 | self.set(Some(())); + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/subscribe.rs:108:18 + | +108 | self.set(Some((arg0,))); + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/subscribe.rs:115:18 + | +115 | self.set(Some((arg0, arg1))); + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope + --> platform/src/subscribe.rs:122:18 + | +122 | self.set(Some((arg0, arg1, arg2))); + | ^^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Err` in this scope + --> platform/src/syscalls_impl.rs:121:24 + | +121 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope + --> platform/src/syscalls_impl.rs:134:13 + | +134 | Ok(()) + | ^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Err` in this scope + --> platform/src/syscalls_impl.rs:234:24 + | +234 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope + --> platform/src/syscalls_impl.rs:245:13 + | +245 | Ok(()) + | ^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Err` in this scope + --> platform/src/syscalls_impl.rs:321:24 + | +321 | return Err(unsafe { core::mem::transmute(r1.as_u32()) }); + | ^^^ not found in this scope + +error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope + --> platform/src/syscalls_impl.rs:332:13 + | +332 | Ok(()) + | ^^ not found in this scope + +Some errors have detailed explanations: E0405, E0412, E0425, E0433, E0463, E0531. +For more information about an error, try `rustc --explain E0405`. +error: could not compile `libtock_platform` due to 143 previous errors +make: *** [Makefile:112: test-stable] Error 101 diff --git a/src/lib.rs b/src/lib.rs index c13b39db..e0745aea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,12 @@ pub mod gpio { PullDown, PullNone, PullUp, }; } + +pub mod humidity { + use libtock_humidity as humidity; + pub type Humidity = humidity::Humidity; +} + pub mod leds { use libtock_leds as leds; pub type Leds = leds::Leds; diff --git a/unittest/src/fake/humidity/mod.rs b/unittest/src/fake/humidity/mod.rs new file mode 100644 index 00000000..d5110935 --- /dev/null +++ b/unittest/src/fake/humidity/mod.rs @@ -0,0 +1,85 @@ +//! Fake implementation of the Humidity API, documented here: +//! https://github.com/tock/tock/blob/master/doc/syscalls/60000_ambient_humidity.md +//! +//! Like the real API, `Humidity` controls a fake humidity sensor. It provides +//! a function `set_value` used to immediately call an upcall with a humidity value read by the sensor +//! and a function 'set_value_sync' used to call the upcall when the read command is received. + +use crate::{DriverInfo, DriverShareRef}; +use libtock_platform::{CommandReturn, ErrorCode}; +use std::cell::Cell; + +// The `upcall_on_command` field is set to Some(value) if an upcall(with value as its argument) should be called when read command is received, +// or None otherwise. It was needed for testing `read_sync` library function which simulates a synchronous humidity read, +// because it was impossible to schedule an upcall during the `synchronous` read in other ways. +pub struct Humidity { + busy: Cell, + upcall_on_command: Cell>, + share_ref: DriverShareRef, +} + +impl Humidity { + pub fn new() -> std::rc::Rc { + std::rc::Rc::new(Humidity { + busy: Cell::new(false), + upcall_on_command: Cell::new(None), + share_ref: Default::default(), + }) + } + + pub fn is_busy(&self) -> bool { + self.busy.get() + } + pub fn set_value(&self, value: i32) { + if self.busy.get() { + self.share_ref + .schedule_upcall(0, (value as u32, 0, 0)) + .expect("Unable to schedule upcall"); + self.busy.set(false); + } + } + pub fn set_value_sync(&self, value: i32) { + self.upcall_on_command.set(Some(value)); + } +} + +impl crate::fake::SyscallDriver for Humidity { + fn info(&self) -> DriverInfo { + DriverInfo::new(DRIVER_NUM).upcall_count(1) + } + + fn register(&self, share_ref: DriverShareRef) { + self.share_ref.replace(share_ref); + } + + fn command(&self, command_id: u32, _argument0: u32, _argument1: u32) -> CommandReturn { + match command_id { + EXISTS => crate::command_return::success(), + + READ_HUM => { + if self.busy.get() { + return crate::command_return::failure(ErrorCode::Busy); + } + self.busy.set(true); + if let Some(val) = self.upcall_on_command.take() { + self.set_value(val); + } + crate::command_return::success() + } + _ => crate::command_return::failure(ErrorCode::NoSupport), + } + } +} + +#[cfg(test)] +mod tests; +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x60001; + +// Command IDs + +const EXISTS: u32 = 0; +const READ_HUM: u32 = 1; diff --git a/unittest/src/fake/humidity/tests.rs b/unittest/src/fake/humidity/tests.rs new file mode 100644 index 00000000..31501537 --- /dev/null +++ b/unittest/src/fake/humidity/tests.rs @@ -0,0 +1,67 @@ +use crate::fake::{self, SyscallDriver}; +use fake::humidity::*; +use libtock_platform::{share, DefaultConfig, YieldNoWaitReturn}; + +//Test the command implementation +#[test] +fn command() { + let hum = Humidity::new(); + + assert!(hum.command(EXISTS, 1, 2).is_success()); + + assert!(hum.command(READ_HUM, 0, 0).is_success()); + + assert_eq!( + hum.command(READ_HUM, 0, 0).get_failure(), + Some(ErrorCode::Busy) + ); + + hum.set_value(100); + assert!(hum.command(READ_HUM, 0, 1).is_success()); + hum.set_value(100); + + hum.set_value_sync(100); + assert!(hum.command(READ_HUM, 0, 1).is_success()); + assert!(hum.command(READ_HUM, 0, 1).is_success()); +} + +// Integration test that verifies Humidity works with fake::Kernel and +// libtock_platform::Syscalls. +#[test] +fn kernel_integration() { + use libtock_platform::Syscalls; + let kernel = fake::Kernel::new(); + let hum = Humidity::new(); + kernel.add_driver(&hum); + assert!(fake::Syscalls::command(DRIVER_NUM, EXISTS, 1, 2).is_success()); + assert!(fake::Syscalls::command(DRIVER_NUM, READ_HUM, 0, 0).is_success()); + assert_eq!( + fake::Syscalls::command(DRIVER_NUM, READ_HUM, 0, 0).get_failure(), + Some(ErrorCode::Busy) + ); + hum.set_value(100); + assert!(fake::Syscalls::command(DRIVER_NUM, READ_HUM, 0, 1).is_success()); + + let listener = Cell::>::new(None); + share::scope(|subscribe| { + assert_eq!( + fake::Syscalls::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, &listener), + Ok(()) + ); + + hum.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(listener.get(), Some((100,))); + + hum.set_value(200); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + + assert!(fake::Syscalls::command(DRIVER_NUM, READ_HUM, 0, 1).is_success()); + hum.set_value(200); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + + hum.set_value_sync(200); + assert!(fake::Syscalls::command(DRIVER_NUM, READ_HUM, 0, 1).is_success()); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + }); +} diff --git a/unittest/src/fake/mod.rs b/unittest/src/fake/mod.rs index bf29e4ff..156616f5 100644 --- a/unittest/src/fake/mod.rs +++ b/unittest/src/fake/mod.rs @@ -13,6 +13,7 @@ mod alarm; mod buttons; mod console; mod gpio; +mod humidity; mod kernel; mod leds; mod low_level_debug; @@ -24,6 +25,7 @@ pub use alarm::Alarm; pub use buttons::Buttons; pub use console::Console; pub use gpio::{Gpio, GpioMode, InterruptEdge, PullMode}; +pub use humidity::Humidity; pub use kernel::Kernel; pub use leds::Leds; pub use low_level_debug::{LowLevelDebug, Message};