/src/task/entry.rs
use core::fmt;
use crate::capabilities::{CapToken, MAX_CAPS, CapType};
use crate::mpu::MemoryMap;
use crate::task::TaskId;
use crate::timer::Ticks;
#[derive(Debug, PartialEq)]
pub enum TaskState {
/// Task running normally; eligible to be scheduled
Running,
/// Blocked waiting for the fulfillment of a device indicated by
/// the capability type contained within.
Blocked(CapType),
/// Waiting for the current number of ticks to equal the value
/// within.
Sleeping(Ticks),
/// The task is exiting and will be removed on the next scheduling pass
Exiting,
}
impl fmt::Display for TaskState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TaskState::Running => write!(f, "running"),
TaskState::Blocked(c) => write!(f, "blocked {}", c),
TaskState::Sleeping(_) => write!(f, "sleeping"),
TaskState::Exiting => write!(f, "exiting"),
}
}
}
#[repr(C)]
#[derive(Debug, Clone)]
pub(crate) struct TaskRegisters {
pub r0: u32,
pub r1: u32,
pub r2: u32,
pub r3: u32,
pub r12: u32,
pub lr: u32,
pub pc: u32,
pub xpsr: u32,
pub sp: u32,
pub r8: u32,
pub r9: u32,
pub r10: u32,
pub r11: u32,
pub r4: u32,
pub r5: u32,
pub r6: u32,
pub r7: u32,
}
impl TaskRegisters {
pub fn new() -> TaskRegisters {
TaskRegisters {
r0: 0,
r1: 0,
r2: 0,
r3: 0,
r4: 0,
r5: 0,
r6: 0,
r7: 0,
r8: 0,
r9: 0,
r10: 0,
r11: 0,
r12: 0,
sp: 0,
lr: 0,
pc: 0,
xpsr: 0x01000000, // Default value sets thread mode, which must always be set
}
}
}
#[derive(Debug)]
pub(crate) struct TaskEntry {
pub id: TaskId,
pub name: heapless::String<8>,
pub regs: TaskRegisters,
pub mem_map: MemoryMap,
pub state: TaskState,
pub priority: u8,
pub io_ready: bool,
pub ticks_ran: u32,
pub caps: heapless::Vec<CapToken, MAX_CAPS>,
}
impl TaskEntry {
pub fn has_capability(&self, cap: CapType) -> bool {
self.caps.iter().any(|c| c.captype() == cap)
}
}