pub fn start(&'static mut self, priority: interrupt::Priority) -> SendSpawner {
        if self
            .core
            .compare_exchange(
                usize::MAX,
                Cpu::current() as usize,
                Ordering::Acquire,
                Ordering::Relaxed,
            )
            .is_err()
        {
            panic!("InterruptExecutor::start() called multiple times on the same executor.");
        }

        unsafe {
            (*self.executor.get())
                .as_mut_ptr()
                .write(InnerExecutor::new(priority, (SWI as usize) as *mut ()));

            EXECUTORS[SWI as usize].set((*self.executor.get()).as_mut_ptr());
        }

        let swi_handler = match SWI {
            0 => handle_interrupt::<0>,
            1 => handle_interrupt::<1>,
            2 => handle_interrupt::<2>,
            #[cfg(not(multi_core))]
            3 => handle_interrupt::<3>,
            _ => unreachable!(),
        };

        self.interrupt
            .set_interrupt_handler(InterruptHandler::new(swi_handler, priority));

        let executor = unsafe { (*self.executor.get()).assume_init_ref() };
        executor.init();
        executor.inner.spawner().make_send()
    }
Start the executor at the given priority level.

This initializes the executor, enables the interrupt, and returns.
The executor keeps running in the background through the interrupt.

This returns a [`SendSpawner`] you can use to spawn tasks on it. A
[`SendSpawner`] is returned instead of a
[`Spawner`](embassy_executor::Spawner) because the
executor effectively runs in a different "thread" (the interrupt),
so spawning tasks on it is effectively sending them.

To obtain a [`Spawner`](embassy_executor::Spawner) for this executor,
use [`Spawner::for_current_executor`](embassy_executor::Spawner::for_current_executor)
from a task running in it.
esp-hal-embassy/src/executor/interrupt.rs