Enable clippy and fix lints
diff --git a/.travis.yml b/.travis.yml index 69d3a37..0bcbb0c 100644 --- a/.travis.yml +++ b/.travis.yml
@@ -19,8 +19,10 @@ - rustup target add thumbv7em-none-eabi - rustup target add riscv32imc-unknown-none-elf - rustup component add rustfmt-preview + - rustup component add clippy script: - cargo fmt --all -- --check - cargo test --workspace + - cargo clippy --workspace --all-targets - ./build_examples.sh
diff --git a/.vscode/settings.json b/.vscode/settings.json index d14867b..8bbc33e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json
@@ -1,4 +1,5 @@ { - "editor.formatOnSave": true, - "rust.all_targets": true, -} \ No newline at end of file + "editor.formatOnSave": true, + "rust.all_targets": true, + "rust.clippy_preference": "on" +}
diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index c97ae32..6f51b9f 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs
@@ -9,6 +9,7 @@ use syn::Error; use syn::ItemFn; +#[allow(clippy::needless_doctest_main)] /// Procedural attribute macro. This is meant to be applied to a binary's async /// `main()`, transforming into a function that returns a type acceptable for /// `main()`. In other words, this will not compile with libtock-rs: @@ -30,7 +31,7 @@ } fn generate_main_wrapped(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { - try_generate_main_wrapped(input).unwrap_or_else(|err| err.to_compile_error().into()) + try_generate_main_wrapped(input).unwrap_or_else(|err| err.to_compile_error()) } fn try_generate_main_wrapped( @@ -63,11 +64,8 @@ async fn main() -> ::libtock::result::TockResult<()>{ method_call().await; } - } - .into(); - let actual: ItemFn = syn::parse2::<ItemFn>(generate_main_wrapped(method_def.into())) - .unwrap() - .into(); + }; + let actual: ItemFn = syn::parse2::<ItemFn>(generate_main_wrapped(method_def)).unwrap(); let expected: ItemFn = syn::parse2::<ItemFn>(quote!( fn main() -> ::libtock::result::TockResult<()> { static mut MAIN_INVOKED: bool = false; @@ -83,8 +81,7 @@ unsafe { ::core::executor::block_on(_block) } } )) - .unwrap() - .into(); + .unwrap(); assert_eq!(actual, expected); } }
diff --git a/examples/adc.rs b/examples/adc.rs index 2ed3b88..61894ad 100644 --- a/examples/adc.rs +++ b/examples/adc.rs
@@ -13,7 +13,7 @@ let mut driver = context.create_timer_driver()?; let timer_driver = driver.activate()?; - let mut console = Console::new(); + let mut console = Console::default(); let mut with_callback = adc::with_callback(|channel: usize, value: usize| { writeln!(console, "channel: {}, value: {}", channel, value).unwrap(); });
diff --git a/examples/adc_buffer.rs b/examples/adc_buffer.rs index b1d8fe0..406bf57 100644 --- a/examples/adc_buffer.rs +++ b/examples/adc_buffer.rs
@@ -10,8 +10,8 @@ #[libtock::main] /// Reads a 128 byte sample into a buffer and prints the first value to the console. async fn main() -> TockResult<()> { - let mut console = Console::new(); - let mut adc_buffer = AdcBuffer::new(); + let mut console = Console::default(); + let mut adc_buffer = AdcBuffer::default(); let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE]; let adc_buffer = libtock::adc::Adc::init_buffer(&mut adc_buffer)?;
diff --git a/examples/button_read.rs b/examples/button_read.rs index 74d1479..d86e70d 100644 --- a/examples/button_read.rs +++ b/examples/button_read.rs
@@ -10,7 +10,7 @@ #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let mut with_callback = buttons::with_callback(|_, _| {}); let mut buttons = with_callback.init()?; let mut button = buttons.iter_mut().next().unwrap();
diff --git a/examples/button_subscribe.rs b/examples/button_subscribe.rs index 8ea4fac..3453c9b 100644 --- a/examples/button_subscribe.rs +++ b/examples/button_subscribe.rs
@@ -10,7 +10,7 @@ // FIXME: Hangs up when buttons are pressed rapidly. Yielding in callback leads to stack overflow. #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let mut with_callback = buttons::with_callback(|button_num: usize, state| { writeln!(
diff --git a/examples/gpio_read.rs b/examples/gpio_read.rs index cb3dc22..ad871ac 100644 --- a/examples/gpio_read.rs +++ b/examples/gpio_read.rs
@@ -11,7 +11,7 @@ // example works on p0.03 #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let pin = GpioPinUnitialized::new(0); let pin = pin.open_for_read(None, InputMode::PullDown)?; let context = timer::DriverContext::create()?;
diff --git a/examples/hardware_test.rs b/examples/hardware_test.rs index 8a4689b..4f8ad5f 100644 --- a/examples/hardware_test.rs +++ b/examples/hardware_test.rs
@@ -21,20 +21,20 @@ impl MyTrait for usize { fn do_something_with_a_console(&self, console: &mut Console) { - write!(console, "trait_obj_value_usize = {}\n", &self).unwrap(); + writeln!(console, "trait_obj_value_usize = {}", &self).unwrap(); } } impl MyTrait for String { fn do_something_with_a_console(&self, console: &mut Console) { - write!(console, "trait_obj_value_string = {}\n", &self).unwrap(); + writeln!(console, "trait_obj_value_string = {}", &self).unwrap(); } } #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); - write!(console, "[test-results]\n")?; + let mut console = Console::default(); + writeln!(console, "[test-results]")?; test_heap(&mut console); test_formatting(&mut console); @@ -49,12 +49,12 @@ fn test_heap(console: &mut Console) { let mut string = String::from("heap_test = \"Heap "); - string.push_str("works.\"\n"); - write!(console, "{}", string).unwrap(); + string.push_str("works.\""); + writeln!(console, "{}", string).unwrap(); } fn test_formatting(console: &mut Console) { - write!(console, "formatting = {}\n", String::from("works")).unwrap(); + writeln!(console, "formatting = {}", String::from("works")).unwrap(); } /// needs P0.03 and P0.04 to be connected @@ -91,7 +91,7 @@ fn test_static_mut(console: &mut Console) { increment_static_mut(); - write!(console, "should_be_one = {}\n", unsafe { STATIC }).unwrap(); + writeln!(console, "should_be_one = {}", unsafe { STATIC }).unwrap(); } /// needs P0.03 and P0.04 to be connected @@ -106,13 +106,13 @@ let pin_out = pin_out.open_for_write().ok().unwrap(); pin_out.set_high().ok().unwrap(); - write!(console, "gpio_works = {}\n", pin_in.read()).unwrap(); + writeln!(console, "gpio_works = {}", pin_in.read()).unwrap(); } async fn test_callbacks_and_wait_forever(console: &mut Console) -> TockResult<()> { let mut with_callback = timer::with_callback(|_, _| { - write!(console, "callbacks_work = true\n").unwrap(); - write!(console, "all_tests_run = true").unwrap(); + writeln!(console, "callbacks_work = true").unwrap(); + writeln!(console, "all_tests_run = true").unwrap(); }); let mut timer = with_callback.init()?;
diff --git a/examples/hello.rs b/examples/hello.rs index 989a572..5e4f987 100644 --- a/examples/hello.rs +++ b/examples/hello.rs
@@ -8,7 +8,7 @@ #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let context = timer::DriverContext::create()?; let mut driver = context.create_timer_driver()?; let timer_driver = driver.activate()?;
diff --git a/examples/sensors.rs b/examples/sensors.rs index 1dd373b..9936d31 100644 --- a/examples/sensors.rs +++ b/examples/sensors.rs
@@ -3,17 +3,18 @@ use core::fmt::Write; use libtock::console::Console; use libtock::result::TockResult; +use libtock::sensors::Ninedof; use libtock::sensors::*; use libtock::timer; use libtock::timer::Duration; #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let mut humidity = HumiditySensor; let mut temperature = TemperatureSensor; let mut light = AmbientLightSensor; - let mut ninedof = unsafe { Ninedof::new() }; + let mut ninedof = Ninedof::default(); let context = timer::DriverContext::create()?; let mut driver = context.create_timer_driver()?; let timer_driver = driver.activate()?;
diff --git a/examples/simple_ble.rs b/examples/simple_ble.rs index a4bee5a..97511a0 100644 --- a/examples/simple_ble.rs +++ b/examples/simple_ble.rs
@@ -24,7 +24,7 @@ let payload = corepack::to_bytes(LedCommand { nr: 2, st: true }).unwrap(); let mut buffer = BleAdvertisingDriver::create_advertising_buffer(); - let mut gap_payload = BlePayload::new(); + let mut gap_payload = BlePayload::default(); gap_payload .add_flag(ble_composer::flags::LE_GENERAL_DISCOVERABLE) .unwrap(); @@ -34,10 +34,7 @@ .unwrap(); gap_payload - .add( - ble_composer::gap_types::COMPLETE_LOCAL_NAME, - "Tock!".as_bytes(), - ) + .add(ble_composer::gap_types::COMPLETE_LOCAL_NAME, b"Tock!") .unwrap(); gap_payload.add_service_payload([91, 79], &payload).unwrap();
diff --git a/examples/temperature.rs b/examples/temperature.rs index 8bce671..8a3eef0 100644 --- a/examples/temperature.rs +++ b/examples/temperature.rs
@@ -7,7 +7,7 @@ #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let temperature = temperature::measure_temperature().await?; writeln!(console, "Temperature: {}", temperature).map_err(Into::into) }
diff --git a/examples/timer_subscribe.rs b/examples/timer_subscribe.rs index c61c759..11afdfd 100644 --- a/examples/timer_subscribe.rs +++ b/examples/timer_subscribe.rs
@@ -9,7 +9,7 @@ #[libtock::main] async fn main() -> TockResult<()> { - let mut console = Console::new(); + let mut console = Console::default(); let mut with_callback = timer::with_callback(|_, _| { writeln!(
diff --git a/src/adc.rs b/src/adc.rs index e01b6ca..ecb18df 100644 --- a/src/adc.rs +++ b/src/adc.rs
@@ -29,8 +29,8 @@ buffer: [u8; BUFFER_SIZE], } -impl AdcBuffer { - pub fn new() -> AdcBuffer { +impl Default for AdcBuffer { + fn default() -> Self { AdcBuffer { buffer: [0; BUFFER_SIZE], }
diff --git a/src/ble_composer.rs b/src/ble_composer.rs index 1701ec5..0bb96d8 100644 --- a/src/ble_composer.rs +++ b/src/ble_composer.rs
@@ -36,13 +36,6 @@ Ok(()) } - pub fn new() -> Self { - BlePayload { - bytes: [0; 39], - occupied: 0, - } - } - pub fn add_service_payload(&mut self, uuid: [u8; 2], content: &[u8]) -> Result<(), ()> { self.check_can_write_num_bytes(4 + content.len())?; self.bytes[self.occupied] = (content.len() + 3) as u8; @@ -65,6 +58,14 @@ } } +impl Default for BlePayload { + fn default() -> Self { + BlePayload { + bytes: [0; 39], + occupied: 0, + } + } +} impl AsRef<[u8]> for BlePayload { fn as_ref(&self) -> &[u8] { &self.bytes[0..self.occupied] @@ -77,7 +78,7 @@ #[test] fn test_add() { - let mut pld = BlePayload::new(); + let mut pld = BlePayload::default(); pld.add(1, &[2]).unwrap(); assert_eq!(pld.as_ref().len(), 3); assert_eq!(pld.as_ref(), &mut [2, 1, 2]) @@ -85,14 +86,14 @@ #[test] fn test_add_service_payload() { - let mut pld = BlePayload::new(); + let mut pld = BlePayload::default(); pld.add_service_payload([1, 2], &[2]).unwrap(); assert_eq!(pld.as_ref(), &[4, 0x16, 1, 2, 2]) } #[test] fn test_add_service_payload_two_times() { - let mut pld = BlePayload::new(); + let mut pld = BlePayload::default(); pld.add_service_payload([1, 2], &[2]).unwrap(); pld.add_service_payload([1, 2], &[2, 3]).unwrap(); @@ -101,13 +102,13 @@ #[test] fn big_data_causes_error() { - let mut pld = BlePayload::new(); + let mut pld = BlePayload::default(); assert!(pld.add_service_payload([1, 2], &[0; 36]).is_err()); } #[test] fn initial_size_is_zero() { - let pld = BlePayload::new(); + let pld = BlePayload::default(); assert_eq!(pld.as_ref().len(), 0); } }
diff --git a/src/console.rs b/src/console.rs index 3fd0361..bfcd6d7 100644 --- a/src/console.rs +++ b/src/console.rs
@@ -25,12 +25,6 @@ } impl Console { - pub fn new() -> Console { - Console { - allow_buffer: [0; 64], - } - } - pub fn write<S: AsRef<[u8]>>(&mut self, text: S) -> TockResult<()> { let mut not_written_yet = text.as_ref(); while !not_written_yet.is_empty() { @@ -69,6 +63,14 @@ } } +impl Default for Console { + fn default() -> Self { + Console { + allow_buffer: [0; 64], + } + } +} + impl fmt::Write for Console { fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> { self.write(string).map_err(|_| fmt::Error)
diff --git a/src/debug/mod.rs b/src/debug/mod.rs index a64b664..f67ae9b 100644 --- a/src/debug/mod.rs +++ b/src/debug/mod.rs
@@ -7,13 +7,15 @@ pub fn println() { let buffer = [b'\n']; - let _ = Console::new().write(&buffer); + let mut console = Console::default(); + let _ = console.write(&buffer); } pub fn print_as_hex(value: usize) { let mut buffer = [b'\n'; 11]; write_as_hex(&mut buffer, value); - let _ = Console::new().write(buffer); + let mut console = Console::default(); + let _ = console.write(buffer); } #[cfg(target_arch = "arm")] @@ -24,34 +26,42 @@ let mut buffer = [b'\n'; 15]; buffer[0..4].clone_from_slice(b"SP: "); write_as_hex(&mut buffer[4..15], stack_pointer); - let _ = Console::new().write(buffer); + let mut console = Console::default(); + let _ = console.write(buffer); } #[cfg(target_arch = "riscv32")] pub fn print_stack_pointer() {} -#[inline(always)] // Initial stack size is too small (128 bytes currently) -pub fn dump_address(address: *const usize) { +#[inline(always)] +/// Dumps address +/// # Safety +/// dereferences pointer without check - may lead to access violation. +pub unsafe fn dump_address(address: *const usize) { let mut buffer = [b' '; 28]; write_as_hex(&mut buffer[0..10], address as usize); buffer[10] = b':'; - write_as_hex(&mut buffer[12..22], unsafe { *address }); + write_as_hex(&mut buffer[12..22], *address); for index in 0..4 { - let byte = unsafe { *(address as *const u8).offset(index) }; + let byte = *(address as *const u8).offset(index); let byte_is_printable_char = byte >= 0x20 && byte < 0x80; if byte_is_printable_char { buffer[23 + index as usize] = byte; } } buffer[27] = b'\n'; - let _ = Console::new().write(&buffer); + let mut console = Console::default(); + let _ = console.write(&buffer); } -pub fn dump_memory(start_address: *const usize, count: isize) { +/// Dumps arbitrary memory regions. +/// # Safety +/// dereferences pointer without check - may lead to access violation. +pub unsafe fn dump_memory(start_address: *const usize, count: isize) { let range = if count < 0 { count..0 } else { 0..count }; for offset in range { - dump_address(unsafe { start_address.offset(offset) }); + dump_address(start_address.offset(offset)); } }
diff --git a/src/memop.rs b/src/memop.rs index eaccb18..064841c 100644 --- a/src/memop.rs +++ b/src/memop.rs
@@ -3,16 +3,19 @@ use crate::syscalls; use core::slice; -// Setting the break is marked as unsafe as it should only be called by the entry point to setup -// the allocator. Updating the break afterwards can lead to allocated memory becoming unaccessible. -// -// Alternate allocator implementations may still find this useful in the future. +/// Set the memory break +/// # Safety +/// Setting the break is marked as unsafe as it should only be called by the entry point to setup +/// the allocator. Updating the break afterwards can lead to allocated memory becoming unaccessible. +/// +/// Alternate allocator implementations may still find this useful in the future. pub unsafe fn set_brk(ptr: *const u8) -> bool { syscalls::raw::memop(0, ptr as usize) == 0 } -pub unsafe fn increment_brk(increment: usize) -> Option<*const u8> { - let result = syscalls::raw::memop(1, increment); +/// Increment the memory break +pub fn increment_brk(increment: usize) -> Option<*const u8> { + let result = unsafe { syscalls::raw::memop(1, increment) }; if result >= 0 { Some(result as *const u8) } else { @@ -64,8 +67,8 @@ } } -// It is safe to return a 'static immutable slice, as the Tock kernel doesn't change the layout of -// flash regions during the application's lifetime. +/// It is safe to return a 'static immutable slice, as the Tock kernel doesn't change the layout of +/// flash regions during the application's lifetime. pub fn get_flash_region(i: usize) -> Option<&'static [u8]> { if i < get_flash_regions_count() { let start = unsafe { syscalls::raw::memop(8, i) as *const u8 }; @@ -78,15 +81,22 @@ } } -// Setting the stack_top and heap_start addresses are marked as unsafe as they should only be called -// by the entry point to setup the allocator. Updating these values afterwards can lead to incorrect -// debug output from the kernel. -// -// Alternate allocator implementations may still find this useful in the future. +/// Set the top of the stack +/// # Safety +/// Setting the stack_top and heap_start addresses are marked as unsafe as they should only be called +/// by the entry point to setup the allocator. Updating these values afterwards can lead to incorrect +/// debug output from the kernel. +/// +/// Alternate allocator implementations may still find this useful in the future. pub unsafe fn set_stack_top(ptr: *const u8) { let _ = syscalls::raw::memop(10, ptr as usize); } +/// Set the top of the heap +/// # Safety +/// Setting the stack_top and heap_start addresses are marked as unsafe as they should only be called +/// by the entry point to setup the allocator. Updating these values afterwards can lead to incorrect +/// debug output from the kernel. pub unsafe fn set_heap_start(ptr: *const u8) { let _ = syscalls::raw::memop(11, ptr as usize); }
diff --git a/src/sensors/ninedof.rs b/src/sensors/ninedof.rs index 7da0dda..7986a40 100644 --- a/src/sensors/ninedof.rs +++ b/src/sensors/ninedof.rs
@@ -30,10 +30,6 @@ } impl Ninedof { - pub unsafe fn new() -> Ninedof { - Ninedof - } - pub fn read_acceleration(&mut self) -> TockResult<NinedofReading> { let res: CbData = Default::default(); subscribe(Self::cb, unsafe { mem::transmute(&res) })?; @@ -61,6 +57,12 @@ } } +impl Default for Ninedof { + fn default() -> Self { + Ninedof + } +} + pub fn subscribe(cb: extern "C" fn(usize, usize, usize, usize), ud: usize) -> TockResult<()> { syscalls::subscribe_fn(DRIVER_NUM, 0, cb, ud)?; Ok(())
diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 4cbef0f..7c5377a 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs
@@ -89,7 +89,7 @@ arg1: usize, arg2: usize, ) -> Result<usize, CommandError> { - let return_code = unsafe { raw::command(driver_number, command_number, arg1, arg2) }; + let return_code = raw::command(driver_number, command_number, arg1, arg2); if return_code >= 0 { Ok(return_code as usize) } else {
diff --git a/src/syscalls/platform_arm.rs b/src/syscalls/platform_arm.rs index 98730d3..cf0048e 100644 --- a/src/syscalls/platform_arm.rs +++ b/src/syscalls/platform_arm.rs
@@ -31,6 +31,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn subscribe( major: usize, minor: usize, @@ -46,16 +48,20 @@ } #[inline(always)] -pub unsafe fn command(major: usize, minor: usize, arg1: usize, arg2: usize) -> isize { - let res; - asm!("svc 2" : "={r0}"(res) - : "{r0}"(major) "{r1}"(minor) "{r2}"(arg1) "{r3}"(arg2) - : "memory" - : "volatile"); - res +pub fn command(major: usize, minor: usize, arg1: usize, arg2: usize) -> isize { + unsafe { + let res; + asm!("svc 2" : "={r0}"(res) + : "{r0}"(major) "{r1}"(minor) "{r2}"(arg1) "{r3}"(arg2) + : "memory" + : "volatile"); + res + } } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn command1(major: usize, minor: usize, arg: usize) -> isize { let res; asm!("svc 2" : "={r0}"(res) @@ -66,6 +72,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn allow(major: usize, minor: usize, slice: *mut u8, len: usize) -> isize { let res; asm!("svc 3" : "={r0}"(res) @@ -76,6 +84,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn memop(major: u32, arg1: usize) -> isize { let res; asm!("svc 4" : "={r0}"(res)
diff --git a/src/syscalls/platform_mock.rs b/src/syscalls/platform_mock.rs index e794c05..e8e026f 100644 --- a/src/syscalls/platform_mock.rs +++ b/src/syscalls/platform_mock.rs
@@ -1,5 +1,12 @@ +/// yield for a callback fired by the kernel +/// # Safety +/// Yielding inside a callback conflicts with Rust's safety guarantees. For example, +/// a FnMut closure could be triggered multiple times making a &mut a shared reference. pub unsafe fn yieldk() {} +/// Subscribe a callback to the kernel +/// # Safety +/// Unsafe as passed callback is dereferenced and called. pub unsafe fn subscribe( _: usize, _: usize, @@ -9,18 +16,27 @@ unimplemented() } -pub unsafe fn command(_: usize, _: usize, _: usize, _: usize) -> isize { +pub fn command(_: usize, _: usize, _: usize, _: usize) -> isize { unimplemented() } +/// Call a command only taking into accoun the first argument +/// # Safety +/// Unsafe as ignored arguments cause leaking of registers to the kernel pub unsafe fn command1(_: usize, _: usize, _: usize) -> isize { unimplemented() } +/// Share a memory region with the kernel +/// # Safety +/// Unsafe as the pointer to the shared buffer is potentially dereferenced by the kernel. pub unsafe fn allow(_: usize, _: usize, _: *mut u8, _: usize) -> isize { unimplemented() } +/// Generic operations on the app's memory as requesting more memory +/// # Safety +/// Allows the kernel to do generic operations on the app's memory which can cause memory corruption. pub unsafe fn memop(_: u32, _: usize) -> isize { unimplemented() }
diff --git a/src/syscalls/platform_riscv32.rs b/src/syscalls/platform_riscv32.rs index 943b72a..7985545 100644 --- a/src/syscalls/platform_riscv32.rs +++ b/src/syscalls/platform_riscv32.rs
@@ -1,4 +1,6 @@ #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn yieldk() { /* TODO: Stop yielding */ asm! ( @@ -12,6 +14,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn subscribe( major: usize, minor: usize, @@ -29,18 +33,22 @@ } #[inline(always)] -pub unsafe fn command(major: usize, minor: usize, arg1: usize, arg2: usize) -> isize { - let res; - asm!("li a0, 2 +pub fn command(major: usize, minor: usize, arg1: usize, arg2: usize) -> isize { + unsafe { + let res; + asm!("li a0, 2 ecall" : "={x10}" (res) : "{x11}" (major), "{x12}" (minor), "{x13}" (arg1), "{x14}" (arg2) : "memory" : "volatile"); - res + res + } } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn command1(major: usize, minor: usize, arg: usize) -> isize { let res; asm!("li a0, 2 @@ -53,6 +61,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn allow(major: usize, minor: usize, slice: *mut u8, len: usize) -> isize { let res; asm!("li a0, 3 @@ -65,6 +75,8 @@ } #[inline(always)] +// Justification: documentation is generated from mocks +#[allow(clippy::missing_safety_doc)] pub unsafe fn memop(major: u32, arg1: usize) -> isize { let res; asm!("li a0, 4
diff --git a/src/timer.rs b/src/timer.rs index 9a43027..a0172b0 100644 --- a/src/timer.rs +++ b/src/timer.rs
@@ -334,7 +334,11 @@ } } - pub unsafe fn create_timer_driver_unsafe<'a>(&'a self) -> TimerDriver<'a> { + /// Create a timer driver instance without checking for running instance + /// # Safety + /// May lead to undefined behavior at the previous consumer of the timer driver. + /// Only safe if no other consumer is still running (e.g. on unwind) + pub unsafe fn create_timer_driver_unsafe(&self) -> TimerDriver<'_> { TimerDriver { callback: Callback { now: &self.current_time, @@ -431,11 +435,11 @@ Ok(()) } - fn activate_timer(&self, timer: &ActiveTimer) -> TockResult<()> { + fn activate_timer(&self, timer: ActiveTimer) -> TockResult<()> { set_alarm_at(timer.instant as usize)?; let now = get_current_ticks()?; - if !is_over(*timer, now as u32) { - self.context.active_timer.set(Some(*timer)); + if !is_over(timer, now as u32) { + self.context.active_timer.set(Some(timer)); } else { self.wakeup_soon()?; } @@ -457,10 +461,7 @@ if !is_over(next_timer, now as u32) { break; } else { - match stop_alarm_at(next_timer.instant as usize) { - Ok(_) => (), - Err(_) => (), - } + stop_alarm_at(next_timer.instant as usize)?; } } Ok(()) @@ -507,14 +508,14 @@ if let Some(active) = self.context.active_timer.get() { if left_is_later(active, this_alarm) { suspended_timer.set(Some(active)); - self.activate_timer(&this_alarm)?; + self.activate_timer(this_alarm)?; } } else { - self.activate_timer(&this_alarm)?; + self.activate_timer(this_alarm)?; } if is_over(this_alarm, now as u32) { if let Some(paused) = suspended_timer.get() { - self.activate_timer(&paused)?; + self.activate_timer(paused)?; } else { self.context.active_timer.set(None); }