Skip to content

Commit 798856f

Browse files
committed
serial terminal, commands not working yet
1 parent 0ff578e commit 798856f

10 files changed

Lines changed: 411 additions & 5 deletions

File tree

process-console/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@ queues = "1.0.2"
2424
itertools = "0.12.1"
2525
ratatui = "0.28.0"
2626
probe-rs = "0.24.0"
27-
27+
clap = { version = "4.1.1", features = ["cargo"] }
28+
async-trait = "0.1.73"
29+
enum_dispatch = "0.3.12"
30+
console = { git = "https://github.com/george-cosma/console.git", branch = "unblock" }
31+
futures = "0.3.31"
32+
tokio-util = "0.7.15"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use core::fmt;
2+
3+
#[derive(Debug)]
4+
pub enum TockloaderError {
5+
TokioSeriallError(tokio_serial::Error),
6+
NoPortAvailable,
7+
CLIError(CLIError),
8+
IOError(std::io::Error),
9+
JoinError(tokio::task::JoinError),
10+
}
11+
12+
#[derive(Debug)]
13+
pub enum CLIError {
14+
MultipleInterfaces,
15+
}
16+
17+
impl fmt::Display for TockloaderError {
18+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19+
match self {
20+
TockloaderError::TokioSeriallError(inner) => {
21+
inner.fmt(f)
22+
}
23+
TockloaderError::NoPortAvailable => {
24+
f.write_str("Tockloader has failed to find any open ports. If your device is plugged in, you can manually specify it using the '--port <path>' argument.")
25+
},
26+
TockloaderError::CLIError(inner) => {
27+
inner.fmt(f)
28+
}
29+
TockloaderError::IOError(inner) => {
30+
inner.fmt(f)
31+
},
32+
TockloaderError::JoinError(inner) => {
33+
inner.fmt(f)
34+
},
35+
}
36+
}
37+
}
38+
39+
impl fmt::Display for CLIError {
40+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41+
match self {
42+
CLIError::MultipleInterfaces => {
43+
f.write_str("At most one of the following tranport interfaces may be used: '--serial', '--openocd', '-jlink'")
44+
},
45+
}
46+
}
47+
}
48+
49+
impl From<std::io::Error> for TockloaderError {
50+
fn from(value: std::io::Error) -> Self {
51+
Self::IOError(value)
52+
}
53+
}
54+
55+
impl From<tokio_serial::Error> for TockloaderError {
56+
fn from(value: tokio_serial::Error) -> Self {
57+
Self::TokioSeriallError(value)
58+
}
59+
}
60+
61+
impl From<tokio::task::JoinError> for TockloaderError {
62+
fn from(value: tokio::task::JoinError) -> Self {
63+
Self::JoinError(value)
64+
}
65+
}
66+
67+
impl std::error::Error for TockloaderError {}
68+
impl std::error::Error for CLIError {}

process-console/src/legacy/mod.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
pub fn run() {
2-
// TODO
3-
panic!();
1+
use clap::ArgMatches;
2+
3+
use crate::legacy::errors::TockloaderError;
4+
use crate::legacy::serial::interface::build_interface;
5+
use crate::legacy::serial::traits::BoardInterface;
6+
use crate::legacy::serial::traits::VirtualTerminal;
7+
8+
mod errors;
9+
mod serial;
10+
11+
pub async fn run(sub_matches: &ArgMatches) -> Result<(), TockloaderError> {
12+
let mut interface = build_interface(sub_matches)?;
13+
interface.open()?;
14+
interface.run_terminal().await?;
15+
16+
Ok(())
417
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use tokio_serial::SerialPortBuilderExt;
2+
3+
use crate::legacy::errors::TockloaderError;
4+
use crate::legacy::serial::traits::BoardInterface;
5+
use crate::legacy::serial::serial::SerialInterface;
6+
7+
impl BoardInterface for SerialInterface {
8+
fn open(&mut self) -> Result<(), TockloaderError> {
9+
// Is it async? It can't be awaited...
10+
let stream = tokio_serial::new(self.port.clone(), self.baud_rate).open_native_async()?;
11+
12+
self.stream = Some(stream);
13+
14+
Ok(())
15+
}
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::legacy::serial::serial::SerialInterface;
2+
3+
use crate::legacy::errors::{CLIError, TockloaderError};
4+
use clap::ArgMatches;
5+
use enum_dispatch::enum_dispatch;
6+
7+
use crate::legacy::serial::traits;
8+
9+
#[enum_dispatch(BoardInterface)]
10+
#[enum_dispatch(VirtualTerminal)]
11+
pub enum Interface {
12+
Serial(SerialInterface),
13+
}
14+
15+
pub fn build_interface(args: &ArgMatches) -> Result<Interface, TockloaderError> {
16+
Ok(SerialInterface::new(args)?.into())
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod interface;
2+
mod serial;
3+
pub mod terminal;
4+
pub mod traits;
5+
pub mod board_interface;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::legacy::serial::interface;
2+
use crate::legacy::serial::terminal;
3+
4+
use clap::ArgMatches;
5+
use tokio_serial::SerialStream;
6+
7+
use crate::legacy::errors::TockloaderError;
8+
9+
pub struct SerialInterface {
10+
pub port: String,
11+
pub baud_rate: u32,
12+
pub stream: Option<SerialStream>,
13+
}
14+
15+
impl SerialInterface {
16+
pub fn new(args: &ArgMatches) -> Result<Self, TockloaderError> {
17+
// If the user has specified a port, we want to try to use it.
18+
// Otherwise, we let tokio-serial enumarate all ports and
19+
// if multiple ports are present, we let the user decide which.
20+
let port = if let Some(user_port) = args.get_one::<String>("port") {
21+
user_port.clone()
22+
} else {
23+
let available_ports = tokio_serial::available_ports()?;
24+
25+
if available_ports.is_empty() {
26+
return Err(TockloaderError::NoPortAvailable);
27+
} else if available_ports.len() == 1 {
28+
clean_port_path(available_ports[0].port_name.clone())
29+
} else {
30+
// available_ports.len() > 1
31+
todo!("Make user choose out of multiple available ports")
32+
}
33+
};
34+
35+
// change this back!!
36+
let baud_rate: u32 = 115200;
37+
// let baud_rate = if let Some(baud_rate) = args.get_one::<u32>("baud-rate") {
38+
// *baud_rate
39+
// } else {
40+
// unreachable!("'--baud-rate' should have a default value.")
41+
// };
42+
43+
Ok(Self {
44+
port,
45+
baud_rate,
46+
stream: None,
47+
})
48+
}
49+
}
50+
51+
// When listing available ports, tokio_serial list unix ports like so:
52+
// /sys/class/tty/ttyACM0
53+
// /sys/class/tty/<port>
54+
// For some users, tokio_serial fails to open ports using this path scheme.
55+
// This function replaces it with the normal '/dev/<port>' scheme.
56+
// Windows COM ports should not be affected.
57+
fn clean_port_path(port: String) -> String {
58+
if port.contains("/sys/class/tty/") {
59+
port.replace("/sys/class/tty/", "/dev/")
60+
} else {
61+
port
62+
}
63+
}

0 commit comments

Comments
 (0)