Skip to content

radio_esp32::osi

wifi_osi_funcs_t: the table Espressif’s blobs call out through.

Generated, not transcribed. The field list below was produced by parsing components/esp_wifi/include/esp_private/wifi_os_adapter.h from the pinned esp-idf release. That is deliberate: the struct is 115 function pointers with no names on the wire, so a single field transposed shifts every one after it and the blob calls the wrong function with the right arguments. Issue #65 names that failure exactly — “a working radio that corrupts memory”. Hand-typing it was not worth the risk.

The generator honours the target guards in the header, which matters: _slowclk_cal_get exists only on the S2, S3 and C3 and is absent here. Including it would have shifted the final sixteen fields, all of them coexistence, which is precisely the sort of fault that appears only when Wi-Fi and BLE run together.

[VERSION] and [MAGIC] are checked by the blob at init. They are the only cheap protection against being built against a different esp-idf than the one this table was generated from, so they are asserted here as well: a mismatch should fail loudly at our boundary rather than inside a binary we cannot debug.

struct WifiOsiFuncs {
pub _version: i32,
pub _env_is_chip: Option<fn(..)>,
pub _set_intr: Option<fn(..)>,
pub _clear_intr: Option<fn(..)>,
pub _set_isr: Option<fn(..)>,
pub _ints_on: Option<fn(..)>,
pub _ints_off: Option<fn(..)>,
pub _is_from_isr: Option<fn(..)>,
pub _spin_lock_create: Option<fn(..)>,
pub _spin_lock_delete: Option<fn(..)>,
pub _wifi_int_disable: Option<fn(..)>,
pub _wifi_int_restore: Option<fn(..)>,
pub _task_yield_from_isr: Option<fn(..)>,
pub _semphr_create: Option<fn(..)>,
pub _semphr_delete: Option<fn(..)>,
pub _semphr_take: Option<fn(..)>,
pub _semphr_give: Option<fn(..)>,
pub _wifi_thread_semphr_get: Option<fn(..)>,
pub _mutex_create: Option<fn(..)>,
pub _recursive_mutex_create: Option<fn(..)>,
pub _mutex_delete: Option<fn(..)>,
pub _mutex_lock: Option<fn(..)>,
pub _mutex_unlock: Option<fn(..)>,
pub _queue_create: Option<fn(..)>,
pub _queue_delete: Option<fn(..)>,
pub _queue_send: Option<fn(..)>,
pub _queue_send_from_isr: Option<fn(..)>,
pub _queue_send_to_back: Option<fn(..)>,
pub _queue_send_to_front: Option<fn(..)>,
pub _queue_recv: Option<fn(..)>,
pub _queue_msg_waiting: Option<fn(..)>,
pub _event_group_create: Option<fn(..)>,
pub _event_group_delete: Option<fn(..)>,
pub _event_group_set_bits: Option<fn(..)>,
pub _event_group_clear_bits: Option<fn(..)>,
pub _event_group_wait_bits: Option<fn(..)>,
pub _task_create_pinned_to_core: Option<fn(..)>,
pub _task_create: Option<fn(..)>,
pub _task_delete: Option<fn(..)>,
pub _task_delay: Option<fn(..)>,
pub _task_ms_to_tick: Option<fn(..)>,
pub _task_get_current_task: Option<fn(..)>,
pub _task_get_max_priority: Option<fn(..)>,
pub _malloc: Option<fn(..)>,
pub _free: Option<fn(..)>,
pub _event_post: Option<fn(..)>,
pub _get_free_heap_size: Option<fn(..)>,
pub _rand: Option<fn(..)>,
pub _dport_access_stall_other_cpu_start_wrap: Option<fn(..)>,
pub _dport_access_stall_other_cpu_end_wrap: Option<fn(..)>,
pub _wifi_apb80m_request: Option<fn(..)>,
pub _wifi_apb80m_release: Option<fn(..)>,
pub _phy_disable: Option<fn(..)>,
pub _phy_enable: Option<fn(..)>,
pub _phy_common_clock_enable: Option<fn(..)>,
pub _phy_common_clock_disable: Option<fn(..)>,
pub _phy_update_country_info: Option<fn(..)>,
pub _read_mac: Option<fn(..)>,
pub _timer_arm: Option<fn(..)>,
pub _timer_disarm: Option<fn(..)>,
pub _timer_done: Option<fn(..)>,
pub _timer_setfn: Option<fn(..)>,
pub _timer_arm_us: Option<fn(..)>,
pub _wifi_reset_mac: Option<fn(..)>,
pub _wifi_clock_enable: Option<fn(..)>,
pub _wifi_clock_disable: Option<fn(..)>,
pub _wifi_rtc_enable_iso: Option<fn(..)>,
pub _wifi_rtc_disable_iso: Option<fn(..)>,
pub _esp_timer_get_time: Option<fn(..)>,
pub _nvs_set_i8: Option<fn(..)>,
pub _nvs_get_i8: Option<fn(..)>,
pub _nvs_set_u8: Option<fn(..)>,
pub _nvs_get_u8: Option<fn(..)>,
pub _nvs_set_u16: Option<fn(..)>,
pub _nvs_get_u16: Option<fn(..)>,
pub _nvs_open: Option<fn(..)>,
pub _nvs_close: Option<fn(..)>,
pub _nvs_commit: Option<fn(..)>,
pub _nvs_set_blob: Option<fn(..)>,
pub _nvs_get_blob: Option<fn(..)>,
pub _nvs_erase_key: Option<fn(..)>,
pub _get_random: Option<fn(..)>,
pub _get_time: Option<fn(..)>,
pub _random: Option<fn(..)>,
pub _log_write: Option<fn(..)>,
pub _log_writev: Option<fn(..)>,
pub _log_timestamp: Option<fn(..)>,
pub _malloc_internal: Option<fn(..)>,
pub _realloc_internal: Option<fn(..)>,
pub _calloc_internal: Option<fn(..)>,
pub _zalloc_internal: Option<fn(..)>,
pub _wifi_malloc: Option<fn(..)>,
pub _wifi_realloc: Option<fn(..)>,
pub _wifi_calloc: Option<fn(..)>,
pub _wifi_zalloc: Option<fn(..)>,
pub _wifi_create_queue: Option<fn(..)>,
pub _wifi_delete_queue: Option<fn(..)>,
pub _coex_init: Option<fn(..)>,
pub _coex_deinit: Option<fn(..)>,
pub _coex_enable: Option<fn(..)>,
pub _coex_disable: Option<fn(..)>,
pub _coex_status_get: Option<fn(..)>,
pub _coex_condition_set: Option<fn(..)>,
pub _coex_wifi_request: Option<fn(..)>,
pub _coex_wifi_release: Option<fn(..)>,
pub _coex_wifi_channel_set: Option<fn(..)>,
pub _coex_event_duration_get: Option<fn(..)>,
pub _coex_pti_get: Option<fn(..)>,
pub _coex_schm_status_bit_clear: Option<fn(..)>,
pub _coex_schm_status_bit_set: Option<fn(..)>,
pub _coex_schm_interval_set: Option<fn(..)>,
pub _coex_schm_interval_get: Option<fn(..)>,
pub _coex_schm_curr_period_get: Option<fn(..)>,
pub _coex_schm_curr_phase_get: Option<fn(..)>,
pub _coex_schm_curr_phase_idx_set: Option<fn(..)>,
pub _coex_schm_curr_phase_idx_get: Option<fn(..)>,
pub _magic: i32,
}

The table itself.

_version first and _magic last, with the function pointers between them in header order. Every pointer is an Option, so a slot we have not implemented is a null the blob can be seen to trip over rather than a jump into whatever happened to be there.

const FIELD_NAMES: [&str; 115];

Every function field’s name, in header order.

The struct is #[repr(C)] with _version first and _magic last, so function n lives at word n + 1 — on a 64-bit host too, where the four bytes of padding after _version bring it to exactly one word.

Generated from the struct definition rather than retyped, for the reason the module docs give about the field list itself: a transposition here would name the wrong entry in a diagnostic, which is worse than no diagnostic. The the_names_line_up_with_the_fields test checks the ends and the count against the struct.

const FUNCTION_COUNT: usize;

Number of function pointers between _version and _magic.

const IDF_VERSION: &str;

esp-idf release this table was generated from.

const MAGIC: i32;

ESP_WIFI_OS_ADAPTER_MAGIC. Spelled “DEADBEAF”, not “DEADBEEF” — that is Espressif’s spelling and copying it correctly matters more than it reads.

const TIME_BLOCKING: u32;

OSI_FUNCS_TIME_BLOCKING — wait forever.

const VERSION: i32;

ESP_WIFI_OS_ADAPTER_VERSION from the pinned header.