[−][src]Trait r3::kernel::PortThreading
Implemented by a port. This trait contains items related to low-level operations for controlling CPU states and context switching.
Safety
Implementing a port is inherently unsafe because it's responsible for initializing the execution environment and providing a dispatcher implementation.
These methods are only meant to be called by the kernel.
Associated Types
Loading content...Associated Constants
pub const PORT_TASK_STATE_INIT: Self::PortTaskState
[src]
The initial value of TaskCb::port_task_state
for all tasks.
pub const STACK_DEFAULT_SIZE: usize
[src]
The default stack size for tasks.
pub const STACK_ALIGN: usize
[src]
The alignment requirement for task stack regions.
Both ends of stack regions are aligned by STACK_ALIGN
. It's
automatically enforced by the kernel configurator for automatically
allocated stack regions (this applies to tasks created without
stack_hunk
). The kernel configurator does not check the alignemnt
for manually-allocated stack regions.
Required methods
pub unsafe fn dispatch_first_task() -> !
[src]
Transfer the control to the dispatcher, discarding the current
(startup) context. State::running_task
is None
at this point.
The dispatcher should call PortToKernel::choose_running_task
to find
the next task to run and transfer the control to that task.
Precondition: CPU Lock active, a boot context
pub unsafe fn yield_cpu()
[src]
Yield the processor.
In a task context, this method immediately transfers the control to
a dispatcher. The dispatcher should call
PortToKernel::choose_running_task
to find the next task to run and
transfer the control to that task.
In an interrupt context, the effect of this method will be deferred until the processor completes the execution of all active interrupt handler threads.
Precondition: CPU Lock inactive
Port Implementation Note: One way to handle the interrupt context case is to set a flag variable and check it in the epilogue of a first-level interrupt handler. Another way is to raise a low-priority interrupt (such as PendSV in Arm-M) and implement dispatching in the handler.
pub unsafe fn exit_and_dispatch(task: &'static TaskCb<Self>) -> !
[src]
Destroy the state of the previously running task (task
, which has
already been removed from State::running_task
) and proceed to
the dispatcher.
Precondition: CPU Lock active
pub unsafe fn enter_cpu_lock()
[src]
Disable all kernel-managed interrupts (this state is called CPU Lock).
Precondition: CPU Lock inactive
pub unsafe fn leave_cpu_lock()
[src]
Re-enable kernel-managed interrupts previously disabled by
enter_cpu_lock
, thus deactivating the CPU Lock state.
Precondition: CPU Lock active
pub unsafe fn initialize_task_state(task: &'static TaskCb<Self>)
[src]
Prepare the task for activation. More specifically, set the current
program counter to TaskAttr::entry_point
and the current stack
pointer to either end of TaskAttr::stack
, ensuring the task will
start execution from entry_point
next time the task receives the
control.
Do not call this for a running task. Calling this for a dormant task is
always safe. For tasks in other states, whether this method is safe is
dependent on how the programming language the task code is written in
is implemented. In particular, this is unsafe for Rust task code because
it might violate the requirement of Pin
if there's a Pin
pointing
to something on the task's stack.
Precondition: CPU Lock active
pub fn is_cpu_lock_active() -> bool
[src]
Return a flag indicating whether a CPU Lock state is active.
pub fn is_task_context() -> bool
[src]
Return a flag indicating whether the current context is an task context.
Provided methods
pub unsafe fn try_enter_cpu_lock() -> bool
[src]
Activate CPU Lock. Return true
iff CPU Lock was inactive before the
call.