bern_arch/
scheduler.rs

1//! Scheduler.
2
3/// Scheduler.
4///
5/// # Implementation
6/// In addition to the trait the hardware context switch exception must be
7/// implemented. The exception must
8/// 1. Push the CPU registers to the stack
9/// 2. Call `switch_context` from the kernel
10///     - in: current task stack pointer in first parameter register (e.g. `r0`)
11///     - out: next task stack pointer in return register (e.g. `r0`)
12/// 3. Pop CPU register from new stack
13///
14/// On a ARM Cortex-M4 for example (simplified):
15/// ```ignore
16/// #[no_mangle]
17/// #[unsafe(naked)]
18/// extern "C" fn PendSV() {
19///     unsafe {
20///         asm!(
21///         "push    {{lr}}",
22///         "mrs     r0, psp",         // get process stack pointer
23///         "stmdb   r0!, {{r4-r11}}", // push registers to stack A
24///         "bl      switch_context",  // call kernel for context switch
25///         "pop     {{lr}}",
26///         "mov     r3, #3",
27///         "msr     control, r3",      // run in unprivileged mode
28///         "isb",
29///         "ldmia   r0!, {{r4-r11}}",  // pop registers from stack B
30///         "msr     psp, r0",          // set process stack pointer
31///         "bx      lr",
32///         options(noreturn),
33///         )
34///     }
35/// }
36/// ```
37///
38/// The exception can call `check_stack` to check wheter the there is enough
39/// space left to store the registers.
40///     - in: stack pointer after stacking
41///     - out: 0 - stack would overflow, 1 - enought space left
42pub trait IScheduler {
43    /// Init the stack of task.
44    ///
45    /// # Safety
46    /// The stack must be large enough for the initial stack frame.
47    unsafe fn init_task_stack(
48        stack_ptr: *mut usize,
49        entry: *const usize,
50        arg: *const usize,
51        exit: *const usize,
52    ) -> *mut usize;
53    /// Start the first task.
54    fn start_first_task(stack_ptr: *const usize) -> ();
55    /// Trigger context switch exception.
56    fn trigger_context_switch();
57}