{"record":{"id":"1f962cf35173328d","repo":"embassy-rs/embassy","slug":"context-switching-only-supported-on-arm","errorCode":null,"errorMessage":"Context switching only supported on ARM","messagePattern":"Context switching only supported on ARM","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32-wpan/src/wba/context.rs","lineNumber":186,"sourceCode":"                self.do_switch(self.task_sp.get(), self.runner_sp.get());\n                // Returns here when runner resumes us\n            }\n            ContextManagerState::Uninitialized => warn!(\"task_yield called while uninitialized\"),\n            ContextManagerState::Yielded => warn!(\"task_yield called while yielded\"),\n        }\n    }\n\n    #[inline]\n    fn do_switch(&'static self, save_sp: *mut u32, restore_sp: *mut u32) {\n        #[cfg(target_arch = \"arm\")]\n        unsafe {\n            context_switch_asm(save_sp, restore_sp);\n        }\n\n        #[cfg(not(target_arch = \"arm\"))]\n        {\n            let _ = (save_sp, restore_sp);\n            panic!(\"Context switching only supported on ARM\");\n        }\n    }\n\n    pub fn in_task_context(&self) -> bool {\n        self.get_state() == ContextManagerState::Running\n    }\n\n    fn get_state(&self) -> ContextManagerState {\n        self.state.load(Ordering::Acquire).into()\n    }\n\n    fn set_state(&self, state: ContextManagerState) {\n        self.state.store(state as u8, Ordering::Release);\n    }\n}\n","sourceCodeStart":168,"sourceCodeEnd":202,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32-wpan/src/wba/context.rs#L168-L202","documentation":"The WBA context-switching implementation in embassy-stm32-wpan relies on hand-written ARM assembly (context_switch_asm) to save/restore stack pointers. On any non-ARM target_arch the cfg branch falls through to a panic in do_switch, since there is no portable context switch.","triggerScenarios":"Calling task_resume or task_yield on the ContextManager while compiling for a non-ARM target (e.g. x86_64 during host-side tests or simulation).","commonSituations":"Running unit tests of code that depends on the context manager with `cargo test` on a desktop x86 machine; accidentally building for a non-ARM target on an STM32WBA project.","solutions":["Build and run only on ARM targets (thumbv7em/thumbv8m etc.) — gate the context manager code behind target_arch = \"arm\"","Stub or mock the ContextManager in host-side tests with cfg(target_arch) conditionals","Use an emulator/QEMU ARM target instead of running on the host"],"exampleFix":"// before\ncm.task_yield(); // run on x86_64 host → panics\n// after\n#[cfg(target_arch = \"arm\")]\ncm.task_yield();\n#[cfg(not(target_arch = \"arm\"))]\nlog::warn!(\"task_yield not available on non-ARM targets\");","handlingStrategy":"type-guard","validationCode":"#[cfg(target_arch = \"arm\")]\nfn context_switching_supported() -> bool { true }\n#[cfg(not(target_arch = \"arm\"))]\nfn context_switching_supported() -> bool { false }","typeGuard":"fn is_arm_target() -> bool { cfg!(target_arch = \"arm\") }","tryCatchPattern":null,"preventionTips":["Only run context-manager code on ARM targets","Mock the ContextManager in host-side tests","Gate wpan/context modules behind target-specific cfgs"],"tags":["embedded","arm","platform","stm32"],"backgroundTag":"unsupported-platform","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}