A defmt RTT logger implementation & separate ringbuffer storing log messages for retrieval via any embedded-io-async::Write implementer (e.g. a embassy-net TCP socket).
The following will still log via RTT just like rtt_target, but also makes the logs available through a TCP socket on port 19021.
Reading logs via the network is as simple as running defmt-print -e path/to/elf tcp --host <DEVICE_IP>.
#[embassy_executor::main]
async fn main(spawner: Spawner) -> ! {
defmt_rtt_net::init!();
// other initialization bits
let stack = /* initializing embassy network stack */;
spawner.spawn(net_logger(stack)).unwrap();
loop {
// main loop
}
}
#[embassy_executor::task]
async fn net_logger(stack: embassy_net::Stack<'static>) {
use embassy_net::tcp::TcpSocket;
const TX_BUF_SIZE: usize = 1024;
const RX_BUF_SIZE: usize = 256;
static mut TX_BUFF: [u8; TX_BUF_SIZE] = [0; TX_BUF_SIZE];
static mut RX_BUFF: [u8; RX_BUF_SIZE] = [0; RX_BUF_SIZE];
info!("[net][logger] starting network logger socket");
let mut socket = unsafe {
TcpSocket::new(
stack,
&mut *core::ptr::addr_of_mut!(RX_BUFF),
&mut *core::ptr::addr_of_mut!(TX_BUFF),
)
};
loop {
info!("[net][logger] waiting for incoming connection...");
if let Err(e) = socket.accept(19021).await {
warn!("[net][logger] failed to accept connection: {}", e);
continue;
}
let (_, w) = socket.split();
if let Err(e) = defmt_rtt_net::net_handler(w).await {
info!("[net][logger] connection lost: {}", e);
}
}
}defmt-rtt-net is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)