|
17 | 17 | //! having the `k_work` embedded in their structure, and Zephyr schedules the work when the given
|
18 | 18 | //! reason happens.
|
19 | 19 | //!
|
20 |
| -//! At this time, only the basic work queue type is supported. |
21 |
| -//! |
22 |
| -//! Zephyr's work queues can be used in different ways: |
23 |
| -//! |
24 |
| -//! - Work can be scheduled as needed. For example, an IRQ handler can queue a work item to process |
25 |
| -//! data it has received from a device. |
26 |
| -//! - Work can be scheduled periodically. |
27 |
| -//! |
28 |
| -//! As most C use of Zephyr statically allocates things like work, these are typically rescheduled |
29 |
| -//! when the work is complete. The work queue scheduling functions are designed, and intended, for |
30 |
| -//! a given work item to be able to reschedule itself, and such usage is common. |
31 |
| -//! |
32 |
| -//! ## Ownership |
33 |
| -//! |
34 |
| -//! The remaining challenge with implementing `k_work` for Rust is that of ownership. The model |
35 |
| -//! taken here is that the work items are held in a `Box` that is effectively owned by the work |
36 |
| -//! itself. When the work item is scheduled to Zephyr, ownership of that box is effectively handed |
37 |
| -//! off to C, and then when the work item is called, the Box re-constructed. This repeats until the |
38 |
| -//! work is no longer needed, at which point the work will be dropped. |
39 |
| -//! |
40 |
| -//! There are two common ways the lifecycle of work can be managed in an embedded system: |
41 |
| -//! |
42 |
| -//! - A set of `Future`'s are allocated once at the start, and these never return a value. Work |
43 |
| -//! Futures inside of this (which correspond to `.await` in async code) can have lives and return |
44 |
| -//! values, but the main loops will not return values, or be dropped. Embedded Futures will |
45 |
| -//! typically not be boxed. |
46 |
| -//! |
47 |
| -//! One consequence of the ownership being passed through to C code is that if the work cancellation |
48 |
| -//! mechanism is used on a work queue, the work items themselves will be leaked. |
49 |
| -//! |
50 |
| -//! These work items are also `Pin`, to ensure that the work actions are not moved. |
51 |
| -//! |
52 |
| -//! ## The work queues themselves |
| 20 | +//! At this point, this code supports the simple work queues, with [`Work`] items. |
53 | 21 | //!
|
54 | 22 | //! Work Queues should be declared with the `define_work_queue!` macro, this macro requires the name
|
55 | 23 | //! of the symbol for the work queue, the stack size, and then zero or more optional arguments,
|
@@ -185,8 +153,10 @@ impl<const SIZE: usize> WorkQueueDecl<SIZE> {
|
185 | 153 | /// A running work queue thread.
|
186 | 154 | ///
|
187 | 155 | /// This must be declared statically, and initialized once. Please see the macro
|
188 |
| -/// [`define_work_queue`] which declares this with a [`StaticWorkQueue`] to help with the |
| 156 | +/// [`define_work_queue`] which declares this with a [`WorkQueue`] to help with the |
189 | 157 | /// association with a stack, and making sure the queue is only started once.
|
| 158 | +/// |
| 159 | +/// [`define_work_queue`]: crate::define_work_queue |
190 | 160 | pub struct WorkQueue {
|
191 | 161 | #[allow(dead_code)]
|
192 | 162 | item: UnsafeCell<k_work_q>,
|
|
0 commit comments