aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/wb55/sub/mm.rs
diff options
context:
space:
mode:
authorRaul Alimbekov <[email protected]>2025-12-16 09:05:22 +0300
committerGitHub <[email protected]>2025-12-16 09:05:22 +0300
commitc9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch)
tree6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-stm32-wpan/src/wb55/sub/mm.rs
parentcde24a3ef1117653ba5ed4184102b33f745782fb (diff)
parent5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff)
Merge branch 'main' into main
Diffstat (limited to 'embassy-stm32-wpan/src/wb55/sub/mm.rs')
-rw-r--r--embassy-stm32-wpan/src/wb55/sub/mm.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/embassy-stm32-wpan/src/wb55/sub/mm.rs b/embassy-stm32-wpan/src/wb55/sub/mm.rs
new file mode 100644
index 000000000..0ca7d1835
--- /dev/null
+++ b/embassy-stm32-wpan/src/wb55/sub/mm.rs
@@ -0,0 +1,84 @@
1//! Memory manager routines
2use core::future::poll_fn;
3use core::mem::MaybeUninit;
4use core::task::Poll;
5
6use aligned::{A4, Aligned};
7use embassy_stm32::ipcc::IpccTxChannel;
8use embassy_sync::waitqueue::AtomicWaker;
9
10use crate::consts::POOL_SIZE;
11use crate::evt;
12use crate::evt::EvtPacket;
13#[cfg(feature = "wb55_ble")]
14use crate::tables::BLE_SPARE_EVT_BUF;
15use crate::tables::{EVT_POOL, FREE_BUF_QUEUE, MemManagerTable, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE};
16use crate::unsafe_linked_list::LinkedListNode;
17
18static MM_WAKER: AtomicWaker = AtomicWaker::new();
19static mut LOCAL_FREE_BUF_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit());
20
21pub struct MemoryManager<'a> {
22 ipcc_mm_release_buffer_channel: IpccTxChannel<'a>,
23}
24
25impl<'a> MemoryManager<'a> {
26 pub(crate) fn new(ipcc_mm_release_buffer_channel: IpccTxChannel<'a>) -> Self {
27 unsafe {
28 LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr());
29 LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr());
30
31 TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable {
32 #[cfg(feature = "wb55_ble")]
33 spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(),
34 #[cfg(not(feature = "wb55_ble"))]
35 spare_ble_buffer: core::ptr::null(),
36 spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(),
37 blepool: EVT_POOL.as_ptr().cast(),
38 blepoolsize: POOL_SIZE as u32,
39 pevt_free_buffer_queue: FREE_BUF_QUEUE.as_mut_ptr(),
40 traces_evt_pool: core::ptr::null(),
41 tracespoolsize: 0,
42 });
43 }
44
45 Self {
46 ipcc_mm_release_buffer_channel,
47 }
48 }
49
50 pub async fn run_queue(&mut self) -> ! {
51 loop {
52 poll_fn(|cx| unsafe {
53 MM_WAKER.register(cx.waker());
54 if critical_section::with(|cs| LinkedListNode::is_empty(cs, LOCAL_FREE_BUF_QUEUE.as_mut_ptr())) {
55 Poll::Pending
56 } else {
57 Poll::Ready(())
58 }
59 })
60 .await;
61
62 self.ipcc_mm_release_buffer_channel
63 .send(|| {
64 critical_section::with(|cs| unsafe {
65 while let Some(node_ptr) = LinkedListNode::remove_head(cs, LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) {
66 LinkedListNode::insert_head(cs, FREE_BUF_QUEUE.as_mut_ptr(), node_ptr);
67 }
68 })
69 })
70 .await;
71 }
72 }
73}
74
75impl<'a> evt::MemoryManager for MemoryManager<'a> {
76 /// SAFETY: passing a pointer to something other than a managed event packet is UB
77 unsafe fn drop_event_packet(evt: *mut EvtPacket) {
78 critical_section::with(|cs| unsafe {
79 LinkedListNode::insert_head(cs, LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _);
80 });
81
82 MM_WAKER.wake();
83 }
84}