Skip to content

Commit 8a280ba

Browse files
committed
zephyr: sys: Create queue type based on k_queue
A simple wrapper around Zephyr's k_queue. Signed-off-by: David Brown <[email protected]>
1 parent ae208b6 commit 8a280ba

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

zephyr/src/sys.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
1212
use zephyr_sys::k_timeout_t;
1313

14+
pub mod queue;
1415
pub mod sync;
1516
pub mod thread;
1617

zephyr/src/sys/queue.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! Lightweight wrapper around Zephyr's `k_queue`.
2+
//!
3+
//! The underlying operations on the `k_queue` are all unsafe, as the model does not match the
4+
//! borrowing model that Rust expects. This module is mainly intended to be used by the
5+
//! implementation of `zephyr::sys::channel`, which can be used without needing unsafe.
6+
7+
use core::ffi::c_void;
8+
9+
use zephyr_sys::{
10+
k_queue,
11+
k_queue_init,
12+
k_queue_append,
13+
k_queue_get,
14+
};
15+
16+
use crate::sys::K_FOREVER;
17+
use crate::object::{StaticKernelObject, Wrapped};
18+
19+
/// A wrapper around a Zephyr `k_queue` object.
20+
#[derive(Clone, Debug)]
21+
pub struct Queue {
22+
item: *mut k_queue,
23+
}
24+
25+
unsafe impl Sync for StaticKernelObject<k_queue> { }
26+
27+
unsafe impl Sync for Queue { }
28+
unsafe impl Send for Queue { }
29+
30+
impl Queue {
31+
/// Append an element to the end of a queue.
32+
///
33+
/// This adds an element to the given [`Queue`]. Zephyr requires the
34+
/// first word of this message to be available for the OS to enqueue
35+
/// the message. See [`Message`] for details on how this can be used
36+
/// safely.
37+
///
38+
/// [`Message`]: crate::sync::channel::Message
39+
pub unsafe fn send(&self, data: *mut c_void) {
40+
k_queue_append(self.item, data)
41+
}
42+
43+
/// Get an element from a queue.
44+
///
45+
/// This routine removes the first data item from the [`Queue`].
46+
pub unsafe fn recv(&self) -> *mut c_void {
47+
k_queue_get(self.item, K_FOREVER)
48+
}
49+
}
50+
51+
impl Wrapped for StaticKernelObject<k_queue> {
52+
type T = Queue;
53+
54+
type I = ();
55+
56+
fn get_wrapped(&self, _arg: Self::I) -> Queue {
57+
let ptr = self.value.get();
58+
unsafe {
59+
k_queue_init(ptr);
60+
}
61+
Queue {
62+
item: ptr,
63+
}
64+
}
65+
}
66+
67+
/// A statically defined Zephyr `k_queue`.
68+
///
69+
/// This should be declared as follows:
70+
/// ```
71+
/// kobj_define! {
72+
/// static MY_QUEUE: StaticQueue;
73+
/// }
74+
///
75+
/// let my_queue = MY_QUEUE.init_once(());
76+
///
77+
/// my_queue.send(...);
78+
/// ```
79+
pub type StaticQueue = StaticKernelObject<k_queue>;

0 commit comments

Comments
 (0)