Remove global wifi/ble init state tracking (#3553)

* Remove global wifi/ble init state tracking

* CHANGELOG.md

* Remove (now) redundant clippy-allow

* Cleanup after rebase

* Fix CHANGELOG

* Rebase

* Remove unused
This commit is contained in:
Björn Quentin 2025-06-10 11:31:11 +02:00 committed by GitHub
parent e3f847c9c8
commit 3893e5665b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 42 additions and 117 deletions

View File

@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Removed `esp_wifi::deinit_unchecked` and `esp_wifi::EspWifiController::deinit` - you can just drop `EspWifiController` instead (#3553)
### Fixed
@ -43,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Bump Rust edition to 2024, bump MSRV to 1.86. (#3391, #3560)
- Update `defmt` to 1.0 (#3416)
- The `log` feature has been replaced by `log-04`. (#3425)
- Removed `esp_wifi::deinit_unchecked` and `esp_wifi::EspWifiController::deinit` - you can just drop `EspWifiController` instead (#3553)
### Fixed

View File

@ -1 +1,12 @@
# Migration Guide from 0.14.0 to {{currentVersion}}
## Deinitialization
`esp_wifi::EspWifiController::deinit` got removed and you should just drop the `EspWifiController` instead.
```diff
- esp_wifi_ctrl.deinit();
+ core::mem::drop(esp_wifi_ctrl);
```
Since `esp_wifi::deinit_unchecked` is now removed there is no unsafe way to forcefully deinit the controller.
Drop the instance of `EspWifiController` instead (see above).

View File

@ -452,7 +452,6 @@ pub(crate) fn ble_init() {
API_vhci_host_register_callback(&VHCI_HOST_CALLBACK);
}
crate::flags::BLE.store(true, Ordering::Release);
}
pub(crate) fn ble_deinit() {
@ -464,7 +463,6 @@ pub(crate) fn ble_deinit() {
btdm_controller_deinit();
crate::common_adapter::chip_specific::phy_disable();
}
crate::flags::BLE.store(false, Ordering::Release);
}
pub fn send_hci(data: &[u8]) {

View File

@ -2,7 +2,6 @@ use alloc::boxed::Box;
use core::{
mem::size_of_val,
ptr::{addr_of, addr_of_mut},
sync::atomic::Ordering,
};
use super::*;
@ -1221,7 +1220,6 @@ pub(crate) fn ble_init() {
debug!("The ble_controller_init was initialized");
}
crate::flags::BLE.store(true, Ordering::Release);
}
pub(crate) fn ble_deinit() {
@ -1248,7 +1246,6 @@ pub(crate) fn ble_deinit() {
crate::common_adapter::chip_specific::phy_disable();
}
crate::flags::BLE.store(false, Ordering::Release);
}
#[cfg(esp32c2)]

View File

@ -117,7 +117,6 @@ use hal::{
time::Rate,
timer::{AnyTimer, PeriodicTimer, timg::Timer as TimgTimer},
};
use portable_atomic::Ordering;
#[cfg(feature = "wifi")]
use crate::wifi::WifiError;
@ -245,54 +244,25 @@ const _: () = {
type TimeBase = PeriodicTimer<'static, Blocking>;
pub(crate) mod flags {
use portable_atomic::AtomicBool;
pub(crate) static ESP_WIFI_INITIALIZED: AtomicBool = AtomicBool::new(false);
pub(crate) static WIFI: AtomicBool = AtomicBool::new(false);
pub(crate) static BLE: AtomicBool = AtomicBool::new(false);
}
#[derive(Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct EspWifiController<'d> {
_inner: PhantomData<&'d ()>,
}
impl EspWifiController<'_> {
/// Is the WiFi part of the radio running
pub fn wifi(&self) -> bool {
crate::flags::WIFI.load(Ordering::Acquire)
}
/// Is the BLE part of the radio running
pub fn ble(&self) -> bool {
crate::flags::BLE.load(Ordering::Acquire)
}
/// De-initialize the radio
pub fn deinit(self) -> Result<(), InitializationError> {
if crate::flags::ESP_WIFI_INITIALIZED.load(Ordering::Acquire) {
// safety: no other driver can be using this if this is callable
unsafe { deinit_unchecked() }
} else {
Ok(())
}
}
pub(crate) unsafe fn conjure() -> Self {
Self {
_inner: PhantomData,
}
}
}
impl Drop for EspWifiController<'_> {
fn drop(&mut self) {
if crate::flags::ESP_WIFI_INITIALIZED.load(Ordering::Acquire) {
// safety: no other driver can be using this if this is callable
unsafe { deinit_unchecked().ok() };
// Disable coexistence
#[cfg(coex)]
{
unsafe { crate::wifi::os_adapter::coex_disable() };
unsafe { crate::wifi::os_adapter::coex_deinit() };
}
shutdown_radio_isr();
// This shuts down the task switcher and timer tick interrupt.
preempt::disable();
}
}
@ -412,57 +382,11 @@ pub fn init<'d>(
error => return Err(InitializationError::General(error)),
}
crate::flags::ESP_WIFI_INITIALIZED.store(true, Ordering::Release);
Ok(EspWifiController {
_inner: PhantomData,
})
}
/// Deinitializes the entire radio stack
///
/// This can be useful to shutdown the stack before going to sleep for example.
///
/// # Safety
///
/// The user must ensure that any use of the radio via the WIFI/BLE/ESP-NOW
/// drivers are complete, else undefined behaviour may occur within those
/// drivers.
pub unsafe fn deinit_unchecked() -> Result<(), InitializationError> {
// Disable coexistence
#[cfg(coex)]
{
unsafe { crate::wifi::os_adapter::coex_disable() };
unsafe { crate::wifi::os_adapter::coex_deinit() };
}
let controller = unsafe { EspWifiController::conjure() };
// Peripheral drivers should already take care of shutting these down
// we have to check this in the case where a user calls `deinit_unchecked`
// directly.
if controller.wifi() {
#[cfg(feature = "wifi")]
crate::wifi::wifi_deinit()?;
crate::flags::WIFI.store(false, Ordering::Release);
}
if controller.ble() {
#[cfg(feature = "ble")]
crate::ble::ble_deinit();
crate::flags::BLE.store(false, Ordering::Release);
}
shutdown_radio_isr();
// This shuts down the task switcher and timer tick interrupt.
preempt::disable();
crate::flags::ESP_WIFI_INITIALIZED.store(false, Ordering::Release);
Ok(())
}
/// Returns true if at least some interrupt levels are disabled.
fn is_interrupts_disabled() -> bool {
#[cfg(target_arch = "xtensa")]

View File

@ -1360,8 +1360,6 @@ pub(crate) fn wifi_init() -> Result<(), WifiError> {
chip_specific::g_misc_nvs = addr_of!(NVS_STRUCT) as u32;
}
crate::flags::WIFI.store(true, Ordering::SeqCst);
Ok(())
}
}
@ -1398,11 +1396,10 @@ pub(crate) unsafe extern "C" fn coex_init() -> i32 {
0
}
pub(crate) fn wifi_deinit() -> Result<(), crate::InitializationError> {
fn wifi_deinit() -> Result<(), crate::InitializationError> {
esp_wifi_result!(unsafe { esp_wifi_stop() })?;
esp_wifi_result!(unsafe { esp_wifi_deinit_internal() })?;
esp_wifi_result!(unsafe { esp_supplicant_deinit() })?;
crate::flags::WIFI.store(false, Ordering::Release);
Ok(())
}
@ -2613,7 +2610,7 @@ pub struct Interfaces<'d> {
///
/// Make sure to **not** call this function while interrupts are disabled.
pub fn new<'d>(
inited: &'d EspWifiController<'d>,
_inited: &'d EspWifiController<'d>,
_device: crate::hal::peripherals::WIFI<'d>,
) -> Result<(WifiController<'d>, Interfaces<'d>), WifiError> {
if crate::is_interrupts_disabled() {
@ -2624,31 +2621,26 @@ pub fn new<'d>(
_phantom: Default::default(),
};
if !inited.wifi() {
crate::wifi::wifi_init()?;
crate::wifi::wifi_init()?;
let mut cntry_code = [0u8; 3];
cntry_code[..crate::CONFIG.country_code.len()]
.copy_from_slice(crate::CONFIG.country_code.as_bytes());
cntry_code[2] = crate::CONFIG.country_code_operating_class;
let mut cntry_code = [0u8; 3];
cntry_code[..crate::CONFIG.country_code.len()]
.copy_from_slice(crate::CONFIG.country_code.as_bytes());
cntry_code[2] = crate::CONFIG.country_code_operating_class;
#[allow(clippy::useless_transmute)]
unsafe {
let country = wifi_country_t {
// FIXME once we bumped the MSRV accordingly (see https://github.com/esp-rs/esp-hal/pull/3027#discussion_r1944718266)
#[allow(clippy::useless_transmute)]
cc: core::mem::transmute::<[u8; 3], [core::ffi::c_char; 3]>(cntry_code),
schan: 1,
nchan: 13,
max_tx_power: 20,
policy: wifi_country_policy_t_WIFI_COUNTRY_POLICY_MANUAL,
};
esp_wifi_result!(esp_wifi_set_country(&country))?;
}
controller.set_power_saving(PowerSaveMode::default())?;
unsafe {
let country = wifi_country_t {
cc: cntry_code,
schan: 1,
nchan: 13,
max_tx_power: 20,
policy: wifi_country_policy_t_WIFI_COUNTRY_POLICY_MANUAL,
};
esp_wifi_result!(esp_wifi_set_country(&country))?;
}
controller.set_power_saving(PowerSaveMode::default())?;
Ok((
controller,
Interfaces {