Created
February 24, 2022 12:01
-
-
Save 9names/d66dfee11c4e3d87920979e9f960c098 to your computer and use it in GitHub Desktop.
Just a toy program to pipe segger-rtt output to stdout for using with defmt-print
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::net::{TcpStream}; | |
use std::io::{Read, Write}; | |
use memchr::memmem; | |
// Update this to match what your tool says. | |
const END_OF_SEGGER_RTT_HEADER: &[u8; 28] = b"Process: JLinkGDBServerCLExe"; | |
fn main() { | |
match TcpStream::connect("localhost:19021") { | |
Ok(mut stream) => { | |
// Do some config. | |
// these should be run-time options, oh well | |
// defmt uses channel 0, my RTT block is at 0x20000000 | |
let msg = b"$$SEGGER_TELNET_ConfigStr=RTTCh;0;SetRTTAddr;0x20000000$$!"; | |
stream.write_all(msg).unwrap(); | |
let mut buffer:[u8;1024] = [0;1024]; | |
// Putting this in a scope to dispose of it when done | |
// Probably overkill, the header isn't that large. | |
{ | |
let mut read_so_far=0; | |
// Small buffer to hold all of the header read so far, so we don't miss our | |
// target string if it gets split over two reads | |
let mut headerbuffer:[u8;1024] = [0;1024]; | |
loop { | |
// keep streaming until we find the end of the header | |
match stream.read(&mut buffer) { | |
Ok(size) => { | |
// make a slice out of what was read | |
let read = &buffer[0..size]; | |
// need our slice sizes to match for copy_from_slices | |
// plus this will become the new "start of slice" | |
let end_of_target = read_so_far + size; | |
let target_slice = &mut headerbuffer[read_so_far..end_of_target]; | |
target_slice.copy_from_slice(read); | |
// If we found our target string, we're ready to print whatever arrives over RTT | |
let mut found = memmem::find_iter(&headerbuffer, END_OF_SEGGER_RTT_HEADER); | |
if found.next().is_some() {break;} | |
// update our target buffer | |
read_so_far = end_of_target; | |
}, | |
Err(_) => todo!(), | |
} | |
} | |
} | |
// We finished reading the header - now just pump everything to stdout | |
loop { | |
match stream.read(&mut buffer) { | |
Ok(size) => { | |
let read = &buffer[0..size]; | |
std::io::stdout().write_all(read).unwrap(); | |
// If there's not much data throughput we won't see anything | |
// so flush constantly to keep us up-to-date | |
let _ = std::io::stdout().flush(); | |
}, | |
Err(_) => todo!(), | |
} | |
} | |
}, | |
Err(e) => { | |
println!("Failed to connect: {}", e); | |
} | |
} | |
println!("Terminated."); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment