diff options
| -rw-r--r-- | embassy-stm32-wpan/src/ble.rs | 9 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/lib.rs | 78 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mm.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sys.rs | 9 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/unsafe_linked_list.rs | 186 | ||||
| -rw-r--r-- | tests/stm32/Cargo.toml | 2 | ||||
| -rw-r--r-- | tests/stm32/src/bin/tl_mbox.rs | 17 |
7 files changed, 229 insertions, 82 deletions
diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs index 19955a8a3..57348a925 100644 --- a/embassy-stm32-wpan/src/ble.rs +++ b/embassy-stm32-wpan/src/ble.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use embassy_stm32::ipcc::Ipcc; | 1 | use embassy_stm32::ipcc::Ipcc; |
| 4 | 2 | ||
| 5 | use crate::cmd::{CmdPacket, CmdSerial}; | 3 | use crate::cmd::{CmdPacket, CmdSerial}; |
| @@ -18,7 +16,7 @@ impl Ble { | |||
| 18 | unsafe { | 16 | unsafe { |
| 19 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | 17 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |
| 20 | 18 | ||
| 21 | TL_BLE_TABLE = MaybeUninit::new(BleTable { | 19 | TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable { |
| 22 | pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), | 20 | pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), |
| 23 | pcs_buffer: CS_BUFFER.as_ptr().cast(), | 21 | pcs_buffer: CS_BUFFER.as_ptr().cast(), |
| 24 | pevt_queue: EVT_QUEUE.as_ptr().cast(), | 22 | pevt_queue: EVT_QUEUE.as_ptr().cast(), |
| @@ -31,11 +29,8 @@ impl Ble { | |||
| 31 | 29 | ||
| 32 | pub(super) fn evt_handler() { | 30 | pub(super) fn evt_handler() { |
| 33 | unsafe { | 31 | unsafe { |
| 34 | let mut node_ptr = core::ptr::null_mut(); | ||
| 35 | let node_ptr_ptr: *mut _ = &mut node_ptr; | ||
| 36 | |||
| 37 | while !LinkedListNode::is_empty(EVT_QUEUE.as_mut_ptr()) { | 32 | while !LinkedListNode::is_empty(EVT_QUEUE.as_mut_ptr()) { |
| 38 | LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); | 33 | let node_ptr = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()); |
| 39 | 34 | ||
| 40 | let event = node_ptr.cast(); | 35 | let event = node_ptr.cast(); |
| 41 | let event = EvtBox::new(event); | 36 | let event = EvtBox::new(event); |
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index c37b67dc4..2852d6270 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | pub mod fmt; | 4 | pub mod fmt; |
| 5 | 5 | ||
| 6 | use core::mem::MaybeUninit; | 6 | use core::mem::MaybeUninit; |
| 7 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 7 | 8 | ||
| 8 | use cmd::CmdPacket; | 9 | use cmd::CmdPacket; |
| 9 | use embassy_futures::block_on; | 10 | use embassy_futures::block_on; |
| @@ -189,33 +190,76 @@ impl<'d> TlMbox<'d> { | |||
| 189 | into_ref!(ipcc); | 190 | into_ref!(ipcc); |
| 190 | 191 | ||
| 191 | unsafe { | 192 | unsafe { |
| 192 | TL_REF_TABLE = MaybeUninit::new(RefTable { | 193 | TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable { |
| 193 | device_info_table: TL_DEVICE_INFO_TABLE.as_mut_ptr(), | 194 | device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(), |
| 194 | ble_table: TL_BLE_TABLE.as_ptr(), | 195 | ble_table: TL_BLE_TABLE.as_ptr(), |
| 195 | thread_table: TL_THREAD_TABLE.as_ptr(), | 196 | thread_table: TL_THREAD_TABLE.as_ptr(), |
| 196 | sys_table: TL_SYS_TABLE.as_ptr(), | 197 | sys_table: TL_SYS_TABLE.as_ptr(), |
| 197 | mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(), | 198 | mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(), |
| 198 | traces_table: TL_TRACES_TABLE.as_ptr(), | 199 | traces_table: TL_TRACES_TABLE.as_ptr(), |
| 199 | mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(), | 200 | mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(), |
| 201 | // zigbee_table: TL_ZIGBEE_TABLE.as_ptr(), | ||
| 202 | // lld_tests_table: TL_LLD_TESTS_TABLE.as_ptr(), | ||
| 203 | // ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(), | ||
| 200 | }); | 204 | }); |
| 201 | 205 | ||
| 202 | TL_SYS_TABLE = MaybeUninit::zeroed(); | 206 | TL_SYS_TABLE |
| 203 | TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed(); | 207 | .as_mut_ptr() |
| 204 | TL_BLE_TABLE = MaybeUninit::zeroed(); | 208 | .write_volatile(MaybeUninit::zeroed().assume_init()); |
| 205 | TL_THREAD_TABLE = MaybeUninit::zeroed(); | 209 | TL_DEVICE_INFO_TABLE |
| 206 | TL_MEM_MANAGER_TABLE = MaybeUninit::zeroed(); | 210 | .as_mut_ptr() |
| 207 | TL_TRACES_TABLE = MaybeUninit::zeroed(); | 211 | .write_volatile(MaybeUninit::zeroed().assume_init()); |
| 208 | TL_MAC_802_15_4_TABLE = MaybeUninit::zeroed(); | 212 | TL_BLE_TABLE |
| 209 | 213 | .as_mut_ptr() | |
| 210 | EVT_POOL = MaybeUninit::zeroed(); | 214 | .write_volatile(MaybeUninit::zeroed().assume_init()); |
| 211 | SYS_SPARE_EVT_BUF = MaybeUninit::zeroed(); | 215 | TL_THREAD_TABLE |
| 212 | BLE_SPARE_EVT_BUF = MaybeUninit::zeroed(); | 216 | .as_mut_ptr() |
| 213 | 217 | .write_volatile(MaybeUninit::zeroed().assume_init()); | |
| 214 | CS_BUFFER = MaybeUninit::zeroed(); | 218 | TL_MEM_MANAGER_TABLE |
| 215 | BLE_CMD_BUFFER = MaybeUninit::zeroed(); | 219 | .as_mut_ptr() |
| 216 | HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); | 220 | .write_volatile(MaybeUninit::zeroed().assume_init()); |
| 221 | |||
| 222 | TL_TRACES_TABLE | ||
| 223 | .as_mut_ptr() | ||
| 224 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 225 | TL_MAC_802_15_4_TABLE | ||
| 226 | .as_mut_ptr() | ||
| 227 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 228 | // TL_ZIGBEE_TABLE | ||
| 229 | // .as_mut_ptr() | ||
| 230 | // .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 231 | // TL_LLD_TESTS_TABLE | ||
| 232 | // .as_mut_ptr() | ||
| 233 | // .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 234 | // TL_BLE_LLD_TABLE | ||
| 235 | // .as_mut_ptr() | ||
| 236 | // .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 237 | |||
| 238 | EVT_POOL | ||
| 239 | .as_mut_ptr() | ||
| 240 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 241 | SYS_SPARE_EVT_BUF | ||
| 242 | .as_mut_ptr() | ||
| 243 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 244 | BLE_SPARE_EVT_BUF | ||
| 245 | .as_mut_ptr() | ||
| 246 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 247 | |||
| 248 | { | ||
| 249 | BLE_CMD_BUFFER | ||
| 250 | .as_mut_ptr() | ||
| 251 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 252 | HCI_ACL_DATA_BUFFER | ||
| 253 | .as_mut_ptr() | ||
| 254 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 255 | CS_BUFFER | ||
| 256 | .as_mut_ptr() | ||
| 257 | .write_volatile(MaybeUninit::zeroed().assume_init()); | ||
| 258 | } | ||
| 217 | } | 259 | } |
| 218 | 260 | ||
| 261 | compiler_fence(Ordering::SeqCst); | ||
| 262 | |||
| 219 | Ipcc::enable(config); | 263 | Ipcc::enable(config); |
| 220 | 264 | ||
| 221 | sys::Sys::enable(); | 265 | sys::Sys::enable(); |
diff --git a/embassy-stm32-wpan/src/mm.rs b/embassy-stm32-wpan/src/mm.rs index ed13b0dbf..06063b89a 100644 --- a/embassy-stm32-wpan/src/mm.rs +++ b/embassy-stm32-wpan/src/mm.rs | |||
| @@ -1,7 +1,5 @@ | |||
| 1 | //! Memory manager routines | 1 | //! Memory manager routines |
| 2 | 2 | ||
| 3 | use core::mem::MaybeUninit; | ||
| 4 | |||
| 5 | use embassy_stm32::ipcc::Ipcc; | 3 | use embassy_stm32::ipcc::Ipcc; |
| 6 | 4 | ||
| 7 | use crate::evt::EvtPacket; | 5 | use crate::evt::EvtPacket; |
| @@ -20,7 +18,7 @@ impl MemoryManager { | |||
| 20 | LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); | 18 | LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); |
| 21 | LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); | 19 | LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); |
| 22 | 20 | ||
| 23 | TL_MEM_MANAGER_TABLE = MaybeUninit::new(MemManagerTable { | 21 | TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable { |
| 24 | spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), | 22 | spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), |
| 25 | spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), | 23 | spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), |
| 26 | blepool: EVT_POOL.as_ptr().cast(), | 24 | blepool: EVT_POOL.as_ptr().cast(), |
| @@ -53,11 +51,9 @@ impl MemoryManager { | |||
| 53 | /// gives free event buffers back to CPU2 from local buffer queue | 51 | /// gives free event buffers back to CPU2 from local buffer queue |
| 54 | pub fn send_free_buf() { | 52 | pub fn send_free_buf() { |
| 55 | unsafe { | 53 | unsafe { |
| 56 | let mut node_ptr = core::ptr::null_mut(); | ||
| 57 | let node_ptr_ptr: *mut _ = &mut node_ptr; | ||
| 58 | |||
| 59 | while !LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { | 54 | while !LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { |
| 60 | LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), node_ptr_ptr); | 55 | let node_ptr = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); |
| 56 | |||
| 61 | LinkedListNode::insert_tail( | 57 | LinkedListNode::insert_tail( |
| 62 | (*(*TL_REF_TABLE.as_ptr()).mem_manager_table).pevt_free_buffer_queue, | 58 | (*(*TL_REF_TABLE.as_ptr()).mem_manager_table).pevt_free_buffer_queue, |
| 63 | node_ptr, | 59 | node_ptr, |
diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs index a19d12d27..0cff5c746 100644 --- a/embassy-stm32-wpan/src/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use embassy_stm32::ipcc::Ipcc; | 1 | use embassy_stm32::ipcc::Ipcc; |
| 4 | 2 | ||
| 5 | use crate::cmd::{CmdPacket, CmdSerial}; | 3 | use crate::cmd::{CmdPacket, CmdSerial}; |
| @@ -15,7 +13,7 @@ impl Sys { | |||
| 15 | unsafe { | 13 | unsafe { |
| 16 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | 14 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |
| 17 | 15 | ||
| 18 | TL_SYS_TABLE = MaybeUninit::new(SysTable { | 16 | TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable { |
| 19 | pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), | 17 | pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), |
| 20 | sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), | 18 | sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), |
| 21 | }) | 19 | }) |
| @@ -47,11 +45,8 @@ impl Sys { | |||
| 47 | 45 | ||
| 48 | pub fn evt_handler() { | 46 | pub fn evt_handler() { |
| 49 | unsafe { | 47 | unsafe { |
| 50 | let mut node_ptr = core::ptr::null_mut(); | ||
| 51 | let node_ptr_ptr: *mut _ = &mut node_ptr; | ||
| 52 | |||
| 53 | while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { | 48 | while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { |
| 54 | LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); | 49 | let node_ptr = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |
| 55 | 50 | ||
| 56 | let event = node_ptr.cast(); | 51 | let event = node_ptr.cast(); |
| 57 | let event = EvtBox::new(event); | 52 | let event = EvtBox::new(event); |
diff --git a/embassy-stm32-wpan/src/unsafe_linked_list.rs b/embassy-stm32-wpan/src/unsafe_linked_list.rs index 52c106fa2..a312178b3 100644 --- a/embassy-stm32-wpan/src/unsafe_linked_list.rs +++ b/embassy-stm32-wpan/src/unsafe_linked_list.rs | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | unused_mut | 11 | unused_mut |
| 12 | )] | 12 | )] |
| 13 | 13 | ||
| 14 | use core::ptr; | ||
| 15 | |||
| 14 | use cortex_m::interrupt; | 16 | use cortex_m::interrupt; |
| 15 | 17 | ||
| 16 | #[derive(Copy, Clone)] | 18 | #[derive(Copy, Clone)] |
| @@ -30,55 +32,136 @@ impl Default for LinkedListNode { | |||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | impl LinkedListNode { | 34 | impl LinkedListNode { |
| 33 | pub unsafe fn init_head(mut list_head: *mut LinkedListNode) { | 35 | pub unsafe fn init_head(mut p_list_head: *mut LinkedListNode) { |
| 34 | (*list_head).next = list_head; | 36 | ptr::write_volatile( |
| 35 | (*list_head).prev = list_head; | 37 | p_list_head, |
| 38 | LinkedListNode { | ||
| 39 | next: p_list_head, | ||
| 40 | prev: p_list_head, | ||
| 41 | }, | ||
| 42 | ); | ||
| 36 | } | 43 | } |
| 37 | 44 | ||
| 38 | pub unsafe fn is_empty(mut list_head: *mut LinkedListNode) -> bool { | 45 | pub unsafe fn is_empty(mut p_list_head: *mut LinkedListNode) -> bool { |
| 39 | interrupt::free(|_| ((*list_head).next) == list_head) | 46 | interrupt::free(|_| ptr::read_volatile(p_list_head).next == p_list_head) |
| 40 | } | 47 | } |
| 41 | 48 | ||
| 42 | pub unsafe fn insert_head(mut list_head: *mut LinkedListNode, mut node: *mut LinkedListNode) { | 49 | /// Insert `node` after `list_head` and before the next node |
| 50 | pub unsafe fn insert_head(mut p_list_head: *mut LinkedListNode, mut p_node: *mut LinkedListNode) { | ||
| 43 | interrupt::free(|_| { | 51 | interrupt::free(|_| { |
| 44 | (*node).next = (*list_head).next; | 52 | let mut list_head = ptr::read_volatile(p_list_head); |
| 45 | (*node).prev = list_head; | 53 | if p_list_head != list_head.next { |
| 46 | (*list_head).next = node; | 54 | let mut node_next = ptr::read_volatile(list_head.next); |
| 47 | (*(*node).next).prev = node; | 55 | let node = LinkedListNode { |
| 56 | next: list_head.next, | ||
| 57 | prev: p_list_head, | ||
| 58 | }; | ||
| 59 | |||
| 60 | list_head.next = p_node; | ||
| 61 | node_next.prev = p_node; | ||
| 62 | |||
| 63 | // All nodes must be written because they will all be seen by another core | ||
| 64 | ptr::write_volatile(p_node, node); | ||
| 65 | ptr::write_volatile(node.next, node_next); | ||
| 66 | ptr::write_volatile(p_list_head, list_head); | ||
| 67 | } else { | ||
| 68 | let node = LinkedListNode { | ||
| 69 | next: list_head.next, | ||
| 70 | prev: p_list_head, | ||
| 71 | }; | ||
| 72 | |||
| 73 | list_head.next = p_node; | ||
| 74 | list_head.prev = p_node; | ||
| 75 | |||
| 76 | // All nodes must be written because they will all be seen by another core | ||
| 77 | ptr::write_volatile(p_node, node); | ||
| 78 | ptr::write_volatile(p_list_head, list_head); | ||
| 79 | } | ||
| 48 | }); | 80 | }); |
| 49 | } | 81 | } |
| 50 | 82 | ||
| 51 | pub unsafe fn insert_tail(mut list_head: *mut LinkedListNode, mut node: *mut LinkedListNode) { | 83 | /// Insert `node` before `list_tail` and after the second-to-last node |
| 84 | pub unsafe fn insert_tail(mut p_list_tail: *mut LinkedListNode, mut p_node: *mut LinkedListNode) { | ||
| 52 | interrupt::free(|_| { | 85 | interrupt::free(|_| { |
| 53 | (*node).next = list_head; | 86 | let mut list_tail = ptr::read_volatile(p_list_tail); |
| 54 | (*node).prev = (*list_head).prev; | 87 | if p_list_tail != list_tail.prev { |
| 55 | (*list_head).prev = node; | 88 | let mut node_prev = ptr::read_volatile(list_tail.prev); |
| 56 | (*(*node).prev).next = node; | 89 | let node = LinkedListNode { |
| 90 | next: p_list_tail, | ||
| 91 | prev: list_tail.prev, | ||
| 92 | }; | ||
| 93 | |||
| 94 | list_tail.prev = p_node; | ||
| 95 | node_prev.next = p_node; | ||
| 96 | |||
| 97 | // All nodes must be written because they will all be seen by another core | ||
| 98 | ptr::write_volatile(p_node, node); | ||
| 99 | ptr::write_volatile(node.prev, node_prev); | ||
| 100 | ptr::write_volatile(p_list_tail, list_tail); | ||
| 101 | } else { | ||
| 102 | let node = LinkedListNode { | ||
| 103 | next: p_list_tail, | ||
| 104 | prev: list_tail.prev, | ||
| 105 | }; | ||
| 106 | |||
| 107 | list_tail.prev = p_node; | ||
| 108 | list_tail.next = p_node; | ||
| 109 | |||
| 110 | // All nodes must be written because they will all be seen by another core | ||
| 111 | ptr::write_volatile(p_node, node); | ||
| 112 | ptr::write_volatile(p_list_tail, list_tail); | ||
| 113 | } | ||
| 57 | }); | 114 | }); |
| 58 | } | 115 | } |
| 59 | 116 | ||
| 60 | /// Remove `node` from the linked list | 117 | /// Remove `node` from the linked list |
| 61 | pub unsafe fn remove_node(mut node: *mut LinkedListNode) { | 118 | pub unsafe fn remove_node(mut p_node: *mut LinkedListNode) { |
| 62 | interrupt::free(|_| { | 119 | interrupt::free(|_| { |
| 63 | (*(*node).prev).next = (*node).next; | 120 | let node = ptr::read_volatile(p_node); |
| 64 | (*(*node).next).prev = (*node).prev; | 121 | if node.next != node.prev { |
| 122 | let mut node_next = ptr::read_volatile(node.next); | ||
| 123 | let mut node_prev = ptr::read_volatile(node.prev); | ||
| 124 | |||
| 125 | node_prev.next = node.next; | ||
| 126 | node_next.prev = node.prev; | ||
| 127 | |||
| 128 | ptr::write_volatile(node.next, node_next); | ||
| 129 | ptr::write_volatile(node.prev, node_prev); | ||
| 130 | } else { | ||
| 131 | let mut node_next = ptr::read_volatile(node.next); | ||
| 132 | |||
| 133 | node_next.next = node.next; | ||
| 134 | node_next.prev = node.prev; | ||
| 135 | |||
| 136 | ptr::write_volatile(node.next, node_next); | ||
| 137 | } | ||
| 65 | }); | 138 | }); |
| 66 | } | 139 | } |
| 67 | 140 | ||
| 68 | /// Remove `list_head` into `node` | 141 | /// Remove `list_head` and return a pointer to the `node`. |
| 69 | pub unsafe fn remove_head(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 142 | pub unsafe fn remove_head(mut p_list_head: *mut LinkedListNode) -> *mut LinkedListNode { |
| 70 | interrupt::free(|_| { | 143 | interrupt::free(|_| { |
| 71 | *node = (*list_head).next; | 144 | let list_head = ptr::read_volatile(p_list_head); |
| 72 | Self::remove_node((*list_head).next); | 145 | |
| 73 | }); | 146 | // Allowed because a removed node is not seen by another core |
| 147 | let p_node = list_head.next; | ||
| 148 | Self::remove_node(p_node); | ||
| 149 | |||
| 150 | p_node | ||
| 151 | }) | ||
| 74 | } | 152 | } |
| 75 | 153 | ||
| 76 | /// Remove `list_tail` into `node` | 154 | /// Remove `list_tail` and return a pointer to the `node`. |
| 77 | pub unsafe fn remove_tail(mut list_tail: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 155 | pub unsafe fn remove_tail(mut p_list_tail: *mut LinkedListNode) -> *mut LinkedListNode { |
| 78 | interrupt::free(|_| { | 156 | interrupt::free(|_| { |
| 79 | *node = (*list_tail).prev; | 157 | let list_tail = ptr::read_volatile(p_list_tail); |
| 80 | Self::remove_node((*list_tail).prev); | 158 | |
| 81 | }); | 159 | // Allowed because a removed node is not seen by another core |
| 160 | let p_node = list_tail.prev; | ||
| 161 | Self::remove_node(p_node); | ||
| 162 | |||
| 163 | p_node | ||
| 164 | }) | ||
| 82 | } | 165 | } |
| 83 | 166 | ||
| 84 | pub unsafe fn insert_node_after(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { | 167 | pub unsafe fn insert_node_after(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { |
| @@ -88,6 +171,8 @@ impl LinkedListNode { | |||
| 88 | (*ref_node).next = node; | 171 | (*ref_node).next = node; |
| 89 | (*(*node).next).prev = node; | 172 | (*(*node).next).prev = node; |
| 90 | }); | 173 | }); |
| 174 | |||
| 175 | todo!("this function has not been converted to volatile semantics"); | ||
| 91 | } | 176 | } |
| 92 | 177 | ||
| 93 | pub unsafe fn insert_node_before(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { | 178 | pub unsafe fn insert_node_before(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { |
| @@ -97,6 +182,8 @@ impl LinkedListNode { | |||
| 97 | (*ref_node).prev = node; | 182 | (*ref_node).prev = node; |
| 98 | (*(*node).prev).next = node; | 183 | (*(*node).prev).next = node; |
| 99 | }); | 184 | }); |
| 185 | |||
| 186 | todo!("this function has not been converted to volatile semantics"); | ||
| 100 | } | 187 | } |
| 101 | 188 | ||
| 102 | pub unsafe fn get_size(mut list_head: *mut LinkedListNode) -> usize { | 189 | pub unsafe fn get_size(mut list_head: *mut LinkedListNode) -> usize { |
| @@ -111,18 +198,47 @@ impl LinkedListNode { | |||
| 111 | } | 198 | } |
| 112 | 199 | ||
| 113 | size | 200 | size |
| 114 | }) | 201 | }); |
| 202 | |||
| 203 | todo!("this function has not been converted to volatile semantics"); | ||
| 115 | } | 204 | } |
| 116 | 205 | ||
| 117 | pub unsafe fn get_next_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 206 | pub unsafe fn get_next_node(mut p_ref_node: *mut LinkedListNode) -> *mut LinkedListNode { |
| 118 | interrupt::free(|_| { | 207 | interrupt::free(|_| { |
| 119 | *node = (*ref_node).next; | 208 | let ref_node = ptr::read_volatile(p_ref_node); |
| 120 | }); | 209 | |
| 210 | // Allowed because a removed node is not seen by another core | ||
| 211 | ref_node.next | ||
| 212 | }) | ||
| 121 | } | 213 | } |
| 122 | 214 | ||
| 123 | pub unsafe fn get_prev_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 215 | pub unsafe fn get_prev_node(mut p_ref_node: *mut LinkedListNode) -> *mut LinkedListNode { |
| 124 | interrupt::free(|_| { | 216 | interrupt::free(|_| { |
| 125 | *node = (*ref_node).prev; | 217 | let ref_node = ptr::read_volatile(p_ref_node); |
| 126 | }); | 218 | |
| 219 | // Allowed because a removed node is not seen by another core | ||
| 220 | ref_node.prev | ||
| 221 | }) | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | #[allow(dead_code)] | ||
| 226 | unsafe fn debug_linked_list(mut p_node: *mut LinkedListNode) { | ||
| 227 | info!("iterating list from node: {:x}", p_node); | ||
| 228 | let mut p_current_node = p_node; | ||
| 229 | let mut i = 0; | ||
| 230 | loop { | ||
| 231 | let current_node = ptr::read_volatile(p_current_node); | ||
| 232 | info!( | ||
| 233 | "node (prev, current, next): {:x}, {:x}, {:x}", | ||
| 234 | current_node.prev, p_current_node, current_node.next | ||
| 235 | ); | ||
| 236 | |||
| 237 | i += 1; | ||
| 238 | if i > 10 || current_node.next == p_node { | ||
| 239 | break; | ||
| 240 | } | ||
| 241 | |||
| 242 | p_current_node = current_node.next; | ||
| 127 | } | 243 | } |
| 128 | } | 244 | } |
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index dcc7d9b8a..487ef4626 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -12,7 +12,7 @@ stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo | |||
| 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo | 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo |
| 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo | 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo |
| 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo | 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo |
| 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma" ] # Nucleo | 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble" ] # Nucleo |
| 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo | 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo |
| 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board | 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board |
| 18 | 18 | ||
diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs index b57519a54..4669cbc62 100644 --- a/tests/stm32/src/bin/tl_mbox.rs +++ b/tests/stm32/src/bin/tl_mbox.rs | |||
| @@ -10,6 +10,7 @@ use common::*; | |||
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::bind_interrupts; | 11 | use embassy_stm32::bind_interrupts; |
| 12 | use embassy_stm32::ipcc::Config; | 12 | use embassy_stm32::ipcc::Config; |
| 13 | use embassy_stm32_wpan::rc::RadioCoprocessor; | ||
| 13 | use embassy_stm32_wpan::TlMbox; | 14 | use embassy_stm32_wpan::TlMbox; |
| 14 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 15 | 16 | ||
| @@ -50,14 +51,14 @@ async fn main(_spawner: Spawner) { | |||
| 50 | Timer::after(Duration::from_millis(50)).await; | 51 | Timer::after(Duration::from_millis(50)).await; |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | // let mut rc = RadioCoprocessor::new(mbox); | 54 | let mut rc = RadioCoprocessor::new(mbox); |
| 54 | // | 55 | |
| 55 | // let response = rc.read().await; | 56 | let response = rc.read().await; |
| 56 | // info!("coprocessor ready {}", response); | 57 | info!("coprocessor ready {}", response); |
| 57 | // | 58 | |
| 58 | // rc.write(&[0x01, 0x03, 0x0c, 0x00, 0x00]); | 59 | rc.write(&[0x01, 0x03, 0x0c, 0x00, 0x00]); |
| 59 | // let response = rc.read().await; | 60 | let response = rc.read().await; |
| 60 | // info!("ble reset rsp {}", response); | 61 | info!("ble reset rsp {}", response); |
| 61 | 62 | ||
| 62 | info!("Test OK"); | 63 | info!("Test OK"); |
| 63 | cortex_m::asm::bkpt(); | 64 | cortex_m::asm::bkpt(); |
