#![cfg(feature = "std")]
use core::mem::size_of;
use core::ptr::null_mut;
use std::sync::Arc;
use std::time::Duration;
use osal_rs::log::{self, log_levels};
use osal_rs::os::*;
#[cfg(not(feature = "serde"))]
use osal_rs::os::{Deserialize, Serialize};
#[cfg(not(feature = "serde"))]
use osal_rs::utils::{Error, Result};
#[cfg(not(feature = "serde"))]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
struct QueueMessage {
bytes: [u8; 4],
}
#[cfg(not(feature = "serde"))]
impl BytesHasLen for QueueMessage {
fn len(&self) -> usize {
self.bytes.len()
}
}
#[cfg(not(feature = "serde"))]
impl Serialize for QueueMessage {
fn to_bytes(&self) -> &[u8] {
&self.bytes
}
}
#[cfg(not(feature = "serde"))]
impl Deserialize for QueueMessage {
fn from_bytes(bytes: &[u8]) -> Result<Self> {
if bytes.len() != 4 {
return Err(Error::ReadError("invalid queue message length"));
}
Ok(Self {
bytes: [bytes[0], bytes[1], bytes[2], bytes[3]],
})
}
}
#[cfg(feature = "serde")]
type QueueMessage = [u8; 4];
fn sample_message() -> QueueMessage {
#[cfg(not(feature = "serde"))]
{
QueueMessage { bytes: [1, 2, 3, 4] }
}
#[cfg(feature = "serde")]
{
[1, 2, 3, 4]
}
}
fn dummy_thread_handle() -> types::ThreadHandle {
1usize as types::ThreadHandle
}
#[derive(Clone, Copy)]
struct HostPriority(types::UBaseType);
impl ToPriority for HostPriority {
fn to_priority(&self) -> types::UBaseType {
self.0
}
}
#[test]
fn std_system_surface_signatures_compile() {
let _start: fn() = <System as SystemFn>::start;
let _get_state: fn() -> ThreadState = <System as SystemFn>::get_state;
let _suspend_all: fn() = <System as SystemFn>::suspend_all;
let _resume_all: fn() -> types::BaseType = <System as SystemFn>::resume_all;
let _stop: fn() = <System as SystemFn>::stop;
let _get_tick_count: fn() -> types::TickType = <System as SystemFn>::get_tick_count;
let _get_current_time_us: fn() -> Duration = <System as SystemFn>::get_current_time_us;
let _get_us_from_tick: fn(&Duration) -> types::TickType = <System as SystemFn>::get_us_from_tick;
let _count_threads: fn() -> usize = <System as SystemFn>::count_threads;
let _get_all_thread: fn() -> SystemState = <System as SystemFn>::get_all_thread;
let _delay: fn(types::TickType) = <System as SystemFn>::delay;
let _delay_until: fn(&mut types::TickType, types::TickType) = <System as SystemFn>::delay_until;
let _critical_section_enter: fn() = <System as SystemFn>::critical_section_enter;
let _critical_section_exit: fn() = <System as SystemFn>::critical_section_exit;
let _check_timer: fn(&Duration, &Duration) -> osal_rs::utils::OsalRsBool = <System as SystemFn>::check_timer;
let _yield_from_isr: fn(types::BaseType) = <System as SystemFn>::yield_from_isr;
let _end_switching_isr: fn(types::BaseType) = <System as SystemFn>::end_switching_isr;
let _enter_critical: fn() = <System as SystemFn>::enter_critical;
let _exit_critical: fn() = <System as SystemFn>::exit_critical;
let _enter_critical_from_isr: fn() -> types::UBaseType = <System as SystemFn>::enter_critical_from_isr;
let _exit_critical_from_isr: fn(types::UBaseType) = <System as SystemFn>::exit_critical_from_isr;
let _get_free_heap_size: fn() -> usize = <System as SystemFn>::get_free_heap_size;
System::delay_with_to_tick(Duration::ZERO);
let mut wake = 0;
System::delay_until_with_to_tick(&mut wake, Duration::ZERO);
let state = System::get_all_thread();
let tasks: &[ThreadMetadata] = &state;
let _ = tasks.first();
}
#[test]
fn std_backend_exports_core_api_surface() {
let _max_mask: types::EventBits = EventGroup::MAX_MASK;
let mut event_group = EventGroup::new().unwrap();
let event_group_handle: &types::EventGroupHandle = &event_group;
let _ = event_group_handle;
let _ = event_group.set(0b0001);
let _ = event_group.set_from_isr(0b0001);
let _ = event_group.get();
let _ = event_group.get_from_isr();
let _ = event_group.clear(0b0001);
let _ = event_group.clear_from_isr(0b0001);
let _ = event_group.wait(0b0001, 0);
let _ = event_group.wait_with_to_tick(0b0001, Duration::ZERO);
let _ = format!("{event_group:?}");
let _ = format!("{event_group}");
event_group.delete();
let mut raw_mutex = RawMutex::new().unwrap();
let raw_mutex_handle: &types::MutexHandle = &raw_mutex;
let _ = raw_mutex_handle;
let _ = raw_mutex.lock();
let _ = raw_mutex.unlock();
let _ = raw_mutex.lock_from_isr();
let _ = raw_mutex.unlock_from_isr();
let _ = format!("{raw_mutex:?}");
let _ = format!("{raw_mutex}");
raw_mutex.delete();
let mut mutex = Mutex::new(0u32);
let mut guard = mutex.lock().unwrap();
guard.update(&41);
*guard += 1;
drop(guard);
let guard_from_isr = mutex.lock_from_isr().unwrap();
drop(guard_from_isr);
let explicit_guard = mutex.lock_from_isr_explicit().unwrap();
drop(explicit_guard);
*mutex.get_mut() = 7;
let _ = format!("{mutex:?}");
let _ = format!("{mutex}");
let _shared_mutex = Mutex::new_arc(9u32);
let inner_mutex = Mutex::new(11u32);
let _ = inner_mutex.into_inner().unwrap();
let mut queue = Queue::new(2, 4).unwrap();
let queue_handle: &types::QueueHandle = &queue;
let _ = queue_handle;
let payload = [1u8, 2, 3, 4];
let mut payload_buffer = [0u8; 4];
queue.post(&payload, 0).unwrap();
let _ = queue.fetch(&mut payload_buffer, 0);
queue.post_from_isr(&payload).unwrap();
let _ = queue.fetch_from_isr(&mut payload_buffer);
queue.post_with_to_tick(&payload, Duration::ZERO).unwrap();
let _ = queue.fetch_with_to_tick(&mut payload_buffer, Duration::ZERO);
let _ = format!("{queue:?}");
let _ = format!("{queue}");
queue.delete();
let message = sample_message();
let mut streamed_queue = QueueStreamed::<QueueMessage>::new(2, size_of::<QueueMessage>() as types::UBaseType).unwrap();
let streamed_handle: &types::QueueHandle = &streamed_queue;
let _ = streamed_handle;
streamed_queue.post(&message, 0).unwrap();
let mut message_buffer = sample_message();
let _ = streamed_queue.fetch(&mut message_buffer, 0);
streamed_queue.post_from_isr(&message).unwrap();
let _ = streamed_queue.fetch_from_isr(&mut message_buffer);
let _ = format!("{streamed_queue:?}");
let _ = format!("{streamed_queue}");
streamed_queue.delete();
let mut semaphore = Semaphore::new(2, 1).unwrap();
let semaphore_handle: &types::SemaphoreHandle = &semaphore;
let _ = semaphore_handle;
let _ = Semaphore::new_with_count(0).unwrap();
let _ = semaphore.wait(Duration::ZERO);
let _ = semaphore.wait_from_isr();
let _ = semaphore.signal();
let _ = semaphore.signal_from_isr();
let _ = format!("{semaphore:?}");
let _ = format!("{semaphore}");
semaphore.delete();
let handle = dummy_thread_handle();
let _ = Thread::new_with_handle(handle, "worker", 128, 1).unwrap();
let _ = Thread::new_with_to_priority("worker", 128, HostPriority(1));
let _ = Thread::new_with_handle_and_to_priority(handle, "worker", 128, HostPriority(1)).unwrap();
let _ = Thread::get_metadata_from_handle(handle);
let mut thread = Thread::new("worker", 128, 1);
let thread_param: ThreadParam = Arc::new(1u32);
let spawned = thread
.spawn(Some(thread_param.clone()), |_thread, param| {
Ok(param.unwrap_or_else(|| Arc::new(0u32) as ThreadParam))
})
.unwrap();
let thread_handle: &types::ThreadHandle = &spawned;
let _ = thread_handle;
let _ = format!("{spawned:?}");
let _ = format!("{spawned}");
let _ = spawned.get_metadata();
let _ = Thread::get_metadata(&spawned);
spawned.notify(ThreadNotification::Increment).unwrap();
let mut higher_priority_task_woken = 0;
spawned
.notify_from_isr(ThreadNotification::SetValueWithOverwrite(7), &mut higher_priority_task_woken)
.unwrap();
let _ = spawned.wait_notification(0, 0, 0);
let _ = spawned.wait_notification_with_to_tick(0, 0, Duration::ZERO);
spawned.suspend();
spawned.resume();
let _ = spawned.join(null_mut()).unwrap();
spawned.delete();
let mut simple_thread = Thread::new("simple", 128, 1);
let _ = simple_thread.spawn_simple(|| {}).unwrap();
let current = Thread::get_current();
let _ = format!("{current:?}");
let timer_param: TimerParam = Arc::new(5u32);
let mut timer = Timer::new("timer", 1, false, Some(timer_param.clone()), |_timer, param| {
Ok(param.unwrap_or_else(|| Arc::new(0u32) as TimerParam))
})
.unwrap();
let _ = Timer::new_with_to_tick("timer", Duration::from_millis(1), true, None, |_timer, param| {
Ok(param.unwrap_or_else(|| Arc::new(0u32) as TimerParam))
})
.unwrap();
let timer_handle: &types::TimerHandle = &timer;
let _ = timer_handle;
let _ = format!("{timer:?}");
let _ = format!("{timer}");
let _ = timer.start(0);
let _ = timer.stop(0);
let _ = timer.reset(0);
let _ = timer.change_period(1, 0);
let _ = timer.start_with_to_tick(Duration::ZERO);
let _ = timer.stop_with_to_tick(Duration::ZERO);
let _ = timer.reset_with_to_tick(Duration::ZERO);
let _ = timer.change_period_with_to_tick(Duration::from_millis(1), Duration::ZERO);
let _ = timer.delete_with_to_tick(Duration::ZERO);
}
#[test]
fn std_backend_exports_logging_api_surface() {
let _log_buffer_size: usize = log::LOG_BUFFER_SIZE;
let _return: &str = log::RETURN;
let _flag_debug: u8 = log_levels::FLAG_DEBUG;
let _flag_info: u8 = log_levels::FLAG_INFO;
let _flag_warning: u8 = log_levels::FLAG_WARNING;
let _flag_error: u8 = log_levels::FLAG_ERROR;
let _flag_fatal: u8 = log_levels::FLAG_FATAL;
let _flag_color_on: u8 = log_levels::FLAG_COLOR_ON;
let _flag_state_on: u8 = log_levels::FLAG_STATE_ON;
let _level_debug: u8 = log_levels::LEVEL_DEBUG;
let _level_info: u8 = log_levels::LEVEL_INFO;
let _level_warning: u8 = log_levels::LEVEL_WARNING;
let _level_error: u8 = log_levels::LEVEL_ERROR;
let _level_fatal: u8 = log_levels::LEVEL_FATAL;
let _set_level_log: fn(u8) = log::set_level_log;
let _set_enable_log: fn(bool) = log::set_enable_log;
let _get_enable_log: fn() -> bool = log::get_enable_log;
let _is_enabled_log: fn(u8) -> bool = log::is_enabled_log;
let _get_level_log: fn() -> u8 = log::get_level_log;
let _set_enable_color: fn(bool) = log::set_enable_color;
let _sys_log: fn(&str, u8, &str) = log::sys_log;
log::set_level_log(log_levels::LEVEL_DEBUG);
log::set_enable_log(true);
log::set_enable_color(true);
let _ = log::get_enable_log();
let _ = log::is_enabled_log(log_levels::FLAG_INFO);
let _ = log::get_level_log();
log::sys_log("StdApiSurface", log_levels::FLAG_INFO, "logging api surface");
osal_rs::print!("std print {}", 1u8);
osal_rs::println!();
osal_rs::println!("std println {}", 2u8);
osal_rs::log_debug!("StdApiSurface", "debug {}", 3u8);
osal_rs::log_info!("StdApiSurface", "info {}", 4u8);
osal_rs::log_warning!("StdApiSurface", "warning {}", 5u8);
osal_rs::log_error!("StdApiSurface", "error {}", 6u8);
osal_rs::log_fatal!("StdApiSurface", "fatal {}", 7u8);
}