components/
debug_queue.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! Component for DebugQueue, the implementation for `debug_enqueue!` and
//! `debug_flush_queue!`.
//!
//! This provides one `Component`, `DebugQueue`, which creates a kernel debug
//! queue using the provided buffer. Data is appended to the queue with
//! `debug_enqueue!`, and can be later flushed to the debug buffer with
//! `debug_flush_queue!`. Any data left on the queue is flushed upon panic.
//!
//! Usage
//! -----
//! ```rust
//! DebugQueueComponent::new().finalize(components::debug_queue_component_static!());
//! ```

// Author: Guillaume Endignoux <guillaumee@google.com>
// Last modified: 05 Mar 2020

use core::mem::MaybeUninit;
use kernel::collections::ring_buffer::RingBuffer;
use kernel::component::Component;

#[macro_export]
macro_rules! debug_queue_component_static {
    () => {{
        let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
        let queue = kernel::static_buf!(kernel::debug::DebugQueue);
        let wrapper = kernel::static_buf!(kernel::debug::DebugQueueWrapper);
        let buffer = kernel::static_buf!([u8; 1024]);

        (ring, queue, wrapper, buffer)
    };};
}

pub struct DebugQueueComponent {}

impl DebugQueueComponent {
    pub fn new() -> Self {
        Self {}
    }
}

impl Component for DebugQueueComponent {
    type StaticInput = (
        &'static mut MaybeUninit<RingBuffer<'static, u8>>,
        &'static mut MaybeUninit<kernel::debug::DebugQueue>,
        &'static mut MaybeUninit<kernel::debug::DebugQueueWrapper>,
        &'static mut MaybeUninit<[u8; 1024]>,
    );
    type Output = ();

    fn finalize(self, s: Self::StaticInput) -> Self::Output {
        let buffer = s.3.write([0; 1024]);
        let ring_buffer = s.0.write(RingBuffer::new(buffer));
        let debug_queue = s.1.write(kernel::debug::DebugQueue::new(ring_buffer));
        let debug_queue_wrapper =
            s.2.write(kernel::debug::DebugQueueWrapper::new(debug_queue));
        unsafe {
            kernel::debug::set_debug_queue(debug_queue_wrapper);
        }
    }
}