Skip to content

Commit

Permalink
riot-rs-threads: cortex-m: make sched() deal with no previous thread
Browse files Browse the repository at this point in the history
  • Loading branch information
kaspar030 committed Apr 17, 2024
1 parent 2084409 commit 7d30fbe
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 78 deletions.
65 changes: 3 additions & 62 deletions src/riot-rs-threads/src/arch/cortex_m.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,65 +62,11 @@ impl Arch for Cpu {
}

#[inline(always)]
fn start_threading(next_sp: usize) {
cortex_m::interrupt::disable();
fn start_threading() {
Self::schedule();
unsafe {
asm!(
"
msr psp, r1 // set new thread's SP to PSP
cpsie i // enable interrupts, otherwise svc hard faults
svc 0 // SVC 0 handles switching
",
in("r1")next_sp);
}
}
}

#[cfg(any(armv7m, armv8m))]
#[naked]
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn SVCall() {
unsafe {
asm!(
"
movw LR, #0xFFFd
movt LR, #0xFFFF
bx lr
",
options(noreturn)
)
};
}

#[cfg(armv6m)]
#[naked]
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn SVCall() {
unsafe {
asm!(
"
/* label rules:
* - number only
* - no combination of *only* [01]
* - add f or b for 'next matching forward/backward'
* so let's use '99' forward ('99f')
*/
ldr r0, 99f
mov LR, r0
bx lr
.align 4
99:
.word 0xFFFFFFFD
",
options(noreturn)
)
};
}

#[cfg(any(armv7m, armv8m))]
#[naked]
#[no_mangle]
Expand All @@ -129,7 +75,6 @@ unsafe extern "C" fn PendSV() {
unsafe {
asm!(
"
mrs r0, psp
cpsid i
bl {sched}
cpsie i
Expand Down Expand Up @@ -163,7 +108,6 @@ unsafe extern "C" fn PendSV() {
unsafe {
asm!(
"
mrs r0, psp
cpsid i
bl sched
cpsie i
Expand Down Expand Up @@ -214,9 +158,6 @@ unsafe extern "C" fn PendSV() {
/// It selects the next thread that should run from the runqueue.
/// This may be current thread, or a new one.
///
/// Input:
/// - old_sp (`r0`): the stack pointer of the currently running thread.
///
/// Returns:
/// - `0` in `r0` if the next thread in the runqueue is the currently running thread
/// - Else it writes into the following registers:
Expand All @@ -227,7 +168,7 @@ unsafe extern "C" fn PendSV() {
/// This function is called in PendSV.
// TODO: make arch independent, or move to arch
#[no_mangle]
unsafe fn sched(old_sp: usize) -> usize {
unsafe fn sched() -> usize {
// SAFETY: interrupts are disabled by caller
let cs = unsafe { CriticalSection::new() };
let next_pid;
Expand Down Expand Up @@ -255,7 +196,7 @@ unsafe fn sched(old_sp: usize) -> usize {
return 0;
}
//println!("current: {} next: {}", current_pid, next_pid);
threads.threads[current_pid as usize].sp = old_sp;
threads.threads[current_pid as usize].sp = cortex_m::register::psp::read() as usize;
threads.current_thread = Some(next_pid);
current_high_regs = threads.threads[current_pid as usize].data.as_ptr();
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/riot-rs-threads/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub trait Arch {
fn schedule();

/// Setup and initiate the first context switch.
fn start_threading(next_sp: usize);
fn start_threading();
}

cfg_if::cfg_if! {
Expand All @@ -36,7 +36,7 @@ cfg_if::cfg_if! {
fn setup_stack(_: &mut [u8], _: usize, _: usize) -> usize {
unimplemented!()
}
fn start_threading(_: usize) {
fn start_threading() {
unimplemented!()
}
fn schedule() {
Expand Down
19 changes: 5 additions & 14 deletions src/riot-rs-threads/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
// invariants
#![allow(clippy::indexing_slicing)]

use critical_section::CriticalSection;

use riot_rs_runqueue::RunQueue;
pub use riot_rs_runqueue::{RunqueueId, ThreadId};

Expand Down Expand Up @@ -176,20 +174,13 @@ impl Threads {
///
/// # Safety
///
/// This may only be called once.
///
/// # Panics
/// This function is crafted to be called at a specific point in the RIOT-rs
/// initialization, by `riot-rs-rt`. Don't call this unless you know you need to.
///
/// Panics if no thread exists.
/// Currently it expects at least:
/// - Cortex-M: to be called from the reset handler while MSP is active
pub unsafe fn start_threading() {
// faking a critical section to get THREADS
// SAFETY: caller ensures invariants
let cs = unsafe { CriticalSection::new() };
let next_sp = THREADS.with_mut_cs(cs, |mut threads| {
let next_pid = threads.runqueue.get_next().unwrap();
threads.threads[next_pid as usize].sp
});
Cpu::start_threading(next_sp);
Cpu::start_threading();
}

/// Trait for types that fit into a single register.
Expand Down

0 comments on commit 7d30fbe

Please sign in to comment.