aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32-wpan/src/ble.rs5
-rw-r--r--embassy-stm32-wpan/src/mm.rs6
-rw-r--r--embassy-stm32-wpan/src/sys.rs5
-rw-r--r--embassy-stm32-wpan/src/unsafe_linked_list.rs142
4 files changed, 100 insertions, 58 deletions
diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs
index ba369bb3a..57348a925 100644
--- a/embassy-stm32-wpan/src/ble.rs
+++ b/embassy-stm32-wpan/src/ble.rs
@@ -29,11 +29,8 @@ impl Ble {
29 29
30 pub(super) fn evt_handler() { 30 pub(super) fn evt_handler() {
31 unsafe { 31 unsafe {
32 let mut node_ptr = core::ptr::null_mut();
33 let node_ptr_ptr: *mut _ = &mut node_ptr;
34
35 while !LinkedListNode::is_empty(EVT_QUEUE.as_mut_ptr()) { 32 while !LinkedListNode::is_empty(EVT_QUEUE.as_mut_ptr()) {
36 LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); 33 let node_ptr = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr());
37 34
38 let event = node_ptr.cast(); 35 let event = node_ptr.cast();
39 let event = EvtBox::new(event); 36 let event = EvtBox::new(event);
diff --git a/embassy-stm32-wpan/src/mm.rs b/embassy-stm32-wpan/src/mm.rs
index 68db49b82..06063b89a 100644
--- a/embassy-stm32-wpan/src/mm.rs
+++ b/embassy-stm32-wpan/src/mm.rs
@@ -51,11 +51,9 @@ impl MemoryManager {
51 /// gives free event buffers back to CPU2 from local buffer queue 51 /// gives free event buffers back to CPU2 from local buffer queue
52 pub fn send_free_buf() { 52 pub fn send_free_buf() {
53 unsafe { 53 unsafe {
54 let mut node_ptr = core::ptr::null_mut();
55 let node_ptr_ptr: *mut _ = &mut node_ptr;
56
57 while !LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { 54 while !LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) {
58 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
59 LinkedListNode::insert_tail( 57 LinkedListNode::insert_tail(
60 (*(*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,
61 node_ptr, 59 node_ptr,
diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs
index f41fac58a..0cff5c746 100644
--- a/embassy-stm32-wpan/src/sys.rs
+++ b/embassy-stm32-wpan/src/sys.rs
@@ -45,11 +45,8 @@ impl Sys {
45 45
46 pub fn evt_handler() { 46 pub fn evt_handler() {
47 unsafe { 47 unsafe {
48 let mut node_ptr = core::ptr::null_mut();
49 let node_ptr_ptr: *mut _ = &mut node_ptr;
50
51 while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { 48 while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) {
52 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());
53 50
54 let event = node_ptr.cast(); 51 let event = node_ptr.cast();
55 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 c4a6c3a72..ddec1afbc 100644
--- a/embassy-stm32-wpan/src/unsafe_linked_list.rs
+++ b/embassy-stm32-wpan/src/unsafe_linked_list.rs
@@ -50,19 +50,33 @@ impl LinkedListNode {
50 pub unsafe fn insert_head(mut p_list_head: *mut LinkedListNode, mut p_node: *mut LinkedListNode) { 50 pub unsafe fn insert_head(mut p_list_head: *mut LinkedListNode, mut p_node: *mut LinkedListNode) {
51 interrupt::free(|_| { 51 interrupt::free(|_| {
52 let mut list_head = ptr::read_volatile(p_list_head); 52 let mut list_head = ptr::read_volatile(p_list_head);
53 let mut node_next = ptr::read_volatile(list_head.next); 53 if p_list_head != list_head.next {
54 let node = LinkedListNode { 54 let mut node_next = ptr::read_volatile(list_head.next);
55 next: list_head.next, 55 let node = LinkedListNode {
56 prev: p_list_head, 56 next: list_head.next,
57 }; 57 prev: p_list_head,
58 58 };
59 list_head.next = p_node; 59
60 node_next.prev = p_node; 60 list_head.next = p_node;
61 61 node_next.prev = p_node;
62 // All nodes must be written because they will all be seen by another core 62
63 ptr::write_volatile(p_node, node); 63 // All nodes must be written because they will all be seen by another core
64 ptr::write_volatile(node.next, node_next); 64 ptr::write_volatile(p_node, node);
65 ptr::write_volatile(p_list_head, list_head); 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 }
66 }); 80 });
67 } 81 }
68 82
@@ -70,57 +84,84 @@ impl LinkedListNode {
70 pub unsafe fn insert_tail(mut p_list_tail: *mut LinkedListNode, mut p_node: *mut LinkedListNode) { 84 pub unsafe fn insert_tail(mut p_list_tail: *mut LinkedListNode, mut p_node: *mut LinkedListNode) {
71 interrupt::free(|_| { 85 interrupt::free(|_| {
72 let mut list_tail = ptr::read_volatile(p_list_tail); 86 let mut list_tail = ptr::read_volatile(p_list_tail);
73 let mut node_prev = ptr::read_volatile(list_tail.prev); 87 if p_list_tail != list_tail.prev {
74 let node = LinkedListNode { 88 let mut node_prev = ptr::read_volatile(list_tail.prev);
75 next: p_list_tail, 89 let node = LinkedListNode {
76 prev: list_tail.prev, 90 next: p_list_tail,
77 }; 91 prev: list_tail.prev,
78 92 };
79 list_tail.prev = p_node; 93
80 node_prev.next = p_node; 94 list_tail.prev = p_node;
81 95 node_prev.next = p_node;
82 // All nodes must be written because they will all be seen by another core 96
83 ptr::write_volatile(p_node, node); 97 // All nodes must be written because they will all be seen by another core
84 ptr::write_volatile(node.prev, node_prev); 98 ptr::write_volatile(p_node, node);
85 ptr::write_volatile(p_list_tail, list_tail); 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 }
86 }); 114 });
87 } 115 }
88 116
89 /// Remove `node` from the linked list 117 /// Remove `node` from the linked list
90 pub unsafe fn remove_node(mut p_node: *mut LinkedListNode) { 118 pub unsafe fn remove_node(mut p_node: *mut LinkedListNode) {
91 interrupt::free(|_| { 119 interrupt::free(|_| {
92 // Writes must occur sequentially, because if prev node, and next node are the same, both must be updated
93 let node = ptr::read_volatile(p_node); 120 let node = ptr::read_volatile(p_node);
94 let mut node_prev = ptr::read_volatile(node.prev); 121 if node.next != node.prev {
95 node_prev.next = node.next; 122 let mut node_next = ptr::read_volatile(node.next);
96 ptr::write_volatile(node.prev, node_prev); 123 let mut node_prev = ptr::read_volatile(node.prev);
124
125 node_prev.next = node.next;
126 node_next.prev = node.prev;
97 127
98 let mut node_next = ptr::read_volatile(node.next); 128 ptr::write_volatile(node.next, node_next);
99 node_next.prev = node.prev; 129 ptr::write_volatile(node.prev, node_prev);
100 ptr::write_volatile(node.next, node_next); 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 }
101 }); 138 });
102 } 139 }
103 140
104 /// Remove `list_head` into `node` 141 /// Remove `list_head` and return a pointer to the `node`.
105 pub unsafe fn remove_head(mut p_list_head: *mut LinkedListNode, mut p_node: *mut *mut LinkedListNode) { 142 pub unsafe fn remove_head(mut p_list_head: *mut LinkedListNode) -> *mut LinkedListNode {
106 interrupt::free(|_| { 143 interrupt::free(|_| {
107 let list_head = ptr::read_volatile(p_list_head); 144 let list_head = ptr::read_volatile(p_list_head);
108 145
109 // Allowed because a removed node is not seen by another core 146 // Allowed because a removed node is not seen by another core
110 *p_node = list_head.next; 147 let p_node = list_head.next;
111 Self::remove_node(*p_node); 148 Self::remove_node(p_node);
112 }); 149
150 p_node
151 })
113 } 152 }
114 153
115 /// Remove `list_tail` into `node` 154 /// Remove `list_tail` and return a pointer to the `node`.
116 pub unsafe fn remove_tail(mut p_list_tail: *mut LinkedListNode, mut p_node: *mut *mut LinkedListNode) { 155 pub unsafe fn remove_tail(mut p_list_tail: *mut LinkedListNode) -> *mut LinkedListNode {
117 interrupt::free(|_| { 156 interrupt::free(|_| {
118 let list_tail = ptr::read_volatile(p_list_tail); 157 let list_tail = ptr::read_volatile(p_list_tail);
119 158
120 // Allowed because a removed node is not seen by another core 159 // Allowed because a removed node is not seen by another core
121 *p_node = list_tail.prev; 160 let p_node = list_tail.prev;
122 Self::remove_node(*p_node); 161 Self::remove_node(p_node);
123 }); 162
163 p_node
164 })
124 } 165 }
125 166
126 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) {
@@ -130,6 +171,8 @@ impl LinkedListNode {
130 (*ref_node).next = node; 171 (*ref_node).next = node;
131 (*(*node).next).prev = node; 172 (*(*node).next).prev = node;
132 }); 173 });
174
175 todo!("this function has not been converted to volatile semantics");
133 } 176 }
134 177
135 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) {
@@ -139,6 +182,8 @@ impl LinkedListNode {
139 (*ref_node).prev = node; 182 (*ref_node).prev = node;
140 (*(*node).prev).next = node; 183 (*(*node).prev).next = node;
141 }); 184 });
185
186 todo!("this function has not been converted to volatile semantics");
142 } 187 }
143 188
144 pub unsafe fn get_size(mut list_head: *mut LinkedListNode) -> usize { 189 pub unsafe fn get_size(mut list_head: *mut LinkedListNode) -> usize {
@@ -153,7 +198,9 @@ impl LinkedListNode {
153 } 198 }
154 199
155 size 200 size
156 }) 201 });
202
203 todo!("this function has not been converted to volatile semantics");
157 } 204 }
158 205
159 pub unsafe fn get_next_node(mut p_ref_node: *mut LinkedListNode, mut p_node: *mut *mut LinkedListNode) { 206 pub unsafe fn get_next_node(mut p_ref_node: *mut LinkedListNode, mut p_node: *mut *mut LinkedListNode) {
@@ -165,9 +212,12 @@ impl LinkedListNode {
165 }); 212 });
166 } 213 }
167 214
168 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 p_node: *mut *mut LinkedListNode) {
169 interrupt::free(|_| { 216 interrupt::free(|_| {
170 *node = (*ref_node).prev; 217 let ref_node = ptr::read_volatile(p_ref_node);
218
219 // Allowed because a removed node is not seen by another core
220 *p_node = ref_node.prev;
171 }); 221 });
172 } 222 }
173} 223}