diff --git a/Cargo.lock b/Cargo.lock index 54b2eb3..1174a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "cfg-if" version = "1.0.0" @@ -63,12 +69,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", "indexmap", @@ -80,9 +86,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck", "proc-macro-error", @@ -100,6 +106,41 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.4.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "ctrlc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" +dependencies = [ + "nix 0.26.4", + "windows-sys", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -123,9 +164,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -157,6 +198,22 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "mach" version = "0.1.2" @@ -181,13 +238,36 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + [[package]] name = "nix" version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", "cfg-if", "libc", ] @@ -200,9 +280,32 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "os_str_bytes" -version = "6.4.1" +version = "6.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" + +[[package]] +name = "parking_lot" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] [[package]] name = "pkg-config" @@ -236,22 +339,31 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.7.1" @@ -269,6 +381,12 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.152" @@ -283,11 +401,11 @@ checksum = "aab92efb5cf60ad310548bc3f16fa6b0d950019cb7ed8ff41968c3d03721cf12" dependencies = [ "CoreFoundation-sys", "IOKit-sys", - "bitflags", + "bitflags 1.3.2", "cfg-if", "libudev", "mach 0.3.2", - "nix", + "nix 0.24.3", "regex", "winapi", ] @@ -297,10 +415,48 @@ name = "serialport_monitor" version = "0.1.0" dependencies = [ "clap", + "crossterm", + "ctrlc", "serialport", "time", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + [[package]] name = "strsim" version = "0.10.0" @@ -309,9 +465,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -361,6 +517,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" @@ -391,3 +553,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 88d8ec8..92e4167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,6 @@ edition = "2021" [dependencies] serialport = "4" time="0.3" -clap = { version = "3.0", features = ["derive"] } +clap = { version = "3", features = ["derive"] } +crossterm = "0.27" +ctrlc = "3" diff --git a/src/args_parse.rs b/src/args_parse.rs index 0d66e0b..7992af9 100644 --- a/src/args_parse.rs +++ b/src/args_parse.rs @@ -1,4 +1,4 @@ -use clap::{AppSettings,Parser}; +use clap::{AppSettings, Parser}; #[derive(Parser, Debug)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] @@ -13,7 +13,7 @@ pub struct Args { #[clap(short, long, value_parser, default_value_t = 0)] pub rts: u8, ///DTR status; 0 disable, 1 enable - #[clap(short, long, value_parser, default_value_t = 1)] + #[clap(short, long, value_parser, default_value_t = 0)] pub dtr: u8, } @@ -30,7 +30,7 @@ pub fn get_args() -> Args { port: String::new(), baud_rate: 115200, rts: 0, - dtr: 1, + dtr: 0, }; println!("your serial ports list:"); let port_list = serialport::available_ports().unwrap(); @@ -61,7 +61,7 @@ pub fn get_args() -> Args { a.rts = buff.trim().parse().unwrap(); } buff.clear(); - println!("please set dtr status (default 1, enable):"); + println!("please set dtr status (default 0, enable):"); std::io::stdin().read_line(&mut buff).expect("read_line error!"); if buff.trim().len() != 0 { a.dtr = buff.trim().parse().unwrap(); diff --git a/src/key_listener.rs b/src/key_listener.rs new file mode 100644 index 0000000..c6ece91 --- /dev/null +++ b/src/key_listener.rs @@ -0,0 +1,226 @@ +use std::thread; + +use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers}; +use serialport::SerialPort; + +pub fn listen_keys(mut port: Box) { + //ctrl+c单独处理 + let mut ctrlc_port = port.try_clone().unwrap(); + ctrlc::set_handler(move || { + ctrlc_port.write(&get_key_data(KeyCode::Char('c'), true)).unwrap(); + }) + .expect("Error setting Ctrl-C handler"); + //port.write(&get_special_key_codes("[?1;0c")).unwrap(); + + thread::spawn(move || { + loop { + let mut code = vec![]; + // `read()` blocks until an `Event` is available + match crossterm::event::read().unwrap() { + //按键事件 + Event::Key(event) => { + if event.kind == KeyEventKind::Press { + code = get_key_data(event.code, event.modifiers == KeyModifiers::CONTROL); + } + } + // Event::Resize(columns, _) => { + // code = get_special_key_codes( + // if columns >= 132 { + // "[?3h" + // } else { + // "[?3l" + // } + // ); + // }, + _ => (), + }; + if code.len() > 0 { + port.write(&code).unwrap(); + } + } + }); +} + +//返回按键数据 +fn get_key_data(key: KeyCode, ctrl: bool) -> Vec { + match key { + //数据来源:https://redirect.cs.umbc.edu/portal/help/theory/ascii.txt + //ctrl组合键 + KeyCode::Char('@') if ctrl => vec![0x00], + KeyCode::Char(' ') if ctrl => vec![0x00], + KeyCode::Char('A') | KeyCode::Char('a') if ctrl => vec![0x01], + KeyCode::Char('B') | KeyCode::Char('b') if ctrl => vec![0x02], + KeyCode::Char('C') | KeyCode::Char('c') if ctrl => vec![0x03], + KeyCode::Char('D') | KeyCode::Char('d') if ctrl => vec![0x04], + KeyCode::Char('E') | KeyCode::Char('e') if ctrl => vec![0x05], + KeyCode::Char('F') | KeyCode::Char('f') if ctrl => vec![0x06], + KeyCode::Char('G') | KeyCode::Char('g') if ctrl => vec![0x07], + KeyCode::Char('H') | KeyCode::Char('h') if ctrl => vec![0x08], + KeyCode::Char('I') | KeyCode::Char('i') if ctrl => vec![0x09], + KeyCode::Char('J') | KeyCode::Char('j') if ctrl => vec![0x0A], + KeyCode::Char('K') | KeyCode::Char('k') if ctrl => vec![0x0B], + KeyCode::Char('L') | KeyCode::Char('l') if ctrl => vec![0x0C], + KeyCode::Char('M') | KeyCode::Char('m') if ctrl => vec![0x0D], + KeyCode::Char('N') | KeyCode::Char('n') if ctrl => vec![0x0E], + KeyCode::Char('O') | KeyCode::Char('o') if ctrl => vec![0x0F], + KeyCode::Char('P') | KeyCode::Char('p') if ctrl => vec![0x10], + KeyCode::Char('Q') | KeyCode::Char('q') if ctrl => vec![0x11], + KeyCode::Char('R') | KeyCode::Char('r') if ctrl => vec![0x12], + KeyCode::Char('S') | KeyCode::Char('s') if ctrl => vec![0x13], + KeyCode::Char('T') | KeyCode::Char('t') if ctrl => vec![0x14], + KeyCode::Char('U') | KeyCode::Char('u') if ctrl => vec![0x15], + KeyCode::Char('V') | KeyCode::Char('v') if ctrl => vec![0x16], + KeyCode::Char('W') | KeyCode::Char('w') if ctrl => vec![0x17], + KeyCode::Char('X') | KeyCode::Char('x') if ctrl => vec![0x18], + KeyCode::Char('Y') | KeyCode::Char('y') if ctrl => vec![0x19], + KeyCode::Char('Z') | KeyCode::Char('z') if ctrl => vec![0x1A], + KeyCode::Char('[') if ctrl => vec![0x1B], + KeyCode::Char('\\') if ctrl => vec![0x1C], + KeyCode::Char(']') if ctrl => vec![0x1D], + KeyCode::Char('^') if ctrl => vec![0x1E], + KeyCode::Char('_') if ctrl => vec![0x1F], + //普通字符按键 + KeyCode::Char(' ') => vec![0x20], + KeyCode::Char('!') => vec![0x21], + KeyCode::Char('"') => vec![0x22], + KeyCode::Char('#') => vec![0x23], + KeyCode::Char('$') => vec![0x24], + KeyCode::Char('%') => vec![0x25], + KeyCode::Char('&') => vec![0x26], + KeyCode::Char('\'') => vec![0x27], + KeyCode::Char('(') => vec![0x28], + KeyCode::Char(')') => vec![0x29], + KeyCode::Char('*') => vec![0x2A], + KeyCode::Char('+') => vec![0x2B], + KeyCode::Char(',') => vec![0x2C], + KeyCode::Char('-') => vec![0x2D], + KeyCode::Char('.') => vec![0x2E], + KeyCode::Char('/') => vec![0x2F], + KeyCode::Char('0') => vec![0x30], + KeyCode::Char('1') => vec![0x31], + KeyCode::Char('2') => vec![0x32], + KeyCode::Char('3') => vec![0x33], + KeyCode::Char('4') => vec![0x34], + KeyCode::Char('5') => vec![0x35], + KeyCode::Char('6') => vec![0x36], + KeyCode::Char('7') => vec![0x37], + KeyCode::Char('8') => vec![0x38], + KeyCode::Char('9') => vec![0x39], + KeyCode::Char(':') => vec![0x3A], + KeyCode::Char(';') => vec![0x3B], + KeyCode::Char('<') => vec![0x3C], + KeyCode::Char('=') => vec![0x3D], + KeyCode::Char('>') => vec![0x3E], + KeyCode::Char('?') => vec![0x3F], + KeyCode::Char('@') => vec![0x40], + KeyCode::Char('A') => vec![0x41], + KeyCode::Char('B') => vec![0x42], + KeyCode::Char('C') => vec![0x43], + KeyCode::Char('D') => vec![0x44], + KeyCode::Char('E') => vec![0x45], + KeyCode::Char('F') => vec![0x46], + KeyCode::Char('G') => vec![0x47], + KeyCode::Char('H') => vec![0x48], + KeyCode::Char('I') => vec![0x49], + KeyCode::Char('J') => vec![0x4A], + KeyCode::Char('K') => vec![0x4B], + KeyCode::Char('L') => vec![0x4C], + KeyCode::Char('M') => vec![0x4D], + KeyCode::Char('N') => vec![0x4E], + KeyCode::Char('O') => vec![0x4F], + KeyCode::Char('P') => vec![0x50], + KeyCode::Char('Q') => vec![0x51], + KeyCode::Char('R') => vec![0x52], + KeyCode::Char('S') => vec![0x53], + KeyCode::Char('T') => vec![0x54], + KeyCode::Char('U') => vec![0x55], + KeyCode::Char('V') => vec![0x56], + KeyCode::Char('W') => vec![0x57], + KeyCode::Char('X') => vec![0x58], + KeyCode::Char('Y') => vec![0x59], + KeyCode::Char('Z') => vec![0x5A], + KeyCode::Char('[') => vec![0x5B], + KeyCode::Char('\\') => vec![0x5C], + KeyCode::Char(']') => vec![0x5D], + KeyCode::Char('^') => vec![0x5E], + KeyCode::Char('_') => vec![0x5F], + KeyCode::Char('`') => vec![0x60], + KeyCode::Char('a') => vec![0x61], + KeyCode::Char('b') => vec![0x62], + KeyCode::Char('c') => vec![0x63], + KeyCode::Char('d') => vec![0x64], + KeyCode::Char('e') => vec![0x65], + KeyCode::Char('f') => vec![0x66], + KeyCode::Char('g') => vec![0x67], + KeyCode::Char('h') => vec![0x68], + KeyCode::Char('i') => vec![0x69], + KeyCode::Char('j') => vec![0x6A], + KeyCode::Char('k') => vec![0x6B], + KeyCode::Char('l') => vec![0x6C], + KeyCode::Char('m') => vec![0x6D], + KeyCode::Char('n') => vec![0x6E], + KeyCode::Char('o') => vec![0x6F], + KeyCode::Char('p') => vec![0x70], + KeyCode::Char('q') => vec![0x71], + KeyCode::Char('r') => vec![0x72], + KeyCode::Char('s') => vec![0x73], + KeyCode::Char('t') => vec![0x74], + KeyCode::Char('u') => vec![0x75], + KeyCode::Char('v') => vec![0x76], + KeyCode::Char('w') => vec![0x77], + KeyCode::Char('x') => vec![0x78], + KeyCode::Char('y') => vec![0x79], + KeyCode::Char('z') => vec![0x7A], + KeyCode::Char('{') => vec![0x7B], + KeyCode::Char('|') => vec![0x7C], + KeyCode::Char('}') => vec![0x7D], + KeyCode::Char('~') => vec![0x7E], + //中文啥的 + KeyCode::Char(any) => any.to_string().as_bytes().to_vec(), + + //特殊按键 + KeyCode::Delete => vec![0x7F], + KeyCode::Backspace => vec![0x08], + KeyCode::Tab => vec![0x09], + KeyCode::Enter => vec![0x0D], + KeyCode::Pause=> vec![0x1A], + KeyCode::Esc => vec![0x1B], + + // https://learn.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences + KeyCode::Up if ctrl => get_special_key_codes("[1;5A"), + KeyCode::Down if ctrl => get_special_key_codes("[1;5B"), + KeyCode::Right if ctrl => get_special_key_codes("[1;5C"), + KeyCode::Left if ctrl => get_special_key_codes("[1;5D"), + KeyCode::Up => get_special_key_codes("[A"), + KeyCode::Down => get_special_key_codes("[B"), + KeyCode::Right => get_special_key_codes("[C"), + KeyCode::Left => get_special_key_codes("[D"), + KeyCode::Home => get_special_key_codes("[H"), + KeyCode::End => get_special_key_codes("[F"), + KeyCode::Insert => get_special_key_codes("[2~"), + KeyCode::PageUp => get_special_key_codes("[5~"), + KeyCode::PageDown => get_special_key_codes("[6~"), + KeyCode::F(1) => get_special_key_codes("OP"), + KeyCode::F(2) => get_special_key_codes("OQ"), + KeyCode::F(3) => get_special_key_codes("OR"), + KeyCode::F(4) => get_special_key_codes("OS"), + KeyCode::F(5) => get_special_key_codes("[15~"), + KeyCode::F(6) => get_special_key_codes("[17~"), + KeyCode::F(7) => get_special_key_codes("[18~"), + KeyCode::F(8) => get_special_key_codes("[19~"), + KeyCode::F(9) => get_special_key_codes("[20~"), + KeyCode::F(10) => get_special_key_codes("[21~"), + KeyCode::F(11) => get_special_key_codes("[23~"), + KeyCode::F(12) => get_special_key_codes("[24~"), + + + _ => vec![], //其他按键不处理 + } +} + +fn get_special_key_codes(s : &str) -> Vec { + let mut v = vec![0x1B]; + let mut b = s.as_bytes().to_vec(); + v.append(&mut b); + v +} diff --git a/src/main.rs b/src/main.rs index fb5ee89..06d2194 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,31 @@ -use std::io::{self, Write, Read}; +use std::{io::{self, Write}, sync::mpsc}; + +use crate::uart_readout::read_loop; mod args_parse; +mod uart_readout; +mod key_listener; fn main() { let args = args_parse::get_args(); - let mut port = serialport::new(args.port, args.baud_rate) - .timeout(std::time::Duration::from_millis(10)).flow_control(serialport::FlowControl::None) - .open().unwrap(); - port.write_request_to_send(args.rts != 0).unwrap(); - port.write_data_terminal_ready(args.dtr != 0).unwrap(); + + let (tx, rx) = mpsc::channel(); + //清屏 print!("\x1bc"); io::stdout().flush().unwrap(); - let mut buff : [u8;4096] = [0;4096]; - let mut read_buff = [0;4096]; + + let port = read_loop(tx.clone(), &args); + + key_listener::listen_keys(port); + loop { - let len = match port.read(&mut buff) { - Err(e) if e.kind() == std::io::ErrorKind::TimedOut => 0, - e => e.unwrap(), - }; - let read_len = std::io::stdin().read(&mut read_buff).unwrap(); - if read_len != 0 { - println!("read:{}",String::from_utf8_lossy(&read_buff[0..read_len])); - port.write(&read_buff[0..read_len]).unwrap(); - } - //没数据,不往下跑 - if len == 0 { - continue; + let r = rx.recv().unwrap(); + if r.len() == 0 {//串口异常 + println!("serial port error! exit!"); + break; } - io::stdout().write(&buff[0..len]).unwrap(); - io::stdout().flush().unwrap(); + let s = String::from_utf8_lossy(&r).to_string(); + io::stdout().write(s.as_bytes()).unwrap(); + io::stdout().flush().ok(); } } diff --git a/src/uart_readout.rs b/src/uart_readout.rs new file mode 100644 index 0000000..8a3d0b1 --- /dev/null +++ b/src/uart_readout.rs @@ -0,0 +1,33 @@ +use std::{sync::mpsc::Sender, io::Read, thread}; +use serialport::SerialPort; +use crate::args_parse::Args; + +//读取串口数据的线程 +pub fn read_loop(tx: Sender>, args : &Args) -> Box { + let mut port = serialport::new(&args.port, args.baud_rate) + .timeout(std::time::Duration::from_millis(10)).flow_control(serialport::FlowControl::None) + .open().unwrap(); + port.write_request_to_send(args.rts != 0).unwrap(); + port.write_data_terminal_ready(args.dtr != 0).unwrap(); + let mut buff : [u8;4096] = [0;4096]; + let mut port_loop = port.try_clone().unwrap(); + thread::spawn(move || { + loop { + let len = match port_loop.read(&mut buff) { + Err(e) if e.kind() == std::io::ErrorKind::TimedOut => 0, + Err(e) => { + println!("error: {:?}", e); + tx.send(vec![].to_vec()).unwrap();//发送空数据,表示串口异常 + 0 + }, + Ok(e) => e, + }; + //没数据,不往下跑 + if len == 0 { + continue; + } + tx.send(buff[0..len].to_vec()).unwrap(); + } + }); + port +}