capsules_core/virtualizers/
virtual_uart.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//! Virtualize a UART bus.
6//!
7//! This allows multiple Tock capsules to use the same UART bus. This is likely
8//! most useful for `printf()` like applications where multiple things want to
9//! write to the same UART channel.
10//!
11//! Clients can choose if they want to receive. Incoming messages will be sent
12//! to all clients that have enabled receiving.
13//!
14//! `MuxUart` provides shared access to a single UART bus for multiple users.
15//! `UartDevice` provides access for a single client.
16//!
17//! Usage
18//! -----
19//!
20//! ```rust,ignore
21//! # use kernel::{hil, static_init};
22//! # use capsules_core::virtual_uart::{MuxUart, UartDevice};
23//!
24//! // Create a shared UART channel for the console and for kernel debug.
25//! let uart_mux = static_init!(
26//!     MuxUart<'static>,
27//!     MuxUart::new(&sam4l::usart::USART0, &mut capsules_core::virtual_uart::RX_BUF)
28//! );
29//! hil::uart::UART::set_receive_client(&sam4l::usart::USART0, uart_mux);
30//! hil::uart::UART::set_transmit_client(&sam4l::usart::USART0, uart_mux);
31//!
32//! // Create a UartDevice for the console.
33//! let console_uart = static_init!(UartDevice, UartDevice::new(uart_mux, true));
34//! console_uart.setup(); // This is important!
35//! let console = static_init!(
36//!     capsules_core::console::Console<'static>,
37//!     capsules_core::console::Console::new(
38//!         console_uart,
39//!         &mut capsules_core::console::WRITE_BUF,
40//!         &mut capsules_core::console::READ_BUF,
41//!         board_kernel.create_grant(&grant_cap)
42//!     )
43//! );
44//! hil::uart::UART::set_transmit_client(console_uart, console);
45//! hil::uart::UART::set_receive_client(console_uart, console);
46//! ```
47
48use core::cell::Cell;
49use core::cmp;
50
51use kernel::collections::list::{List, ListLink, ListNode};
52use kernel::deferred_call::{DeferredCall, DeferredCallClient};
53use kernel::hil::uart;
54use kernel::utilities::cells::{OptionalCell, TakeCell};
55use kernel::ErrorCode;
56
57pub const RX_BUF_LEN: usize = 64;
58
59pub struct MuxUart<'a> {
60    uart: &'a dyn uart::Uart<'a>,
61    speed: u32,
62    devices: List<'a, UartDevice<'a>>,
63    inflight: OptionalCell<&'a UartDevice<'a>>,
64    buffer: TakeCell<'static, [u8]>,
65    completing_read: Cell<bool>,
66    deferred_call: DeferredCall,
67}
68
69impl uart::TransmitClient for MuxUart<'_> {
70    fn transmitted_buffer(
71        &self,
72        tx_buffer: &'static mut [u8],
73        tx_len: usize,
74        rcode: Result<(), ErrorCode>,
75    ) {
76        self.inflight.map(move |device| {
77            self.inflight.clear();
78            device.transmitted_buffer(tx_buffer, tx_len, rcode);
79        });
80        self.do_next_op();
81    }
82}
83
84impl uart::ReceiveClient for MuxUart<'_> {
85    fn received_buffer(
86        &self,
87        buffer: &'static mut [u8],
88        rx_len: usize,
89        rcode: Result<(), ErrorCode>,
90        error: uart::Error,
91    ) {
92        // Likely we will issue another receive in response to the previous one
93        // finishing. `next_read_len` keeps track of the shortest outstanding
94        // receive requested by any client. We start with the longest it can be,
95        // i.e. the length of the buffer we pass to the UART.
96        let mut next_read_len = buffer.len();
97        let mut read_pending = false;
98
99        // Set a flag that we are in this callback handler. This allows us to
100        // note that we can wait until all callbacks are finished before
101        // starting a new UART receive.
102        self.completing_read.set(true);
103
104        // Because clients may issue another read in their callback we need to
105        // first copy out all the data, then make the callbacks.
106        //
107        // Multiple client reads of different sizes can be pending. This code
108        // copies the underlying UART read into each of the client buffers.
109        self.devices.iter().for_each(|device| {
110            if device.receiver {
111                device.rx_buffer.take().map(|rxbuf| {
112                    let state = device.state.get();
113                    // Copy the read into the buffer starting at rx_position
114                    let position = device.rx_position.get();
115                    let remaining = device.rx_len.get() - position;
116                    let len = cmp::min(rx_len, remaining);
117                    if state == UartDeviceReceiveState::Receiving
118                        || state == UartDeviceReceiveState::Aborting
119                    {
120                        // debug!("Have {} bytes, copying in bytes {}-{}, {} remain", rx_len, position, position + len, remaining);
121                        rxbuf[position..(len + position)].copy_from_slice(&buffer[..len]);
122                    }
123                    device.rx_position.set(position + len);
124                    device.rx_buffer.replace(rxbuf);
125                });
126            }
127        });
128        // If the underlying read completes a client read, issue a callback to
129        // that client. In the meanwhile, compute the length of the next
130        // underlying UART read as the shortest outstanding read, including and
131        // new reads setup in the callback. If any client has more to read or
132        // has started a new read, issue another underlying UART receive.
133        self.devices.iter().for_each(|device| {
134            if device.receiver {
135                device.rx_buffer.take().map(|rxbuf| {
136                    let state = device.state.get();
137                    let position = device.rx_position.get();
138                    let remaining = device.rx_len.get() - position;
139                    // If this finishes the read, signal to the caller,
140                    // otherwise update state so next read will fill in
141                    // more data.
142                    if remaining == 0 {
143                        device.state.set(UartDeviceReceiveState::Idle);
144                        device.received_buffer(rxbuf, position, rcode, error);
145                        // Need to check if receive was called in callback
146                        if device.state.get() == UartDeviceReceiveState::Receiving {
147                            read_pending = true;
148                            next_read_len = cmp::min(next_read_len, device.rx_len.get());
149                        }
150                    } else if state == UartDeviceReceiveState::Aborting {
151                        device.state.set(UartDeviceReceiveState::Idle);
152                        device.received_buffer(
153                            rxbuf,
154                            position,
155                            Err(ErrorCode::CANCEL),
156                            uart::Error::Aborted,
157                        );
158                        // Need to check if receive was called in callback
159                        if device.state.get() == UartDeviceReceiveState::Receiving {
160                            read_pending = true;
161                            next_read_len = cmp::min(next_read_len, device.rx_len.get());
162                        }
163                    } else {
164                        device.rx_buffer.replace(rxbuf);
165                        next_read_len = cmp::min(next_read_len, remaining);
166                        read_pending = true;
167                    }
168                });
169            }
170        });
171
172        // After we have finished all callbacks we can replace this buffer. We
173        // have to wait to replace this to make sure that a client calling
174        // `receive_buffer()` in its callback does not start an underlying UART
175        // receive before all callbacks have finished.
176        self.buffer.replace(buffer);
177
178        // Clear the flag that we are in this handler.
179        self.completing_read.set(false);
180
181        // If either our outstanding receive was longer than the number of bytes
182        // we just received, or if a new receive has been started, we start the
183        // underlying UART receive again.
184        if read_pending {
185            if let Err((e, buf)) = self.start_receive(next_read_len) {
186                self.buffer.replace(buf);
187
188                // Report the error to all devices
189                self.devices.iter().for_each(|device| {
190                    if device.receiver {
191                        device.rx_buffer.take().map(|rxbuf| {
192                            let state = device.state.get();
193                            let position = device.rx_position.get();
194
195                            if state == UartDeviceReceiveState::Receiving {
196                                device.state.set(UartDeviceReceiveState::Idle);
197
198                                device.received_buffer(
199                                    rxbuf,
200                                    position,
201                                    Err(e),
202                                    uart::Error::Aborted,
203                                );
204                            }
205                        });
206                    }
207                });
208            }
209        }
210    }
211}
212
213impl<'a> MuxUart<'a> {
214    pub fn new(uart: &'a dyn uart::Uart<'a>, buffer: &'static mut [u8], speed: u32) -> MuxUart<'a> {
215        MuxUart {
216            uart,
217            speed,
218            devices: List::new(),
219            inflight: OptionalCell::empty(),
220            buffer: TakeCell::new(buffer),
221            completing_read: Cell::new(false),
222            deferred_call: DeferredCall::new(),
223        }
224    }
225
226    pub fn initialize(&self) {
227        let _ = self.uart.configure(uart::Parameters {
228            baud_rate: self.speed,
229            width: uart::Width::Eight,
230            stop_bits: uart::StopBits::One,
231            parity: uart::Parity::None,
232            hw_flow_control: false,
233        });
234    }
235
236    fn do_next_op(&self) {
237        if self.inflight.is_none() {
238            let mnode = self.devices.iter().find(|node| node.operation.is_some());
239            mnode.map(|node| {
240                node.tx_buffer.take().map(|buf| {
241                    node.operation.take().map(move |op| match op {
242                        Operation::Transmit { len } => match self.uart.transmit_buffer(buf, len) {
243                            Ok(()) => {
244                                self.inflight.set(node);
245                            }
246                            Err((ecode, buf)) => {
247                                node.tx_client.map(move |client| {
248                                    node.transmitting.set(false);
249                                    client.transmitted_buffer(buf, 0, Err(ecode));
250                                });
251                            }
252                        },
253                        Operation::TransmitWord { word } => {
254                            let rcode = self.uart.transmit_word(word);
255                            if rcode != Ok(()) {
256                                node.tx_client.map(|client| {
257                                    node.transmitting.set(false);
258                                    client.transmitted_word(rcode);
259                                });
260                            }
261                        }
262                    });
263                });
264            });
265        }
266    }
267
268    /// Starts a new UART reception, return value denotes whether starting
269    /// the reception will issue a callback before the new read. A callback
270    /// needs to be issued before the new read if a read was ongoing; the
271    /// callback finishes the current read so the new one can start.
272    ///
273    /// Three cases:
274    /// 1. We are in the midst of completing a read: let the `received_buffer()`
275    ///    handler restart the reads if needed (return false)
276    /// 2. We are in the midst of a read: abort so we can start a new read now
277    ///    (return true)
278    /// 3. We are idle: start reading (return false)
279    fn start_receive(&self, rx_len: usize) -> Result<bool, (ErrorCode, &'static mut [u8])> {
280        self.buffer.take().map_or_else(
281            || {
282                // No rxbuf which means a read is ongoing
283                if self.completing_read.get() {
284                    // Case (1). Do nothing here, `received_buffer()` handler
285                    // will call start_receive when ready.
286                    Ok(false)
287                } else {
288                    // Case (2). Stop the previous read so we can use the
289                    // `received_buffer()` handler to recalculate the minimum
290                    // length for a read.
291                    let _ = self.uart.receive_abort();
292                    Ok(true)
293                }
294            },
295            |rxbuf| {
296                // Case (3). No ongoing receive calls, we can start one now.
297                let len = cmp::min(rx_len, rxbuf.len());
298                self.uart.receive_buffer(rxbuf, len)?;
299                Ok(false)
300            },
301        )
302    }
303
304    /// Asynchronously executes the next operation, if any. Used by calls
305    /// to trigger do_next_op such that it will execute after the call
306    /// returns. This is important in case the operation triggers an error,
307    /// requiring a callback with an error condition; if the operation
308    /// is executed synchronously, the callback may be reentrant (executed
309    /// during the downcall). Please see
310    /// <https://github.com/tock/tock/issues/1496>
311    fn do_next_op_async(&self) {
312        self.deferred_call.set();
313    }
314}
315
316impl DeferredCallClient for MuxUart<'_> {
317    fn handle_deferred_call(&self) {
318        self.do_next_op();
319    }
320
321    fn register(&'static self) {
322        self.deferred_call.register(self);
323    }
324}
325
326#[derive(Copy, Clone, PartialEq)]
327enum Operation {
328    Transmit { len: usize },
329    TransmitWord { word: u32 },
330}
331
332#[derive(Copy, Clone, PartialEq)]
333enum UartDeviceReceiveState {
334    Idle,
335    Receiving,
336    Aborting,
337}
338
339pub struct UartDevice<'a> {
340    state: Cell<UartDeviceReceiveState>,
341    mux: &'a MuxUart<'a>,
342    receiver: bool, // Whether or not to pass this UartDevice incoming messages.
343    tx_buffer: TakeCell<'static, [u8]>,
344    transmitting: Cell<bool>,
345    rx_buffer: TakeCell<'static, [u8]>,
346    rx_position: Cell<usize>,
347    rx_len: Cell<usize>,
348    operation: OptionalCell<Operation>,
349    next: ListLink<'a, UartDevice<'a>>,
350    rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
351    tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
352}
353
354impl<'a> UartDevice<'a> {
355    pub fn new(mux: &'a MuxUart<'a>, receiver: bool) -> UartDevice<'a> {
356        UartDevice {
357            state: Cell::new(UartDeviceReceiveState::Idle),
358            mux,
359            receiver,
360            tx_buffer: TakeCell::empty(),
361            transmitting: Cell::new(false),
362            rx_buffer: TakeCell::empty(),
363            rx_position: Cell::new(0),
364            rx_len: Cell::new(0),
365            operation: OptionalCell::empty(),
366            next: ListLink::empty(),
367            rx_client: OptionalCell::empty(),
368            tx_client: OptionalCell::empty(),
369        }
370    }
371
372    /// Must be called right after `static_init!()`.
373    pub fn setup(&'a self) {
374        self.mux.devices.push_head(self);
375    }
376}
377
378impl uart::TransmitClient for UartDevice<'_> {
379    fn transmitted_buffer(
380        &self,
381        tx_buffer: &'static mut [u8],
382        tx_len: usize,
383        rcode: Result<(), ErrorCode>,
384    ) {
385        self.tx_client.map(move |client| {
386            self.transmitting.set(false);
387            client.transmitted_buffer(tx_buffer, tx_len, rcode);
388        });
389    }
390
391    fn transmitted_word(&self, rcode: Result<(), ErrorCode>) {
392        self.tx_client.map(move |client| {
393            self.transmitting.set(false);
394            client.transmitted_word(rcode);
395        });
396    }
397}
398impl uart::ReceiveClient for UartDevice<'_> {
399    fn received_buffer(
400        &self,
401        rx_buffer: &'static mut [u8],
402        rx_len: usize,
403        rcode: Result<(), ErrorCode>,
404        error: uart::Error,
405    ) {
406        self.rx_client.map(move |client| {
407            self.state.set(UartDeviceReceiveState::Idle);
408            client.received_buffer(rx_buffer, rx_len, rcode, error);
409        });
410    }
411}
412
413impl<'a> ListNode<'a, UartDevice<'a>> for UartDevice<'a> {
414    fn next(&'a self) -> &'a ListLink<'a, UartDevice<'a>> {
415        &self.next
416    }
417}
418
419impl<'a> uart::Transmit<'a> for UartDevice<'a> {
420    fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
421        self.tx_client.set(client);
422    }
423
424    fn transmit_abort(&self) -> Result<(), ErrorCode> {
425        Err(ErrorCode::FAIL)
426    }
427
428    /// Transmit data.
429    fn transmit_buffer(
430        &self,
431        tx_data: &'static mut [u8],
432        tx_len: usize,
433    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
434        if tx_len == 0 {
435            Err((ErrorCode::SIZE, tx_data))
436        } else if self.transmitting.get() {
437            Err((ErrorCode::BUSY, tx_data))
438        } else {
439            self.tx_buffer.replace(tx_data);
440            self.transmitting.set(true);
441            self.operation.set(Operation::Transmit { len: tx_len });
442            self.mux.do_next_op_async();
443            Ok(())
444        }
445    }
446
447    fn transmit_word(&self, word: u32) -> Result<(), ErrorCode> {
448        if self.transmitting.get() {
449            Err(ErrorCode::BUSY)
450        } else {
451            self.transmitting.set(true);
452            self.operation.set(Operation::TransmitWord { word });
453            self.mux.do_next_op_async();
454            Ok(())
455        }
456    }
457}
458
459impl<'a> uart::Receive<'a> for UartDevice<'a> {
460    fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
461        self.rx_client.set(client);
462    }
463
464    /// Receive data until buffer is full.
465    fn receive_buffer(
466        &self,
467        rx_buffer: &'static mut [u8],
468        rx_len: usize,
469    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
470        if self.rx_buffer.is_some() {
471            Err((ErrorCode::BUSY, rx_buffer))
472        } else if rx_len > rx_buffer.len() {
473            Err((ErrorCode::SIZE, rx_buffer))
474        } else {
475            self.rx_buffer.replace(rx_buffer);
476            self.rx_len.set(rx_len);
477            self.rx_position.set(0);
478            self.state.set(UartDeviceReceiveState::Idle);
479            self.mux.start_receive(rx_len)?;
480            self.state.set(UartDeviceReceiveState::Receiving);
481            Ok(())
482        }
483    }
484
485    // This virtualized device will abort its read: other devices
486    // devices will continue with their reads.
487    fn receive_abort(&self) -> Result<(), ErrorCode> {
488        self.state.set(UartDeviceReceiveState::Aborting);
489        let _ = self.mux.uart.receive_abort();
490        Err(ErrorCode::BUSY)
491    }
492
493    fn receive_word(&self) -> Result<(), ErrorCode> {
494        Err(ErrorCode::FAIL)
495    }
496}