Skip to content

Commit

Permalink
Switch tasks at prio level 1
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Feb 21, 2025
1 parent 4a9ef47 commit 105ca14
Showing 1 changed file with 4 additions and 9 deletions.
13 changes: 4 additions & 9 deletions esp-wifi/src/preempt_builtin/timer/xtensa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ const TIMESLICE_FREQUENCY: Rate = Rate::from_hz(crate::CONFIG.tick_rate_hz);

use super::TIMER;

// CPU-internal software interrupt, priority 3. For some reason, the task
// switcher fails when triggered at priority 1, otherwise we could use interrupt
// number 7 instead at priority 1.
const SW_INTERRUPT: u32 = 1 << 29;
const SW_INTERRUPT: u32 = 1 << 7;

pub(crate) fn setup_timer(mut timer1: TimeBase) {
// The timer needs to tick at Priority 1 to prevent accidentally interrupting
Expand Down Expand Up @@ -56,20 +53,18 @@ pub(crate) fn disable_multitasking() {
xtensa_lx::interrupt::disable_mask(SW_INTERRUPT);
}

extern "C" fn timer_tick_handler() {
extern "C" fn timer_tick_handler(context: &mut TrapFrame) {
TIMER.with(|timer| {
let timer = unwrap!(timer.as_mut());
timer.clear_interrupt();
});

// For unknown reasons, task_switch would end up generating an exception when
// called at priority 1, so trigger the level 3 interrupt instead.
yield_task();
task_switch(context);
}

#[allow(non_snake_case)]
#[no_mangle]
fn Software1(_level: u32, context: &mut TrapFrame) {
fn Software0(_level: u32, context: &mut TrapFrame) {
let intr = SW_INTERRUPT;
unsafe { core::arch::asm!("wsr.intclear {0}", in(reg) intr, options(nostack)) };

Expand Down

0 comments on commit 105ca14

Please sign in to comment.