{"record":{"id":"3edc149056e7e647","repo":"embassy-rs/embassy","slug":"take-called-more-than-once","errorCode":null,"errorMessage":"take called more than once!","messagePattern":"take called more than once!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-rp/src/interpolator.rs","lineNumber":140,"sourceCode":"        /// Interpolator peripheral type.\n        #[derive(Copy, Clone)]\n        pub struct $interp {\n            not_send: PhantomData<*const ()>,\n        }\n\n        impl $interp {\n            ///Returns the peripheral *once* for each core. Panics if called more than once per core.\n            pub fn take() -> $crate::Peri<'static, Self> {\n                critical_section::with(Self::take_with_cs)\n            }\n\n            fn take_with_cs(_cs: critical_section::CriticalSection) -> $crate::Peri<'static, Self> {\n                #[unsafe(no_mangle)]\n                static mut $static: [bool; 2] = [false, false];\n\n                unsafe {\n                    if $static[current_core()] {\n                        panic!(\"take called more than once!\");\n                    }\n                    $static[current_core()] = true;\n\n                    Self::steal()\n                }\n            }\n\n            /// Unsafely create an instance of this peripheral out of thin air.\n            ///\n            /// # Safety\n            ///\n            /// You must ensure that you're only using one instance of this type at a time.\n            #[inline]\n            pub unsafe fn steal() -> $crate::Peri<'static, Self> {\n                $crate::Peri::new_unchecked(Self {\n                    not_send: PhantomData,\n                })\n            }","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-rp/src/interpolator.rs#L122-L158","documentation":"This panic is in the `impl_peri_interpolators`-style `take_with_cs` glue generated by a macro in embassy-rp's interpolator module. Each interpolator peripheral tracks a per-core `[bool; 2]` flag; if `take`/`take_with_cs` is called twice for the same peripheral on the same core, it panics to enforce single ownership of the hardware block.","triggerScenarios":"Calling the interpolator's `take()` (or take_with_cs) more than once for the same interpolator instance on the same core — e.g. constructing two interpolator wrapper objects from the same static, or re-running init code after it already succeeded.","commonSituations":"Retry logic that re-runs peripheral setup, shared helper functions called from multiple places, or test harnesses initializing the same interpolator repeatedly on core0/core1.","solutions":["Ensure `take`/`take_with_cs` for each interpolator is called exactly once per core; store the returned Peri and reuse it","Pass the already-taken interpolator handle into second consumers instead of stealing again","If ownership must move between tasks, structure code so the Peri is passed along rather than re-taken"],"exampleFix":"// before\nlet interp1 = Interp::<0, 0>::take();\nlet interp1b = Interp::<0, 0>::take(); // panics\n// after\nlet interp1 = Interp::<0, 0>::take();\nuse_interp(&interp1);\nuse_interp(&interp1); // reuse the same handle","handlingStrategy":"type-guard","validationCode":"static TAKEN: AtomicBool = AtomicBool::new(false);\nif TAKEN.swap(true, Ordering::SeqCst) { /* skip re-take */ }","typeGuard":"fn already_taken(flag: &[bool; 2], core: usize) -> bool { flag[core] }","tryCatchPattern":null,"preventionTips":["Call peripheral take() once during init and store the handle statically","Avoid re-running init code paths on retry","Pass Peri handles by reference instead of re-taking"],"tags":["embedded","ownership","peripheral","rust"],"backgroundTag":"file-already-exists","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}