use core::{fmt, hash::Hash, ops::Range};
use crate::{
kernel::error::*,
time::{Duration, Time},
};
pub trait Id: fmt::Debug + Copy + Eq + Ord + Hash + Send + Sync + 'static {}
impl<T: ?Sized + fmt::Debug + Copy + Eq + Ord + Hash + Send + Sync + 'static> Id for T {}
pub unsafe trait KernelBase: fmt::Debug + Copy + Sized + 'static {
type RawDebugPrinter: fmt::Debug + Send + Sync;
type RawTaskId: Id;
const RAW_SUPPORTED_QUEUE_ORDERS: &'static [Option<QueueOrderKind>] = &[];
fn raw_debug() -> Self::RawDebugPrinter;
fn raw_acquire_cpu_lock() -> Result<(), CpuLockError>;
unsafe fn raw_release_cpu_lock() -> Result<(), CpuLockError>;
fn raw_has_cpu_lock() -> bool;
unsafe fn raw_unboost_priority() -> Result<(), BoostPriorityError>;
fn raw_is_priority_boost_active() -> bool;
fn raw_is_task_context() -> bool;
fn raw_is_interrupt_context() -> bool;
fn raw_is_boot_complete() -> bool;
fn raw_set_time(time: Time) -> Result<(), TimeError>;
unsafe fn raw_exit_task() -> Result<!, ExitTaskError>;
fn raw_park() -> Result<(), ParkError>;
fn raw_park_timeout(timeout: Duration) -> Result<(), ParkTimeoutError>;
fn raw_sleep(duration: Duration) -> Result<(), SleepError>;
fn raw_task_current() -> Result<Self::RawTaskId, GetCurrentTaskError>;
unsafe fn raw_task_activate(this: Self::RawTaskId) -> Result<(), ActivateTaskError>;
unsafe fn raw_task_interrupt(this: Self::RawTaskId) -> Result<(), InterruptTaskError>;
unsafe fn raw_task_unpark_exact(this: Self::RawTaskId) -> Result<(), UnparkExactError>;
unsafe fn raw_task_priority(this: Self::RawTaskId) -> Result<usize, GetTaskPriorityError>;
unsafe fn raw_task_effective_priority(
this: Self::RawTaskId,
) -> Result<usize, GetTaskPriorityError>;
}
pub unsafe trait KernelTime: KernelBase {
fn raw_time() -> Result<Time, TimeError>;
}
pub unsafe trait KernelBoostPriority: KernelBase {
fn raw_boost_priority() -> Result<(), BoostPriorityError>;
}
pub unsafe trait KernelTaskSetPriority: KernelBase {
unsafe fn raw_task_set_priority(
this: Self::RawTaskId,
priority: usize,
) -> Result<(), SetTaskPriorityError>;
}
pub unsafe trait KernelAdjustTime: KernelBase {
const RAW_TIME_USER_HEADROOM: Duration = Duration::from_secs(1);
fn raw_adjust_time(delta: Duration) -> Result<(), AdjustTimeError>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum QueueOrder {
Fifo,
TaskPriority,
}
impl QueueOrder {
#[inline]
pub const fn is_supported<System: KernelBase>(&self) -> bool {
let kind = match self {
QueueOrder::Fifo => QueueOrderKind::Fifo,
QueueOrder::TaskPriority => QueueOrderKind::TaskPriority,
};
let mut i = 0;
let values = System::RAW_SUPPORTED_QUEUE_ORDERS;
while i < values.len() {
if let Some(value) = values[i] {
if value as u8 == kind as u8 {
return true;
}
}
i += 1;
}
false
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum QueueOrderKind {
Fifo,
TaskPriority,
}
pub unsafe trait KernelEventGroup: KernelBase {
type RawEventGroupId: Id;
unsafe fn raw_event_group_set(
this: Self::RawEventGroupId,
bits: EventGroupBits,
) -> Result<(), UpdateEventGroupError>;
unsafe fn raw_event_group_clear(
this: Self::RawEventGroupId,
bits: EventGroupBits,
) -> Result<(), UpdateEventGroupError>;
unsafe fn raw_event_group_get(
this: Self::RawEventGroupId,
) -> Result<EventGroupBits, GetEventGroupError>;
unsafe fn raw_event_group_wait(
this: Self::RawEventGroupId,
bits: EventGroupBits,
flags: EventGroupWaitFlags,
) -> Result<EventGroupBits, WaitEventGroupError>;
unsafe fn raw_event_group_wait_timeout(
this: Self::RawEventGroupId,
bits: EventGroupBits,
flags: EventGroupWaitFlags,
timeout: Duration,
) -> Result<EventGroupBits, WaitEventGroupTimeoutError>;
unsafe fn raw_event_group_poll(
this: Self::RawEventGroupId,
bits: EventGroupBits,
flags: EventGroupWaitFlags,
) -> Result<EventGroupBits, PollEventGroupError>;
}
bitflags::bitflags! {
pub struct EventGroupWaitFlags: u8 {
const ALL = 1 << 0;
const CLEAR = 1 << 1;
}
}
pub type EventGroupBits = u32;
pub unsafe trait KernelMutex: KernelBase {
type RawMutexId: Id;
const RAW_SUPPORTED_MUTEX_PROTOCOLS: &'static [Option<MutexProtocolKind>] = &[];
unsafe fn raw_mutex_is_locked(this: Self::RawMutexId) -> Result<bool, QueryMutexError>;
unsafe fn raw_mutex_unlock(this: Self::RawMutexId) -> Result<(), UnlockMutexError>;
unsafe fn raw_mutex_lock(this: Self::RawMutexId) -> Result<(), LockMutexError>;
unsafe fn raw_mutex_lock_timeout(
this: Self::RawMutexId,
timeout: Duration,
) -> Result<(), LockMutexTimeoutError>;
unsafe fn raw_mutex_try_lock(this: Self::RawMutexId) -> Result<(), TryLockMutexError>;
unsafe fn raw_mutex_mark_consistent(
this: Self::RawMutexId,
) -> Result<(), MarkConsistentMutexError>;
}
#[doc = include_str!("../common.md")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum MutexProtocol {
None,
Ceiling(usize),
}
impl MutexProtocol {
#[inline]
pub const fn is_supported<System: KernelMutex>(&self) -> bool {
let kind = match self {
MutexProtocol::None => MutexProtocolKind::None,
MutexProtocol::Ceiling(_) => MutexProtocolKind::Ceiling,
};
let mut i = 0;
let values = System::RAW_SUPPORTED_MUTEX_PROTOCOLS;
while i < values.len() {
if let Some(value) = values[i] {
if value as u8 == kind as u8 {
return true;
}
}
i += 1;
}
false
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum MutexProtocolKind {
None,
Ceiling,
}
pub unsafe trait KernelSemaphore: KernelBase {
type RawSemaphoreId: Id;
unsafe fn raw_semaphore_drain(this: Self::RawSemaphoreId) -> Result<(), DrainSemaphoreError>;
unsafe fn raw_semaphore_get(
this: Self::RawSemaphoreId,
) -> Result<SemaphoreValue, GetSemaphoreError>;
unsafe fn raw_semaphore_signal(
this: Self::RawSemaphoreId,
count: SemaphoreValue,
) -> Result<(), SignalSemaphoreError>;
unsafe fn raw_semaphore_signal_one(
this: Self::RawSemaphoreId,
) -> Result<(), SignalSemaphoreError>;
unsafe fn raw_semaphore_wait_one(this: Self::RawSemaphoreId) -> Result<(), WaitSemaphoreError>;
unsafe fn raw_semaphore_wait_one_timeout(
this: Self::RawSemaphoreId,
timeout: Duration,
) -> Result<(), WaitSemaphoreTimeoutError>;
unsafe fn raw_semaphore_poll_one(this: Self::RawSemaphoreId) -> Result<(), PollSemaphoreError>;
}
#[doc = include_str!("../common.md")]
pub type SemaphoreValue = usize;
pub unsafe trait KernelTimer: KernelBase {
type RawTimerId: Id;
unsafe fn raw_timer_start(this: Self::RawTimerId) -> Result<(), StartTimerError>;
unsafe fn raw_timer_stop(this: Self::RawTimerId) -> Result<(), StopTimerError>;
unsafe fn raw_timer_set_delay(
this: Self::RawTimerId,
delay: Option<Duration>,
) -> Result<(), SetTimerDelayError>;
unsafe fn raw_timer_set_period(
this: Self::RawTimerId,
period: Option<Duration>,
) -> Result<(), SetTimerPeriodError>;
}
pub unsafe trait KernelInterruptLine: KernelBase {
#[allow(clippy::reversed_empty_ranges)] const RAW_MANAGED_INTERRUPT_PRIORITY_RANGE: Range<InterruptPriority> = 0..0;
const RAW_MANAGED_INTERRUPT_LINES: &'static [InterruptNum] = &[];
unsafe fn raw_interrupt_line_set_priority(
this: InterruptNum,
value: InterruptPriority,
) -> Result<(), SetInterruptLinePriorityError>;
unsafe fn raw_interrupt_line_enable(this: InterruptNum)
-> Result<(), EnableInterruptLineError>;
unsafe fn raw_interrupt_line_disable(
this: InterruptNum,
) -> Result<(), EnableInterruptLineError>;
unsafe fn raw_interrupt_line_pend(this: InterruptNum) -> Result<(), PendInterruptLineError>;
unsafe fn raw_interrupt_line_clear(this: InterruptNum) -> Result<(), ClearInterruptLineError>;
unsafe fn raw_interrupt_line_is_pending(
this: InterruptNum,
) -> Result<bool, QueryInterruptLineError>;
}
pub type InterruptNum = usize;
pub type InterruptPriority = i16;
pub type InterruptHandlerFn = unsafe extern "C" fn();