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.
45//! 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//! ```
4748use core::cell::Cell;
49use core::cmp;
5051use 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;
5657pub const RX_BUF_LEN: usize = 64;
5859pub 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}
6869impl uart::TransmitClient for MuxUart<'_> {
70fn transmitted_buffer(
71&self,
72 tx_buffer: &'static mut [u8],
73 tx_len: usize,
74 rcode: Result<(), ErrorCode>,
75 ) {
76self.inflight.map(move |device| {
77self.inflight.clear();
78 device.transmitted_buffer(tx_buffer, tx_len, rcode);
79 });
80self.do_next_op();
81 }
82}
8384impl uart::ReceiveClient for MuxUart<'_> {
85fn 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.
96let mut next_read_len = buffer.len();
97let mut read_pending = false;
9899// 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.
102self.completing_read.set(true);
103104// 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.
109self.devices.iter().for_each(|device| {
110if device.receiver {
111 device.rx_buffer.take().map(|rxbuf| {
112let state = device.state.get();
113// Copy the read into the buffer starting at rx_position
114let position = device.rx_position.get();
115let remaining = device.rx_len.get() - position;
116let len = cmp::min(rx_len, remaining);
117if state == UartDeviceReceiveState::Receiving
118 || state == UartDeviceReceiveState::Aborting
119 {
120// debug!("Have {} bytes, copying in bytes {}-{}, {} remain", rx_len, position, position + len, remaining);
121rxbuf[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.
133self.devices.iter().for_each(|device| {
134if device.receiver {
135 device.rx_buffer.take().map(|rxbuf| {
136let state = device.state.get();
137let position = device.rx_position.get();
138let 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.
142if 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
146if 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,
155Err(ErrorCode::CANCEL),
156 uart::Error::Aborted,
157 );
158// Need to check if receive was called in callback
159if 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 });
171172// 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.
176self.buffer.replace(buffer);
177178// Clear the flag that we are in this handler.
179self.completing_read.set(false);
180181// 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.
184if read_pending {
185if let Err((e, buf)) = self.start_receive(next_read_len) {
186self.buffer.replace(buf);
187188// Report the error to all devices
189self.devices.iter().for_each(|device| {
190if device.receiver {
191 device.rx_buffer.take().map(|rxbuf| {
192let state = device.state.get();
193let position = device.rx_position.get();
194195if state == UartDeviceReceiveState::Receiving {
196 device.state.set(UartDeviceReceiveState::Idle);
197198 device.received_buffer(
199 rxbuf,
200 position,
201Err(e),
202 uart::Error::Aborted,
203 );
204 }
205 });
206 }
207 });
208 }
209 }
210 }
211}
212213impl<'a> MuxUart<'a> {
214pub 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 }
225226pub fn initialize(&self) {
227let _ = 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 }
235236fn do_next_op(&self) {
237if self.inflight.is_none() {
238let 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) {
243Ok(()) => {
244self.inflight.set(node);
245 }
246Err((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 } => {
254let rcode = self.uart.transmit_word(word);
255if 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 }
267268/// 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)
279fn start_receive(&self, rx_len: usize) -> Result<bool, (ErrorCode, &'static mut [u8])> {
280self.buffer.take().map_or_else(
281 || {
282// No rxbuf which means a read is ongoing
283if self.completing_read.get() {
284// Case (1). Do nothing here, `received_buffer()` handler
285 // will call start_receive when ready.
286Ok(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.
291let _ = self.uart.receive_abort();
292Ok(true)
293 }
294 },
295 |rxbuf| {
296// Case (3). No ongoing receive calls, we can start one now.
297let len = cmp::min(rx_len, rxbuf.len());
298self.uart.receive_buffer(rxbuf, len)?;
299Ok(false)
300 },
301 )
302 }
303304/// 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>
311fn do_next_op_async(&self) {
312self.deferred_call.set();
313 }
314}
315316impl DeferredCallClient for MuxUart<'_> {
317fn handle_deferred_call(&self) {
318self.do_next_op();
319 }
320321fn register(&'static self) {
322self.deferred_call.register(self);
323 }
324}
325326#[derive(Copy, Clone, PartialEq)]
327enum Operation {
328 Transmit { len: usize },
329 TransmitWord { word: u32 },
330}
331332#[derive(Copy, Clone, PartialEq)]
333enum UartDeviceReceiveState {
334 Idle,
335 Receiving,
336 Aborting,
337}
338339pub struct UartDevice<'a> {
340 state: Cell<UartDeviceReceiveState>,
341 mux: &'a MuxUart<'a>,
342 receiver: bool, // Whether or not to pass this UartDevice incoming messages.
343tx_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}
353354impl<'a> UartDevice<'a> {
355pub 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 }
371372/// Must be called right after `static_init!()`.
373pub fn setup(&'a self) {
374self.mux.devices.push_head(self);
375 }
376}
377378impl uart::TransmitClient for UartDevice<'_> {
379fn transmitted_buffer(
380&self,
381 tx_buffer: &'static mut [u8],
382 tx_len: usize,
383 rcode: Result<(), ErrorCode>,
384 ) {
385self.tx_client.map(move |client| {
386self.transmitting.set(false);
387 client.transmitted_buffer(tx_buffer, tx_len, rcode);
388 });
389 }
390391fn transmitted_word(&self, rcode: Result<(), ErrorCode>) {
392self.tx_client.map(move |client| {
393self.transmitting.set(false);
394 client.transmitted_word(rcode);
395 });
396 }
397}
398impl uart::ReceiveClient for UartDevice<'_> {
399fn received_buffer(
400&self,
401 rx_buffer: &'static mut [u8],
402 rx_len: usize,
403 rcode: Result<(), ErrorCode>,
404 error: uart::Error,
405 ) {
406self.rx_client.map(move |client| {
407self.state.set(UartDeviceReceiveState::Idle);
408 client.received_buffer(rx_buffer, rx_len, rcode, error);
409 });
410 }
411}
412413impl<'a> ListNode<'a, UartDevice<'a>> for UartDevice<'a> {
414fn next(&'a self) -> &'a ListLink<'a, UartDevice<'a>> {
415&self.next
416 }
417}
418419impl<'a> uart::Transmit<'a> for UartDevice<'a> {
420fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
421self.tx_client.set(client);
422 }
423424fn transmit_abort(&self) -> Result<(), ErrorCode> {
425Err(ErrorCode::FAIL)
426 }
427428/// Transmit data.
429fn transmit_buffer(
430&self,
431 tx_data: &'static mut [u8],
432 tx_len: usize,
433 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
434if tx_len == 0 {
435Err((ErrorCode::SIZE, tx_data))
436 } else if self.transmitting.get() {
437Err((ErrorCode::BUSY, tx_data))
438 } else {
439self.tx_buffer.replace(tx_data);
440self.transmitting.set(true);
441self.operation.set(Operation::Transmit { len: tx_len });
442self.mux.do_next_op_async();
443Ok(())
444 }
445 }
446447fn transmit_word(&self, word: u32) -> Result<(), ErrorCode> {
448if self.transmitting.get() {
449Err(ErrorCode::BUSY)
450 } else {
451self.transmitting.set(true);
452self.operation.set(Operation::TransmitWord { word });
453self.mux.do_next_op_async();
454Ok(())
455 }
456 }
457}
458459impl<'a> uart::Receive<'a> for UartDevice<'a> {
460fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
461self.rx_client.set(client);
462 }
463464/// Receive data until buffer is full.
465fn receive_buffer(
466&self,
467 rx_buffer: &'static mut [u8],
468 rx_len: usize,
469 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
470if self.rx_buffer.is_some() {
471Err((ErrorCode::BUSY, rx_buffer))
472 } else if rx_len > rx_buffer.len() {
473Err((ErrorCode::SIZE, rx_buffer))
474 } else {
475self.rx_buffer.replace(rx_buffer);
476self.rx_len.set(rx_len);
477self.rx_position.set(0);
478self.state.set(UartDeviceReceiveState::Idle);
479self.mux.start_receive(rx_len)?;
480self.state.set(UartDeviceReceiveState::Receiving);
481Ok(())
482 }
483 }
484485// This virtualized device will abort its read: other devices
486 // devices will continue with their reads.
487fn receive_abort(&self) -> Result<(), ErrorCode> {
488self.state.set(UartDeviceReceiveState::Aborting);
489let _ = self.mux.uart.receive_abort();
490Err(ErrorCode::BUSY)
491 }
492493fn receive_word(&self) -> Result<(), ErrorCode> {
494Err(ErrorCode::FAIL)
495 }
496}