-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding a way to deinitialize the WiFi stack. #2187
base: main
Are you sure you want to change the base?
Conversation
b6ee505
to
89132fa
Compare
@@ -13,6 +13,7 @@ categories = ["embedded", "hardware-support", "no-std"] | |||
|
|||
[dependencies] | |||
defmt = { version = "0.3.8", optional = true } | |||
bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "macros", "async"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's not good - we won't be able to release esp-wifi with a git dependency - and also users are free to use any BLE stack they want
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I'm excited to see this land!
I see the core functionality is in place (minus the c2 issues) but I think the API surface could do with some polish.
info!("WiFi and BLE coexistence deinitialized"); | ||
|
||
// Drop the WiFi controller and stack | ||
drop(controller); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call drop manually here.
drop(controller); | ||
drop(stack); | ||
drop(ble); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need to stop the timer responsible for task switching (this was @bugadani's main complaint iirc) so for both arch's we need an equivalent setup_timer
to tear down the timer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, my stuff was really sensitive to the periodic interruptions caused by the scheduler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be probably safer to also unlisten interrupts related to the radio peripherals
)) | ||
} | ||
|
||
pub fn reinitialize( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we drop this function and just use initialize instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would pretty much prefer that 👍
@@ -282,7 +282,7 @@ impl<'a, MODE: WifiDeviceMode> WifiStack<'a, MODE> { | |||
/// Create a new [Socket] | |||
#[cfg(feature = "tcp")] | |||
pub fn get_socket<'s>( | |||
&'s self, | |||
&'s mut self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bjoernQ I'm not that familiar with the stack, but I think this should stay as &self
? That's why we wrap things in refcell internally, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, agree, I've covered it in masked User can't create more than 1 socket at this point
item of a TODO list above 😆
Will do something about that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely - having only one socket is quite limiting 🤣
common_adapter::RADIO_CLOCKS, | ||
hal::system::{RadioClockController, RadioPeripherals}, | ||
}; | ||
|
||
// use crate::{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove these if they're not used
@@ -215,12 +215,21 @@ extern "C" { | |||
|
|||
pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32; | |||
|
|||
// #[cfg(not(esp32c2))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove these if they are useless
esp_wifi_result!(unsafe { esp_wifi_stop() })?; | ||
esp_wifi_result!(unsafe { esp_wifi_deinit_internal() })?; | ||
|
||
// Deinitialize BLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should resuse the deinitialize_ble
etc methods here in the deinit all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, we shouldn't care about what network or Bluetooth stack the user is using - e.g. they can use embassy-net instead and they can use Trouble instead of bleps. Users can even directly deal with HCI and use raw smoltcp
|
||
bt_periph_module_disable(); | ||
|
||
// npl::esp_ble_unregister_bb_funcs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed?
let event = event.cast_mut(); | ||
|
||
if (*event).dummy == 0 { | ||
panic!("Trying to deinitialize an uninitialized event"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a bit sus, was this just test code or do the blobs really emit empty events?
unsafe { | ||
// HCI deinit | ||
npl::r_ble_hci_trans_cfg_hs( | ||
Some(core::mem::transmute::< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks sus, these should be None
when null, shouldn't they?
Some(core::mem::transmute::< | ||
*const (), | ||
unsafe extern "C" fn(*const u8, *const c_void), | ||
>(core::ptr::null())), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
unsafe { | ||
// HCI deinit | ||
npl::r_ble_hci_trans_cfg_hs( | ||
Some(core::mem::transmute::< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
#[non_exhaustive] | ||
/// An internal struct designed to make [`EspWifiDeinitialization`] uncreatable | ||
/// outside of this crate. | ||
pub struct EspWifiDeinitializationInternal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't need multiple internal-but-externally-not-constructible types
@@ -290,7 +314,7 @@ impl EspWifiTimerSource for TimeBase { | |||
/// # } | |||
/// ``` | |||
pub fn initialize( | |||
init_for: EspWifiInitFor, | |||
init_for: EspWifiFor, | |||
timer: impl EspWifiTimerSource, | |||
rng: hal::rng::Rng, | |||
radio_clocks: hal::peripherals::RADIO_CLK, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing we'll need to pass peripherals as impl Peripheral
and bind their lifetimes in EspWifiInitialization
so that they aren't reused before deinited. Then we'd pass EspWifiInitialization
to the deinit functions, which may return a different EspWifiInitialization
if they only partially deinit, or ()
if everything was dropped.
#[derive(Debug, PartialEq, PartialOrd)] | ||
#[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
/// Represents the state of being deinitialized for WiFi, Bluetooth or both. | ||
pub enum EspWifiDeinitialization { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get why this is needed. Just transform EspWifiInitialization
if something changes.
Awesome achievement and a great start! I'm not a huge fan of renaming |
Thank you for your contribution!
We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:
Submission Checklist 📝
cargo xtask fmt-packages
command to ensure that all changed code is formatted correctly.CHANGELOG.md
in the proper section.Extra:
Pull Request Details 📖
closes #1604
Description
Problems to be fixed:
NPL
BLE chipscoex
mode, but not when usingBLE
alone.However, I decided to do at least a Draft PR to get some feedback or implementation suggestions
Testing
Some short examples (will
BLE:
Wi-Fi:
Coex: