components/
lldb.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for LowLevelDebug
6//!
7//! This provides one Component, LowLevelDebugComponent, which provides the
8//! LowLevelDebug driver---a driver that can prints messages to the serial port
9//! relying on only `command`s from userspace. It is particularly useful for
10//! board or runtime bringup when more complex operations (allow and subscribe)
11//! may still not be working.
12//!
13//! Usage
14//! -----
15//! ```rust
16//! let lldb = LowLevelDebugComponent::new(board_kernel, uart_mux)
17//!     .finalize(components::low_level_debug_component_static!());
18//! ```
19
20// Author: Amit Levy <amit@amitlevy.com>
21// Last modified: 12/04/2019
22
23use capsules_core::low_level_debug::LowLevelDebug;
24use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
25use core::mem::MaybeUninit;
26use kernel::capabilities;
27use kernel::component::Component;
28use kernel::create_capability;
29use kernel::hil;
30
31#[macro_export]
32macro_rules! low_level_debug_component_static {
33    () => {{
34        let uart =
35            kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice<'static>);
36        let buffer = kernel::static_buf!([u8; capsules_core::low_level_debug::BUF_LEN]);
37        let lldb = kernel::static_buf!(
38            capsules_core::low_level_debug::LowLevelDebug<
39                'static,
40                capsules_core::virtualizers::virtual_uart::UartDevice<'static>,
41            >
42        );
43
44        (uart, buffer, lldb)
45    };};
46}
47
48pub struct LowLevelDebugComponent {
49    board_kernel: &'static kernel::Kernel,
50    driver_num: usize,
51    uart_mux: &'static MuxUart<'static>,
52}
53
54impl LowLevelDebugComponent {
55    pub fn new(
56        board_kernel: &'static kernel::Kernel,
57        driver_num: usize,
58        uart_mux: &'static MuxUart,
59    ) -> LowLevelDebugComponent {
60        LowLevelDebugComponent {
61            board_kernel,
62            driver_num,
63            uart_mux,
64        }
65    }
66}
67
68impl Component for LowLevelDebugComponent {
69    type StaticInput = (
70        &'static mut MaybeUninit<UartDevice<'static>>,
71        &'static mut MaybeUninit<[u8; capsules_core::low_level_debug::BUF_LEN]>,
72        &'static mut MaybeUninit<LowLevelDebug<'static, UartDevice<'static>>>,
73    );
74    type Output = &'static LowLevelDebug<'static, UartDevice<'static>>;
75
76    fn finalize(self, s: Self::StaticInput) -> Self::Output {
77        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
78
79        let lldb_uart = s.0.write(UartDevice::new(self.uart_mux, true));
80        lldb_uart.setup();
81
82        let buffer = s.1.write([0; capsules_core::low_level_debug::BUF_LEN]);
83
84        let lldb = s.2.write(LowLevelDebug::new(
85            buffer,
86            lldb_uart,
87            self.board_kernel.create_grant(self.driver_num, &grant_cap),
88        ));
89        hil::uart::Transmit::set_transmit_client(lldb_uart, lldb);
90
91        lldb
92    }
93}