Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 122 additions & 37 deletions boards/components/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use capsules_core::console;
use capsules_core::console_ordered::ConsoleOrdered;

use capsules_core::virtualizers::selection_policy::{InsertionFirstPolicy, SelectionPolicy};
use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
use core::mem::MaybeUninit;
Expand All @@ -53,45 +54,98 @@ use capsules_core::console::DEFAULT_BUF_SIZE;
#[macro_export]
macro_rules! uart_mux_component_static {
// Common logic for both branches
($rx_buffer_len: expr) => {{
($rx_buffer_len: expr, $P: ty) => {{
use capsules_core::virtualizers::virtual_uart::MuxUart;
use kernel::static_buf;
let uart_mux = static_buf!(MuxUart<'static>);
let uart_mux = static_buf!(MuxUart<'static, $P>);
let rx_buf = static_buf!([u8; $rx_buffer_len]);
(uart_mux, rx_buf)
}};
() => {
$crate::uart_mux_component_static!(capsules_core::virtualizers::virtual_uart::RX_BUF_LEN);
};
($rx_buffer_len: literal) => {
$crate::uart_mux_component_static!($rx_buffer_len);
};
($P: ty) => {{
$crate::uart_mux_component_static!(
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
$P
)
}};
// By default, if no selection policy is provided we will use the `InsertionFirstPolicy`.
// This option has been chosen as the default to maintain backwards compatibility.
() => {{
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
$crate::uart_mux_component_static!(
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
InsertionFirstPolicy
)
}};
($rx_buffer_len: literal) => {{
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
$crate::uart_mux_component_static!($rx_buffer_len, InsertionFirstPolicy)
}};
}

pub struct UartMuxComponent<const RX_BUF_LEN: usize> {
pub struct UartMuxComponent<
const RX_BUF_LEN: usize,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static = InsertionFirstPolicy,
> {
uart: &'static dyn uart::Uart<'static>,
baud_rate: u32,
selection_policy: P,
}

impl<const RX_BUF_LEN: usize> UartMuxComponent<RX_BUF_LEN> {
// Implemented for backward compatibility
impl<const RX_BUF_LEN: usize> UartMuxComponent<RX_BUF_LEN, InsertionFirstPolicy> {
/// Create a new MuxComponent with the [`InsertionFirstPolicy`] selection policy.
pub fn new(
uart: &'static dyn uart::Uart<'static>,
baud_rate: u32,
) -> UartMuxComponent<RX_BUF_LEN> {
UartMuxComponent { uart, baud_rate }
) -> UartMuxComponent<RX_BUF_LEN, InsertionFirstPolicy> {
Comment thread
alexandruradovici marked this conversation as resolved.
UartMuxComponent {
uart,
baud_rate,
selection_policy: InsertionFirstPolicy,
}
}
}

// Implemented to specify a custom selection policy
impl<const RX_BUF_LEN: usize, P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static>
UartMuxComponent<RX_BUF_LEN, P>
{
/// Create a new MuxComponent with a custom selection policy.
/// It determines which device will be selected next
/// from the list of devices in the virtualizer.
///
/// For the default implementation, please refer to `new` function
/// which uses `InsertionFirstPolicy` selection polity.
pub fn new_with_policy(
uart: &'static dyn uart::Uart<'static>,
baud_rate: u32,
selection_policy: P,
) -> UartMuxComponent<RX_BUF_LEN, P> {
UartMuxComponent {
uart,
baud_rate,
selection_policy,
}
}
}

impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
impl<const RX_BUF_LEN: usize, P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static>
Component for UartMuxComponent<RX_BUF_LEN, P>
{
type StaticInput = (
&'static mut MaybeUninit<MuxUart<'static>>,
&'static mut MaybeUninit<MuxUart<'static, P>>,
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
);
type Output = &'static MuxUart<'static>;
type Output = &'static MuxUart<'static, P>;

fn finalize(self, s: Self::StaticInput) -> Self::Output {
let rx_buf = s.1.write([0; RX_BUF_LEN]);
let uart_mux = s.0.write(MuxUart::new(self.uart, rx_buf, self.baud_rate));
let uart_mux = s.0.write(MuxUart::new_with_policy(
self.uart,
rx_buf,
self.baud_rate,
self.selection_policy,
));
kernel::deferred_call::DeferredCallClient::register(uart_mux);

uart_mux.initialize();
Expand All @@ -105,37 +159,54 @@ impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
#[macro_export]
macro_rules! console_component_static {
// Common logic for both branches
($rx_buffer_len: expr, $tx_buffer_len: expr) => {{
($rx_buffer_len: expr, $tx_buffer_len: expr, $P: ty) => {{
use capsules_core::console::{Console, DEFAULT_BUF_SIZE};
use capsules_core::virtualizers::virtual_uart::UartDevice;
use kernel::static_buf;
let read_buf = static_buf!([u8; $rx_buffer_len]);
let write_buf = static_buf!([u8; $tx_buffer_len]);
// Create virtual device for console.
let console_uart = static_buf!(UartDevice);
let console_uart = static_buf!(UartDevice<$P>);
let console = static_buf!(Console<'static>);
(write_buf, read_buf, console_uart, console)
}};
() => {
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE);
($rx_buffer_len: literal, $tx_buffer_len: literal, $P: ty) => {
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, $P);
};
($rx_buffer_len: literal, $tx_buffer_len: literal) => {
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len);
($rx_buffer_len: literal, $tx_buffer_len: literal) => {{
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, InsertionFirstPolicy)
}};
($P: ty) => {
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, $P);
};
() => {{
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, InsertionFirstPolicy)
}};
}

pub struct ConsoleComponent<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> {
pub struct ConsoleComponent<
const RX_BUF_LEN: usize,
const TX_BUF_LEN: usize,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> {
board_kernel: &'static kernel::Kernel,
driver_num: usize,
uart_mux: &'static MuxUart<'static>,
uart_mux: &'static MuxUart<'static, P>,
}

impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
impl<
const RX_BUF_LEN: usize,
const TX_BUF_LEN: usize,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
{
pub fn new(
board_kernel: &'static kernel::Kernel,
driver_num: usize,
uart_mux: &'static MuxUart,
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
uart_mux: &'static MuxUart<P>,
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P> {
ConsoleComponent {
board_kernel,
driver_num,
Expand All @@ -144,13 +215,16 @@ impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_L
}
}

impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> Component
for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN>
impl<
const RX_BUF_LEN: usize,
const TX_BUF_LEN: usize,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> Component for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
{
type StaticInput = (
&'static mut MaybeUninit<[u8; TX_BUF_LEN]>,
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
&'static mut MaybeUninit<UartDevice<'static>>,
&'static mut MaybeUninit<UartDevice<'static, P>>,
&'static mut MaybeUninit<console::Console<'static>>,
);
type Output = &'static console::Console<'static>;
Expand Down Expand Up @@ -189,26 +263,33 @@ macro_rules! console_ordered_component_static {
};};
}

pub struct ConsoleOrderedComponent<A: 'static + time::Alarm<'static>> {
pub struct ConsoleOrderedComponent<
A: 'static + time::Alarm<'static>,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> {
board_kernel: &'static kernel::Kernel,
driver_num: usize,
uart_mux: &'static MuxUart<'static>,
uart_mux: &'static MuxUart<'static, P>,
alarm_mux: &'static MuxAlarm<'static, A>,
atomic_size: usize,
retry_timer: u32,
write_timer: u32,
}

impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
impl<
A: 'static + time::Alarm<'static>,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> ConsoleOrderedComponent<A, P>
{
pub fn new(
board_kernel: &'static kernel::Kernel,
driver_num: usize,
uart_mux: &'static MuxUart<'static>,
uart_mux: &'static MuxUart<'static, P>,
alarm_mux: &'static MuxAlarm<'static, A>,
atomic_size: usize,
retry_timer: u32,
write_timer: u32,
) -> ConsoleOrderedComponent<A> {
) -> ConsoleOrderedComponent<A, P> {
ConsoleOrderedComponent {
board_kernel,
driver_num,
Expand All @@ -221,11 +302,15 @@ impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
}
}

impl<A: 'static + time::Alarm<'static>> Component for ConsoleOrderedComponent<A> {
impl<
A: 'static + time::Alarm<'static>,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> Component for ConsoleOrderedComponent<A, P>
{
type StaticInput = (
&'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
&'static mut MaybeUninit<[u8; DEFAULT_BUF_SIZE]>,
&'static mut MaybeUninit<UartDevice<'static>>,
&'static mut MaybeUninit<UartDevice<'static, P>>,
&'static mut MaybeUninit<ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>>,
);
type Output = &'static ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>;
Expand Down
51 changes: 39 additions & 12 deletions boards/components/src/debug_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
// Author: Brad Campbell <bradjc@virginia.edu>
// Last modified: 11/07/2019

use capsules_core::virtualizers::selection_policy::SelectionPolicy;
use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
use capsules_system::debug_writer::uart_debug_writer::UartDebugWriter;
use core::mem::MaybeUninit;
Expand Down Expand Up @@ -55,17 +56,29 @@ const DEBUG_BUFFER_SPLIT: usize = 64;
/// quick succession.
#[macro_export]
macro_rules! debug_writer_component_static {
($BUF_SIZE_KB:expr) => {{
let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice);
($BUF_SIZE_KB:expr, $P: ty) => {{
let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice<$P>);
let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
let debug =
kernel::static_buf!(capsules_system::debug_writer::uart_debug_writer::UartDebugWriter);

(uart, ring, buffer, debug)
};};
($P: ty) => {{
$crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE, $P)
};};
($BUF_SIZE_KB:expr) => {{
$crate::debug_writer_component_static!(
$BUF_SIZE_KB,
capsules_core::virtualizers::selection_policy::InsertionFirstPolicy
)
};};
() => {{
$crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE)
$crate::debug_writer_component_static!(
$crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE,
capsules_core::virtualizers::selection_policy::InsertionFirstPolicy
)
};};
}

Expand All @@ -92,20 +105,27 @@ macro_rules! debug_writer_no_mux_component_static {

// Allow dead code because we need the `Chip` type but don't use `chip`.
#[allow(dead_code)]
pub struct DebugWriterComponent<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> {
uart_mux: &'static MuxUart<'static>,
pub struct DebugWriterComponent<
const BUF_SIZE_BYTES: usize,
C: SetDebugWriterCapability,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> {
uart_mux: &'static MuxUart<'static, P>,
marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
capability: C,
}

impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
DebugWriterComponent<BUF_SIZE_BYTES, C>
impl<
const BUF_SIZE_BYTES: usize,
C: SetDebugWriterCapability,
SP: SelectionPolicy<&'static UartDevice<'static, SP>> + 'static,
> DebugWriterComponent<BUF_SIZE_BYTES, C, SP>
{
/// Create a debug writer component while binding the global variable used
/// by debug.rs to the main thread.
#[cfg(target_has_atomic = "ptr")]
pub fn new<P: kernel::platform::chip::ThreadIdProvider>(
uart_mux: &'static MuxUart,
uart_mux: &'static MuxUart<SP>,
capability: C,
) -> Self {
kernel::debug::initialize_debug_writer_wrapper::<P>();
Expand Down Expand Up @@ -137,7 +157,11 @@ impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
/// })
/// .finalize(components::debug_writer_component_static!());
/// ```
pub fn new_unsafe<F>(uart_mux: &'static MuxUart, capability: C, bind_debug_global: F) -> Self
pub fn new_unsafe<F>(
uart_mux: &'static MuxUart<SP>,
capability: C,
bind_debug_global: F,
) -> Self
where
F: FnOnce(),
{
Expand All @@ -154,11 +178,14 @@ impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
pub struct Capability;
unsafe impl capabilities::ProcessManagementCapability for Capability {}

impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> Component
for DebugWriterComponent<BUF_SIZE_BYTES, C>
impl<
const BUF_SIZE_BYTES: usize,
C: SetDebugWriterCapability,
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
> Component for DebugWriterComponent<BUF_SIZE_BYTES, C, P>
{
type StaticInput = (
&'static mut MaybeUninit<UartDevice<'static>>,
&'static mut MaybeUninit<UartDevice<'static, P>>,
&'static mut MaybeUninit<RingBuffer<'static, u8>>,
&'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
&'static mut MaybeUninit<UartDebugWriter>,
Expand Down
Loading
Loading