embassy-rs/embassy · critical

this function has not been converted to volatile semantics

Error message

this function has not been converted to volatile semantics

What it means

`insert_node_before` in the WPAN unsafe linked list still performs raw pointer writes without volatile operations, which is required because the list is shared with the wireless coprocessor core. The function deliberately panics with `todo!` until it is ported to volatile semantics, so it must not be called.

Solutions

  1. Do not call `insert_node_before`; use the higher-level embassy-stm32-wpan APIs (BLE/MAC stack entry points) that manage the list.
  2. Use `remove_node`/`get_next_node`/`get_size`-style operations that have been converted to volatile access.
  3. Implement the insertion yourself with `ptr::read_volatile`/`write_volatile` if you must manipulate the shared list.
  4. Check embassy-stm32-wpan releases/changelog for when volatile semantics land for this function.

Example fix

// before
unsafe { unsafe_linked_list::insert_node_before(cs, node, ref_node) };
// after (volatile-equivalent, or use supported APIs)
unsafe {
    (*node).next = ptr::read_volatile(ref_node);
    (*node).prev = ptr::read_volatile((*ref_node).prev);
    ptr::write_volatile(&mut (*ref_node).prev, node);
    let prev = ptr::read_volatile((*node).prev);
    ptr::write_volatile(&mut (*prev).next, node);
}
Defensive patterns

Strategy: validation

Validate before calling

// Avoid the panicking helper entirely; use only volatile-converted ops:
// safe alternatives: remove_node, get_next_node
// fn uses_supported_list_apis(code: &str) -> bool {
//     !code.contains("insert_node_before")
// }

Prevention

When it happens

Trigger: Calling `unsafe_linked_list::insert_node_before(...)` — any invocation panics after mutating the list pointers, leaving the list corrupted before the panic.

Common situations: Extending the embassy-stm32-wpan stack with custom list operations; calling internal WPAN list helpers directly instead of the higher-level BLE/MAC APIs; porting code from older versions of the wpan crate where the function existed.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/23e7841d40dfdd19. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32-wpan/src/wb/unsafe_linked_list.rs:210

        ref_node.next = p_node;
        prev_node.prev = p_node;

        ptr::write_volatile(p_node, node);
        ptr::write_volatile(p_ref_node, ref_node);
        ptr::write_volatile(node.next, prev_node);
    }

    pub unsafe fn insert_node_before(
        _cs: CriticalSection,
        mut node: *mut LinkedListNode,
        mut ref_node: *mut LinkedListNode,
    ) {
        (*node).next = ref_node;
        (*node).prev = (*ref_node).prev;
        (*ref_node).prev = node;
        (*(*node).prev).next = node;

        todo!("this function has not been converted to volatile semantics");
    }

    pub unsafe fn get_size(_cs: CriticalSection, mut list_head: *mut LinkedListNode) -> usize {
        let mut size = 0;
        let mut temp: *mut LinkedListNode = core::ptr::null_mut::<LinkedListNode>();

        temp = (*list_head).next;
        while temp != list_head {
            size += 1;
            temp = (*temp).next
        }

        let _ = size;

        todo!("this function has not been converted to volatile semantics");
    }

    pub unsafe fn get_next_node(_cs: CriticalSection, mut p_ref_node: *mut LinkedListNode) -> *mut LinkedListNode {

View on GitHub (pinned to 463a07b963)