Skip to content
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

Esp wifi/more dynamic allocations #2396

Merged
merged 41 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e611f82
Dynamic allocation of timers
bjoernQ Oct 18, 2024
02b0bc1
Replace statically allocated NPL events
bjoernQ Oct 21, 2024
583ff73
Remove NPL CALLOUTS
bjoernQ Oct 22, 2024
6ea93b4
Remove NPL EventQueue
bjoernQ Oct 22, 2024
f3cb198
Use `Vec` instead of `heapless::spsc::Queue` internally in NPL
bjoernQ Oct 22, 2024
160cd83
Use `alloc` since we have it in NPL
bjoernQ Oct 22, 2024
cd264e2
Refactor
bjoernQ Oct 22, 2024
e44a59e
Fix
bjoernQ Oct 22, 2024
20d4233
More `Vec`
bjoernQ Oct 22, 2024
6b8ef64
Fix
bjoernQ Oct 23, 2024
59da91b
Fix nightly-warnings
bjoernQ Oct 23, 2024
2e18cfd
Limit RX_STA queue
bjoernQ Oct 23, 2024
a55cf11
Revert unintentional change
bjoernQ Oct 23, 2024
e0685e4
esp-now: Make data private
bjoernQ Oct 23, 2024
79dd267
CHANGELOG.md
bjoernQ Oct 23, 2024
ab377ca
Clippy
bjoernQ Oct 23, 2024
1d0f3a1
MSRV
bjoernQ Oct 23, 2024
b11e293
Move locking into RawQueue
bjoernQ Oct 23, 2024
cd8287f
Remove unused import
bjoernQ Oct 23, 2024
af15488
Simplify `queue_recv`
bjoernQ Oct 24, 2024
4e803df
Address TODO
bjoernQ Oct 24, 2024
0641ab3
Clippy
bjoernQ Oct 24, 2024
965c829
Review I
bjoernQ Oct 28, 2024
1fc3572
Review II
bjoernQ Oct 28, 2024
358ac57
Clarify
bjoernQ Oct 28, 2024
45aa0da
Review III
bjoernQ Oct 28, 2024
fc50571
Review IV
bjoernQ Oct 28, 2024
6b7d0d3
Review V
bjoernQ Oct 28, 2024
0c83691
Fix
bjoernQ Oct 28, 2024
6c96917
`steal` RNG and RADIO_CLOCKS
bjoernQ Oct 28, 2024
06482b8
`drop_in_place`
bjoernQ Oct 29, 2024
dad5121
De-duplicate
bjoernQ Oct 29, 2024
d99e218
Use `VecDeque`
bjoernQ Oct 30, 2024
aa28e99
Revert unintentional changes
bjoernQ Oct 30, 2024
e4bdd57
Fix
bjoernQ Oct 30, 2024
9509d26
Update esp-wifi/MIGRATING-0.10.md
bjoernQ Oct 30, 2024
14530d2
assert
bjoernQ Oct 30, 2024
cccf6ac
Fix
bjoernQ Oct 30, 2024
dc818fc
Expect `*mut ConcurrentQueue` where applicable
bjoernQ Oct 30, 2024
43c6151
Comment why stealing is fine
bjoernQ Oct 31, 2024
033a42f
Fix
bjoernQ Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions esp-wifi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- No need to add `rom_functions.x` manually anymore (#2374)
- esp-now: Data is now private in `ReceivedData` - use `data()`(#2396)

### Fixed

Expand Down
6 changes: 6 additions & 0 deletions esp-wifi/MIGRATING-0.10.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ rustflags = [
- "-C", "link-arg=-Trom_functions.x",
]
```

## ESP-NOW: Use `data` to access the received payload

Previously `data` and `len` were public - use the previously already existing `data()` function.

Accessing `data` or `len` was never encouraged.
225 changes: 39 additions & 186 deletions esp-wifi/src/ble/btdm.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,30 @@
use core::{cell::RefCell, ptr::addr_of};
use alloc::boxed::Box;
use core::ptr::{addr_of, addr_of_mut};

use critical_section::Mutex;
use esp_wifi_sys::c_types::c_void;
use portable_atomic::{AtomicBool, Ordering};

use super::ReceivedPacket;
use crate::{
binary::include::*,
ble::{
btdm::ble_os_adapter_chip_specific::{osi_funcs_s, G_OSI_FUNCS},
HciOutCollector,
HCI_OUT_COLLECTOR,
},
compat::{common::str_from_c, queue::SimpleQueue},
compat::common::{self, str_from_c, ConcurrentQueue},
hal::macros::ram,
memory_fence::memory_fence,
timer::yield_task,
};

#[cfg_attr(esp32c3, path = "os_adapter_esp32c3.rs")]
#[cfg_attr(esp32s3, path = "os_adapter_esp32s3.rs")]
#[cfg_attr(esp32, path = "os_adapter_esp32.rs")]
pub(crate) mod ble_os_adapter_chip_specific;

static BT_RECEIVE_QUEUE: Mutex<RefCell<SimpleQueue<ReceivedPacket, 10>>> =
Mutex::new(RefCell::new(SimpleQueue::new()));

#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ReceivedPacket {
pub len: u8,
pub data: [u8; 256],
}

static BT_INTERNAL_QUEUE: Mutex<RefCell<SimpleQueue<[u8; 8], 10>>> =
Mutex::new(RefCell::new(SimpleQueue::new()));

static PACKET_SENT: AtomicBool = AtomicBool::new(true);

#[repr(C)]
struct vhci_host_callback_s {
struct VhciHostCallbacks {
notify_host_send_available: extern "C" fn(), /* callback used to notify that the host can
* send packet to controller */
notify_host_recv: extern "C" fn(*mut u8, u16) -> i32, /* callback used to notify that the
Expand All @@ -62,10 +49,10 @@ extern "C" {

fn API_vhci_host_check_send_available() -> bool;
fn API_vhci_host_send_packet(data: *const u8, len: u16);
fn API_vhci_host_register_callback(vhci_host_callbac: *const vhci_host_callback_s) -> i32;
fn API_vhci_host_register_callback(vhci_host_callbac: *const VhciHostCallbacks) -> i32;
}

static VHCI_HOST_CALLBACK: vhci_host_callback_s = vhci_host_callback_s {
static VHCI_HOST_CALLBACK: VhciHostCallbacks = VhciHostCallbacks {
notify_host_send_available,
notify_host_recv,
};
Expand All @@ -79,27 +66,21 @@ extern "C" fn notify_host_send_available() {
extern "C" fn notify_host_recv(data: *mut u8, len: u16) -> i32 {
trace!("notify_host_recv {:?} {}", data, len);

unsafe {
let mut buf = [0u8; 256];
buf[..len as usize].copy_from_slice(core::slice::from_raw_parts(data, len as usize));

let packet = ReceivedPacket {
len: len as u8,
data: buf,
};

critical_section::with(|cs| {
let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
if queue.enqueue(packet).is_err() {
warn!("Dropping BLE packet");
}
});
let data = unsafe { core::slice::from_raw_parts(data, len as usize) };

let packet = ReceivedPacket {
data: Box::from(data),
};

dump_packet_info(core::slice::from_raw_parts(data as *const u8, len as usize));
critical_section::with(|cs| {
let mut queue = super::BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
queue.push_back(packet);
});

#[cfg(feature = "async")]
crate::ble::controller::asynch::hci_read_data_available();
}
super::dump_packet_info(data);

#[cfg(feature = "async")]
crate::ble::controller::asynch::hci_read_data_available();

0
}
Expand Down Expand Up @@ -178,38 +159,21 @@ unsafe extern "C" fn mutex_unlock(_mutex: *const ()) -> i32 {
}

unsafe extern "C" fn queue_create(len: u32, item_size: u32) -> *const () {
if len != 5 && item_size != 8 {
panic!("Unexpected queue spec {} {}", len, item_size);
}
&BT_INTERNAL_QUEUE as *const _ as *const ()
let ptr = common::create_queue(len as i32, item_size as i32);
ptr.cast()
}

unsafe extern "C" fn queue_delete(queue: *const ()) {
trace!("Unimplemented queue_delete {:?}", queue);
common::delete_queue(queue as *mut ConcurrentQueue)
}

#[ram]
unsafe extern "C" fn queue_send(queue: *const (), item: *const (), _block_time_ms: u32) -> i32 {
if queue == &BT_INTERNAL_QUEUE as *const _ as *const () {
critical_section::with(|_| {
// assume the size is 8 - shouldn't rely on that
let message = item as *const u8;
let mut data = [0u8; 8];
for (i, data) in data.iter_mut().enumerate() {
*data = *message.add(i);
}
trace!("queue posting {:?}", data);

critical_section::with(|cs| {
let mut queue = BT_INTERNAL_QUEUE.borrow_ref_mut(cs);
unwrap!(queue.enqueue(data));
});
memory_fence();
});
} else {
panic!("Unknown queue");
}
1
unsafe extern "C" fn queue_send(queue: *const (), item: *const (), block_time_ms: u32) -> i32 {
common::send_queued(
queue as *mut ConcurrentQueue,
item as *mut c_void,
block_time_ms,
)
}

#[ram]
Expand All @@ -225,53 +189,11 @@ unsafe extern "C" fn queue_send_from_isr(
}

unsafe extern "C" fn queue_recv(queue: *const (), item: *const (), block_time_ms: u32) -> i32 {
trace!(
"queue_recv {:?} item {:?} block_time_tick {}",
queue,
item,
block_time_ms
);

let forever = block_time_ms == crate::compat::common::OSI_FUNCS_TIME_BLOCKING;
let start = crate::timer::get_systimer_count();
let block_ticks = crate::timer::millis_to_ticks(block_time_ms as u64);

// handle the BT_QUEUE
if queue == &BT_INTERNAL_QUEUE as *const _ as *const () {
loop {
let res = critical_section::with(|_| {
memory_fence();

critical_section::with(|cs| {
let mut queue = BT_INTERNAL_QUEUE.borrow_ref_mut(cs);
if let Some(message) = queue.dequeue() {
let item = item as *mut u8;
for i in 0..8 {
item.offset(i).write_volatile(message[i as usize]);
}
trace!("received {:?}", message);
1
} else {
0
}
})
});

if res == 1 {
trace!("queue_recv returns");
return res;
}

if !forever && crate::timer::elapsed_time_since(start) > block_ticks {
trace!("queue_recv returns with timeout");
return -1;
}

yield_task();
}
} else {
panic!("Unknown queue to handle in queue_recv");
}
common::receive_queued(
queue as *mut ConcurrentQueue,
item as *mut c_void,
block_time_ms,
)
}

#[ram]
Expand Down Expand Up @@ -444,7 +366,7 @@ unsafe extern "C" fn custom_queue_create(

pub(crate) fn ble_init() {
unsafe {
*(HCI_OUT_COLLECTOR.as_mut_ptr()) = HciOutCollector::new();
(*addr_of_mut!(HCI_OUT_COLLECTOR)).write(HciOutCollector::new());
// turn on logging
#[cfg(feature = "sys-logs")]
{
Expand Down Expand Up @@ -532,67 +454,8 @@ pub(crate) fn ble_deinit() {
}
}

static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256];
static mut BLE_HCI_READ_DATA_INDEX: usize = 0;
static mut BLE_HCI_READ_DATA_LEN: usize = 0;

#[cfg(feature = "async")]
pub(crate) fn have_hci_read_data() -> bool {
critical_section::with(|cs| {
let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
!queue.is_empty()
|| unsafe {
BLE_HCI_READ_DATA_LEN > 0 && (BLE_HCI_READ_DATA_LEN >= BLE_HCI_READ_DATA_INDEX)
}
})
}

pub(crate) fn read_next(data: &mut [u8]) -> usize {
critical_section::with(|cs| {
let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);

match queue.dequeue() {
Some(packet) => {
data[..packet.len as usize].copy_from_slice(&packet.data[..packet.len as usize]);
packet.len as usize
}
None => 0,
}
})
}

pub(crate) fn read_hci(data: &mut [u8]) -> usize {
unsafe {
if BLE_HCI_READ_DATA_LEN == 0 {
critical_section::with(|cs| {
let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);

if let Some(packet) = queue.dequeue() {
BLE_HCI_READ_DATA[..packet.len as usize]
.copy_from_slice(&packet.data[..packet.len as usize]);
BLE_HCI_READ_DATA_LEN = packet.len as usize;
BLE_HCI_READ_DATA_INDEX = 0;
}
});
}

if BLE_HCI_READ_DATA_LEN > 0 {
data[0] = BLE_HCI_READ_DATA[BLE_HCI_READ_DATA_INDEX];
BLE_HCI_READ_DATA_INDEX += 1;

if BLE_HCI_READ_DATA_INDEX >= BLE_HCI_READ_DATA_LEN {
BLE_HCI_READ_DATA_LEN = 0;
BLE_HCI_READ_DATA_INDEX = 0;
}
return 1;
}
}

0
}

pub(crate) fn send_hci(data: &[u8]) {
let hci_out = unsafe { &mut *HCI_OUT_COLLECTOR.as_mut_ptr() };
pub fn send_hci(data: &[u8]) {
let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
hci_out.push(data);

if hci_out.is_ready() {
Expand All @@ -611,7 +474,7 @@ pub(crate) fn send_hci(data: &[u8]) {
API_vhci_host_send_packet(packet.as_ptr(), packet.len() as u16);
trace!("sent vhci host packet");

dump_packet_info(packet);
super::dump_packet_info(packet);

break;
}
Expand All @@ -623,13 +486,3 @@ pub(crate) fn send_hci(data: &[u8]) {
hci_out.reset();
}
}

#[allow(unreachable_code, unused_variables)]
fn dump_packet_info(buffer: &[u8]) {
#[cfg(not(feature = "dump-packets"))]
return;

critical_section::with(|cs| {
info!("@HCIFRAME {:?}", buffer);
});
}
2 changes: 1 addition & 1 deletion esp-wifi/src/ble/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub mod asynch {

use super::{read_hci, send_hci, BleConnectorError};
use crate::{
ble::ble::have_hci_read_data,
ble::have_hci_read_data,
hal::peripheral::{Peripheral, PeripheralRef},
EspWifiInitialization,
};
Expand Down
Loading