├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── img ├── cli.png └── htop.gif └── src ├── args_parse.rs ├── key_listener.rs ├── main.rs └── uart_readout.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .vscode/ -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.15" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "is_terminal_polyfill", 17 | "utf8parse", 18 | ] 19 | 20 | [[package]] 21 | name = "anstyle" 22 | version = "1.0.8" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 25 | 26 | [[package]] 27 | name = "anstyle-parse" 28 | version = "0.2.5" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 31 | dependencies = [ 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle-query" 37 | version = "1.1.1" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 40 | dependencies = [ 41 | "windows-sys 0.52.0", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-wincon" 46 | version = "3.0.4" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 49 | dependencies = [ 50 | "anstyle", 51 | "windows-sys 0.52.0", 52 | ] 53 | 54 | [[package]] 55 | name = "autocfg" 56 | version = "1.4.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 59 | 60 | [[package]] 61 | name = "bitflags" 62 | version = "1.3.2" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 65 | 66 | [[package]] 67 | name = "bitflags" 68 | version = "2.6.0" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 71 | 72 | [[package]] 73 | name = "cfg-if" 74 | version = "1.0.0" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 77 | 78 | [[package]] 79 | name = "cfg_aliases" 80 | version = "0.2.1" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 83 | 84 | [[package]] 85 | name = "clap" 86 | version = "4.5.19" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" 89 | dependencies = [ 90 | "clap_builder", 91 | "clap_derive", 92 | ] 93 | 94 | [[package]] 95 | name = "clap_builder" 96 | version = "4.5.19" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" 99 | dependencies = [ 100 | "anstream", 101 | "anstyle", 102 | "clap_lex", 103 | "strsim", 104 | ] 105 | 106 | [[package]] 107 | name = "clap_derive" 108 | version = "4.5.18" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" 111 | dependencies = [ 112 | "heck", 113 | "proc-macro2", 114 | "quote", 115 | "syn", 116 | ] 117 | 118 | [[package]] 119 | name = "clap_lex" 120 | version = "0.7.2" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 123 | 124 | [[package]] 125 | name = "colorchoice" 126 | version = "1.0.2" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 129 | 130 | [[package]] 131 | name = "core-foundation-sys" 132 | version = "0.8.7" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 135 | 136 | [[package]] 137 | name = "crossterm" 138 | version = "0.28.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" 141 | dependencies = [ 142 | "bitflags 2.6.0", 143 | "crossterm_winapi", 144 | "mio", 145 | "parking_lot", 146 | "rustix", 147 | "signal-hook", 148 | "signal-hook-mio", 149 | "winapi", 150 | ] 151 | 152 | [[package]] 153 | name = "crossterm_winapi" 154 | version = "0.9.1" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 157 | dependencies = [ 158 | "winapi", 159 | ] 160 | 161 | [[package]] 162 | name = "ctrlc" 163 | version = "3.4.5" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" 166 | dependencies = [ 167 | "nix 0.29.0", 168 | "windows-sys 0.59.0", 169 | ] 170 | 171 | [[package]] 172 | name = "deranged" 173 | version = "0.3.11" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 176 | dependencies = [ 177 | "powerfmt", 178 | ] 179 | 180 | [[package]] 181 | name = "errno" 182 | version = "0.3.9" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 185 | dependencies = [ 186 | "libc", 187 | "windows-sys 0.52.0", 188 | ] 189 | 190 | [[package]] 191 | name = "heck" 192 | version = "0.5.0" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 195 | 196 | [[package]] 197 | name = "hermit-abi" 198 | version = "0.3.9" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 201 | 202 | [[package]] 203 | name = "io-kit-sys" 204 | version = "0.4.1" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" 207 | dependencies = [ 208 | "core-foundation-sys", 209 | "mach2", 210 | ] 211 | 212 | [[package]] 213 | name = "is_terminal_polyfill" 214 | version = "1.70.1" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 217 | 218 | [[package]] 219 | name = "libc" 220 | version = "0.2.159" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" 223 | 224 | [[package]] 225 | name = "libudev" 226 | version = "0.3.0" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" 229 | dependencies = [ 230 | "libc", 231 | "libudev-sys", 232 | ] 233 | 234 | [[package]] 235 | name = "libudev-sys" 236 | version = "0.1.4" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" 239 | dependencies = [ 240 | "libc", 241 | "pkg-config", 242 | ] 243 | 244 | [[package]] 245 | name = "linux-raw-sys" 246 | version = "0.4.14" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 249 | 250 | [[package]] 251 | name = "lock_api" 252 | version = "0.4.12" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 255 | dependencies = [ 256 | "autocfg", 257 | "scopeguard", 258 | ] 259 | 260 | [[package]] 261 | name = "log" 262 | version = "0.4.22" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 265 | 266 | [[package]] 267 | name = "mach2" 268 | version = "0.4.2" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" 271 | dependencies = [ 272 | "libc", 273 | ] 274 | 275 | [[package]] 276 | name = "mio" 277 | version = "1.0.2" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 280 | dependencies = [ 281 | "hermit-abi", 282 | "libc", 283 | "log", 284 | "wasi", 285 | "windows-sys 0.52.0", 286 | ] 287 | 288 | [[package]] 289 | name = "nix" 290 | version = "0.26.4" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 293 | dependencies = [ 294 | "bitflags 1.3.2", 295 | "cfg-if", 296 | "libc", 297 | ] 298 | 299 | [[package]] 300 | name = "nix" 301 | version = "0.29.0" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" 304 | dependencies = [ 305 | "bitflags 2.6.0", 306 | "cfg-if", 307 | "cfg_aliases", 308 | "libc", 309 | ] 310 | 311 | [[package]] 312 | name = "num-conv" 313 | version = "0.1.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 316 | 317 | [[package]] 318 | name = "parking_lot" 319 | version = "0.12.3" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 322 | dependencies = [ 323 | "lock_api", 324 | "parking_lot_core", 325 | ] 326 | 327 | [[package]] 328 | name = "parking_lot_core" 329 | version = "0.9.10" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 332 | dependencies = [ 333 | "cfg-if", 334 | "libc", 335 | "redox_syscall", 336 | "smallvec", 337 | "windows-targets", 338 | ] 339 | 340 | [[package]] 341 | name = "pkg-config" 342 | version = "0.3.31" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 345 | 346 | [[package]] 347 | name = "powerfmt" 348 | version = "0.2.0" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 351 | 352 | [[package]] 353 | name = "proc-macro2" 354 | version = "1.0.87" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" 357 | dependencies = [ 358 | "unicode-ident", 359 | ] 360 | 361 | [[package]] 362 | name = "quote" 363 | version = "1.0.37" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 366 | dependencies = [ 367 | "proc-macro2", 368 | ] 369 | 370 | [[package]] 371 | name = "redox_syscall" 372 | version = "0.5.7" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 375 | dependencies = [ 376 | "bitflags 2.6.0", 377 | ] 378 | 379 | [[package]] 380 | name = "rustix" 381 | version = "0.38.37" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 384 | dependencies = [ 385 | "bitflags 2.6.0", 386 | "errno", 387 | "libc", 388 | "linux-raw-sys", 389 | "windows-sys 0.52.0", 390 | ] 391 | 392 | [[package]] 393 | name = "scopeguard" 394 | version = "1.2.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 397 | 398 | [[package]] 399 | name = "serde" 400 | version = "1.0.210" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 403 | dependencies = [ 404 | "serde_derive", 405 | ] 406 | 407 | [[package]] 408 | name = "serde_derive" 409 | version = "1.0.210" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 412 | dependencies = [ 413 | "proc-macro2", 414 | "quote", 415 | "syn", 416 | ] 417 | 418 | [[package]] 419 | name = "serialport" 420 | version = "4.5.1" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "3ba776acc8c373b9175829206229366273225436845c04f9c20aab8099960e2e" 423 | dependencies = [ 424 | "bitflags 2.6.0", 425 | "cfg-if", 426 | "core-foundation-sys", 427 | "io-kit-sys", 428 | "libudev", 429 | "mach2", 430 | "nix 0.26.4", 431 | "scopeguard", 432 | "unescaper", 433 | "winapi", 434 | ] 435 | 436 | [[package]] 437 | name = "serialport_monitor" 438 | version = "1.0.0" 439 | dependencies = [ 440 | "clap", 441 | "crossterm", 442 | "ctrlc", 443 | "serialport", 444 | "time", 445 | ] 446 | 447 | [[package]] 448 | name = "signal-hook" 449 | version = "0.3.17" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 452 | dependencies = [ 453 | "libc", 454 | "signal-hook-registry", 455 | ] 456 | 457 | [[package]] 458 | name = "signal-hook-mio" 459 | version = "0.2.4" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" 462 | dependencies = [ 463 | "libc", 464 | "mio", 465 | "signal-hook", 466 | ] 467 | 468 | [[package]] 469 | name = "signal-hook-registry" 470 | version = "1.4.2" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 473 | dependencies = [ 474 | "libc", 475 | ] 476 | 477 | [[package]] 478 | name = "smallvec" 479 | version = "1.13.2" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 482 | 483 | [[package]] 484 | name = "strsim" 485 | version = "0.11.1" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 488 | 489 | [[package]] 490 | name = "syn" 491 | version = "2.0.79" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" 494 | dependencies = [ 495 | "proc-macro2", 496 | "quote", 497 | "unicode-ident", 498 | ] 499 | 500 | [[package]] 501 | name = "thiserror" 502 | version = "1.0.64" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" 505 | dependencies = [ 506 | "thiserror-impl", 507 | ] 508 | 509 | [[package]] 510 | name = "thiserror-impl" 511 | version = "1.0.64" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" 514 | dependencies = [ 515 | "proc-macro2", 516 | "quote", 517 | "syn", 518 | ] 519 | 520 | [[package]] 521 | name = "time" 522 | version = "0.3.36" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 525 | dependencies = [ 526 | "deranged", 527 | "num-conv", 528 | "powerfmt", 529 | "serde", 530 | "time-core", 531 | ] 532 | 533 | [[package]] 534 | name = "time-core" 535 | version = "0.1.2" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 538 | 539 | [[package]] 540 | name = "unescaper" 541 | version = "0.1.5" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" 544 | dependencies = [ 545 | "thiserror", 546 | ] 547 | 548 | [[package]] 549 | name = "unicode-ident" 550 | version = "1.0.13" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 553 | 554 | [[package]] 555 | name = "utf8parse" 556 | version = "0.2.2" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 559 | 560 | [[package]] 561 | name = "wasi" 562 | version = "0.11.0+wasi-snapshot-preview1" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 565 | 566 | [[package]] 567 | name = "winapi" 568 | version = "0.3.9" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 571 | dependencies = [ 572 | "winapi-i686-pc-windows-gnu", 573 | "winapi-x86_64-pc-windows-gnu", 574 | ] 575 | 576 | [[package]] 577 | name = "winapi-i686-pc-windows-gnu" 578 | version = "0.4.0" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 581 | 582 | [[package]] 583 | name = "winapi-x86_64-pc-windows-gnu" 584 | version = "0.4.0" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 587 | 588 | [[package]] 589 | name = "windows-sys" 590 | version = "0.52.0" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 593 | dependencies = [ 594 | "windows-targets", 595 | ] 596 | 597 | [[package]] 598 | name = "windows-sys" 599 | version = "0.59.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 602 | dependencies = [ 603 | "windows-targets", 604 | ] 605 | 606 | [[package]] 607 | name = "windows-targets" 608 | version = "0.52.6" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 611 | dependencies = [ 612 | "windows_aarch64_gnullvm", 613 | "windows_aarch64_msvc", 614 | "windows_i686_gnu", 615 | "windows_i686_gnullvm", 616 | "windows_i686_msvc", 617 | "windows_x86_64_gnu", 618 | "windows_x86_64_gnullvm", 619 | "windows_x86_64_msvc", 620 | ] 621 | 622 | [[package]] 623 | name = "windows_aarch64_gnullvm" 624 | version = "0.52.6" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 627 | 628 | [[package]] 629 | name = "windows_aarch64_msvc" 630 | version = "0.52.6" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 633 | 634 | [[package]] 635 | name = "windows_i686_gnu" 636 | version = "0.52.6" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 639 | 640 | [[package]] 641 | name = "windows_i686_gnullvm" 642 | version = "0.52.6" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 645 | 646 | [[package]] 647 | name = "windows_i686_msvc" 648 | version = "0.52.6" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 651 | 652 | [[package]] 653 | name = "windows_x86_64_gnu" 654 | version = "0.52.6" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 657 | 658 | [[package]] 659 | name = "windows_x86_64_gnullvm" 660 | version = "0.52.6" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 663 | 664 | [[package]] 665 | name = "windows_x86_64_msvc" 666 | version = "0.52.6" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 669 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serialport_monitor" 3 | version = "1.0.1" 4 | description = "monitor and control serialport in terminal" 5 | authors = ["chenxuuu "] 6 | edition = "2021" 7 | repository = "https://github.com/chenxuuu/serialport_monitor" 8 | homepage = "https://github.com/chenxuuu/serialport_monitor" 9 | keywords = ["serialport", "cli"] 10 | license = "MIT" 11 | exclude = [ 12 | "img/*", 13 | ] 14 | 15 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 16 | 17 | [dependencies] 18 | serialport = "4" 19 | time="0.3" 20 | clap = { version = "4", features = ["derive"] } 21 | crossterm = "0" 22 | ctrlc = "3" 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 chenxuuu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # serialport_monitor 2 | 3 | 用自己喜欢的终端打印串口日志。pure serialport data printer, for your favorite terminal. 4 | 5 | 可以代替MobaXterm、SecureCRT、PuTTy等串口连接SSH或查看日志的软件。 6 | 7 | ![cli](img/cli.png) 8 | 9 | ![htop](img/htop.gif) 10 | 11 | 我是搭配window terminal用,挺好 12 | 13 | 已上传win的编译文件到release,可以自取 14 | 15 | ## Install 16 | 17 | ```bash 18 | cargo install serialport_monitor 19 | ``` 20 | -------------------------------------------------------------------------------- /img/cli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/serialport_monitor/16e6569201caaf853e857740a0095ef2e0b3bf59/img/cli.png -------------------------------------------------------------------------------- /img/htop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/serialport_monitor/16e6569201caaf853e857740a0095ef2e0b3bf59/img/htop.gif -------------------------------------------------------------------------------- /src/args_parse.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[clap()] 5 | pub struct Args { 6 | ///port name, example COM1,/dev/ttyUSB0 7 | #[clap(short, long, value_parser,value_name="port")] 8 | pub port: String, 9 | ///baud_rate; default 115200 10 | #[clap(short, long, value_parser,default_value_t= 115200)] 11 | pub baud_rate: u32, 12 | ///RTS status; 0 disable, 1 enable 13 | #[clap(short, long, value_parser, default_value_t = 0)] 14 | pub rts: u8, 15 | ///DTR status; 0 disable, 1 enable 16 | #[clap(short, long, value_parser, default_value_t = 0)] 17 | pub dtr: u8, 18 | } 19 | 20 | //获取参数 21 | pub fn get_args() -> Args { 22 | match Args::try_parse(){ 23 | Ok(a) => a, 24 | Err(e) if e.kind() == clap::error::ErrorKind::DisplayHelp => Args::parse() , 25 | Err(e) if e.kind() == clap::error::ErrorKind::DisplayVersion => Args::parse() , 26 | _ => { 27 | //没给参数,手动获取下 28 | let mut buff = String::new(); 29 | let mut a = Args{ 30 | port: String::new(), 31 | baud_rate: 115200, 32 | rts: 0, 33 | dtr: 0, 34 | }; 35 | println!("your serial ports list:"); 36 | let port_list = serialport::available_ports().unwrap(); 37 | port_list.iter().for_each(|p| println!("{}",p.port_name)); 38 | println!("please select your serial port (default first port if exist):"); 39 | std::io::stdin().read_line(&mut buff).expect("read_line error!"); 40 | a.port = if buff.trim().len() == 0 { 41 | if port_list.len() > 0{ 42 | port_list[0].port_name.clone() 43 | } 44 | else{ 45 | panic!("no port found!") 46 | } 47 | } else { 48 | buff.trim().to_string() 49 | }; 50 | buff.clear(); 51 | 52 | println!("please set a baud rate (default 115200):"); 53 | std::io::stdin().read_line(&mut buff).expect("read_line error!"); 54 | if buff.trim().len() != 0 { 55 | a.baud_rate = buff.trim().parse().unwrap(); 56 | } 57 | buff.clear(); 58 | println!("please set rts status (default 0, disable):"); 59 | std::io::stdin().read_line(&mut buff).expect("read_line error!"); 60 | if buff.trim().len() != 0 { 61 | a.rts = buff.trim().parse().unwrap(); 62 | } 63 | buff.clear(); 64 | println!("please set dtr status (default 0, enable):"); 65 | std::io::stdin().read_line(&mut buff).expect("read_line error!"); 66 | if buff.trim().len() != 0 { 67 | a.dtr = buff.trim().parse().unwrap(); 68 | } 69 | a 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/key_listener.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers}; 4 | use serialport::SerialPort; 5 | 6 | pub fn listen_keys(mut port: Box) { 7 | //ctrl+c单独处理 8 | let mut ctrlc_port = port.try_clone().unwrap(); 9 | ctrlc::set_handler(move || { 10 | ctrlc_port.write(&get_key_data(KeyCode::Char('c'), true)).unwrap(); 11 | }) 12 | .expect("Error setting Ctrl-C handler"); 13 | //port.write(&get_special_key_codes("[?1;0c")).unwrap(); 14 | 15 | thread::spawn(move || { 16 | loop { 17 | let mut code = vec![]; 18 | // `read()` blocks until an `Event` is available 19 | match crossterm::event::read().unwrap() { 20 | //按键事件 21 | Event::Key(event) => { 22 | if event.kind == KeyEventKind::Press { 23 | code = get_key_data(event.code, event.modifiers == KeyModifiers::CONTROL); 24 | } 25 | } 26 | // Event::Resize(columns, _) => { 27 | // code = get_special_key_codes( 28 | // if columns >= 132 { 29 | // "[?3h" 30 | // } else { 31 | // "[?3l" 32 | // } 33 | // ); 34 | // }, 35 | _ => (), 36 | }; 37 | if code.len() > 0 { 38 | port.write(&code).unwrap(); 39 | } 40 | } 41 | }); 42 | } 43 | 44 | //返回按键数据 45 | fn get_key_data(key: KeyCode, ctrl: bool) -> Vec { 46 | match key { 47 | //数据来源:https://redirect.cs.umbc.edu/portal/help/theory/ascii.txt 48 | //ctrl组合键 49 | KeyCode::Char('@') if ctrl => vec![0x00], 50 | KeyCode::Char(' ') if ctrl => vec![0x00], 51 | KeyCode::Char('A') | KeyCode::Char('a') if ctrl => vec![0x01], 52 | KeyCode::Char('B') | KeyCode::Char('b') if ctrl => vec![0x02], 53 | KeyCode::Char('C') | KeyCode::Char('c') if ctrl => vec![0x03], 54 | KeyCode::Char('D') | KeyCode::Char('d') if ctrl => vec![0x04], 55 | KeyCode::Char('E') | KeyCode::Char('e') if ctrl => vec![0x05], 56 | KeyCode::Char('F') | KeyCode::Char('f') if ctrl => vec![0x06], 57 | KeyCode::Char('G') | KeyCode::Char('g') if ctrl => vec![0x07], 58 | KeyCode::Char('H') | KeyCode::Char('h') if ctrl => vec![0x08], 59 | KeyCode::Char('I') | KeyCode::Char('i') if ctrl => vec![0x09], 60 | KeyCode::Char('J') | KeyCode::Char('j') if ctrl => vec![0x0A], 61 | KeyCode::Char('K') | KeyCode::Char('k') if ctrl => vec![0x0B], 62 | KeyCode::Char('L') | KeyCode::Char('l') if ctrl => vec![0x0C], 63 | KeyCode::Char('M') | KeyCode::Char('m') if ctrl => vec![0x0D], 64 | KeyCode::Char('N') | KeyCode::Char('n') if ctrl => vec![0x0E], 65 | KeyCode::Char('O') | KeyCode::Char('o') if ctrl => vec![0x0F], 66 | KeyCode::Char('P') | KeyCode::Char('p') if ctrl => vec![0x10], 67 | KeyCode::Char('Q') | KeyCode::Char('q') if ctrl => vec![0x11], 68 | KeyCode::Char('R') | KeyCode::Char('r') if ctrl => vec![0x12], 69 | KeyCode::Char('S') | KeyCode::Char('s') if ctrl => vec![0x13], 70 | KeyCode::Char('T') | KeyCode::Char('t') if ctrl => vec![0x14], 71 | KeyCode::Char('U') | KeyCode::Char('u') if ctrl => vec![0x15], 72 | KeyCode::Char('V') | KeyCode::Char('v') if ctrl => vec![0x16], 73 | KeyCode::Char('W') | KeyCode::Char('w') if ctrl => vec![0x17], 74 | KeyCode::Char('X') | KeyCode::Char('x') if ctrl => vec![0x18], 75 | KeyCode::Char('Y') | KeyCode::Char('y') if ctrl => vec![0x19], 76 | KeyCode::Char('Z') | KeyCode::Char('z') if ctrl => vec![0x1A], 77 | KeyCode::Char('[') if ctrl => vec![0x1B], 78 | KeyCode::Char('\\') if ctrl => vec![0x1C], 79 | KeyCode::Char(']') if ctrl => vec![0x1D], 80 | KeyCode::Char('^') if ctrl => vec![0x1E], 81 | KeyCode::Char('_') if ctrl => vec![0x1F], 82 | //普通字符按键 83 | KeyCode::Char(' ') => vec![0x20], 84 | KeyCode::Char('!') => vec![0x21], 85 | KeyCode::Char('"') => vec![0x22], 86 | KeyCode::Char('#') => vec![0x23], 87 | KeyCode::Char('$') => vec![0x24], 88 | KeyCode::Char('%') => vec![0x25], 89 | KeyCode::Char('&') => vec![0x26], 90 | KeyCode::Char('\'') => vec![0x27], 91 | KeyCode::Char('(') => vec![0x28], 92 | KeyCode::Char(')') => vec![0x29], 93 | KeyCode::Char('*') => vec![0x2A], 94 | KeyCode::Char('+') => vec![0x2B], 95 | KeyCode::Char(',') => vec![0x2C], 96 | KeyCode::Char('-') => vec![0x2D], 97 | KeyCode::Char('.') => vec![0x2E], 98 | KeyCode::Char('/') => vec![0x2F], 99 | KeyCode::Char('0') => vec![0x30], 100 | KeyCode::Char('1') => vec![0x31], 101 | KeyCode::Char('2') => vec![0x32], 102 | KeyCode::Char('3') => vec![0x33], 103 | KeyCode::Char('4') => vec![0x34], 104 | KeyCode::Char('5') => vec![0x35], 105 | KeyCode::Char('6') => vec![0x36], 106 | KeyCode::Char('7') => vec![0x37], 107 | KeyCode::Char('8') => vec![0x38], 108 | KeyCode::Char('9') => vec![0x39], 109 | KeyCode::Char(':') => vec![0x3A], 110 | KeyCode::Char(';') => vec![0x3B], 111 | KeyCode::Char('<') => vec![0x3C], 112 | KeyCode::Char('=') => vec![0x3D], 113 | KeyCode::Char('>') => vec![0x3E], 114 | KeyCode::Char('?') => vec![0x3F], 115 | KeyCode::Char('@') => vec![0x40], 116 | KeyCode::Char('A') => vec![0x41], 117 | KeyCode::Char('B') => vec![0x42], 118 | KeyCode::Char('C') => vec![0x43], 119 | KeyCode::Char('D') => vec![0x44], 120 | KeyCode::Char('E') => vec![0x45], 121 | KeyCode::Char('F') => vec![0x46], 122 | KeyCode::Char('G') => vec![0x47], 123 | KeyCode::Char('H') => vec![0x48], 124 | KeyCode::Char('I') => vec![0x49], 125 | KeyCode::Char('J') => vec![0x4A], 126 | KeyCode::Char('K') => vec![0x4B], 127 | KeyCode::Char('L') => vec![0x4C], 128 | KeyCode::Char('M') => vec![0x4D], 129 | KeyCode::Char('N') => vec![0x4E], 130 | KeyCode::Char('O') => vec![0x4F], 131 | KeyCode::Char('P') => vec![0x50], 132 | KeyCode::Char('Q') => vec![0x51], 133 | KeyCode::Char('R') => vec![0x52], 134 | KeyCode::Char('S') => vec![0x53], 135 | KeyCode::Char('T') => vec![0x54], 136 | KeyCode::Char('U') => vec![0x55], 137 | KeyCode::Char('V') => vec![0x56], 138 | KeyCode::Char('W') => vec![0x57], 139 | KeyCode::Char('X') => vec![0x58], 140 | KeyCode::Char('Y') => vec![0x59], 141 | KeyCode::Char('Z') => vec![0x5A], 142 | KeyCode::Char('[') => vec![0x5B], 143 | KeyCode::Char('\\') => vec![0x5C], 144 | KeyCode::Char(']') => vec![0x5D], 145 | KeyCode::Char('^') => vec![0x5E], 146 | KeyCode::Char('_') => vec![0x5F], 147 | KeyCode::Char('`') => vec![0x60], 148 | KeyCode::Char('a') => vec![0x61], 149 | KeyCode::Char('b') => vec![0x62], 150 | KeyCode::Char('c') => vec![0x63], 151 | KeyCode::Char('d') => vec![0x64], 152 | KeyCode::Char('e') => vec![0x65], 153 | KeyCode::Char('f') => vec![0x66], 154 | KeyCode::Char('g') => vec![0x67], 155 | KeyCode::Char('h') => vec![0x68], 156 | KeyCode::Char('i') => vec![0x69], 157 | KeyCode::Char('j') => vec![0x6A], 158 | KeyCode::Char('k') => vec![0x6B], 159 | KeyCode::Char('l') => vec![0x6C], 160 | KeyCode::Char('m') => vec![0x6D], 161 | KeyCode::Char('n') => vec![0x6E], 162 | KeyCode::Char('o') => vec![0x6F], 163 | KeyCode::Char('p') => vec![0x70], 164 | KeyCode::Char('q') => vec![0x71], 165 | KeyCode::Char('r') => vec![0x72], 166 | KeyCode::Char('s') => vec![0x73], 167 | KeyCode::Char('t') => vec![0x74], 168 | KeyCode::Char('u') => vec![0x75], 169 | KeyCode::Char('v') => vec![0x76], 170 | KeyCode::Char('w') => vec![0x77], 171 | KeyCode::Char('x') => vec![0x78], 172 | KeyCode::Char('y') => vec![0x79], 173 | KeyCode::Char('z') => vec![0x7A], 174 | KeyCode::Char('{') => vec![0x7B], 175 | KeyCode::Char('|') => vec![0x7C], 176 | KeyCode::Char('}') => vec![0x7D], 177 | KeyCode::Char('~') => vec![0x7E], 178 | //中文啥的 179 | KeyCode::Char(any) => any.to_string().as_bytes().to_vec(), 180 | 181 | //特殊按键 182 | KeyCode::Delete => vec![0x7F], 183 | KeyCode::Backspace => vec![0x08], 184 | KeyCode::Tab => vec![0x09], 185 | KeyCode::Enter => vec![0x0D], 186 | KeyCode::Pause=> vec![0x1A], 187 | KeyCode::Esc => vec![0x1B], 188 | 189 | // https://learn.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences 190 | KeyCode::Up if ctrl => get_special_key_codes("[1;5A"), 191 | KeyCode::Down if ctrl => get_special_key_codes("[1;5B"), 192 | KeyCode::Right if ctrl => get_special_key_codes("[1;5C"), 193 | KeyCode::Left if ctrl => get_special_key_codes("[1;5D"), 194 | KeyCode::Up => get_special_key_codes("[A"), 195 | KeyCode::Down => get_special_key_codes("[B"), 196 | KeyCode::Right => get_special_key_codes("[C"), 197 | KeyCode::Left => get_special_key_codes("[D"), 198 | KeyCode::Home => get_special_key_codes("[H"), 199 | KeyCode::End => get_special_key_codes("[F"), 200 | KeyCode::Insert => get_special_key_codes("[2~"), 201 | KeyCode::PageUp => get_special_key_codes("[5~"), 202 | KeyCode::PageDown => get_special_key_codes("[6~"), 203 | KeyCode::F(1) => get_special_key_codes("OP"), 204 | KeyCode::F(2) => get_special_key_codes("OQ"), 205 | KeyCode::F(3) => get_special_key_codes("OR"), 206 | KeyCode::F(4) => get_special_key_codes("OS"), 207 | KeyCode::F(5) => get_special_key_codes("[15~"), 208 | KeyCode::F(6) => get_special_key_codes("[17~"), 209 | KeyCode::F(7) => get_special_key_codes("[18~"), 210 | KeyCode::F(8) => get_special_key_codes("[19~"), 211 | KeyCode::F(9) => get_special_key_codes("[20~"), 212 | KeyCode::F(10) => get_special_key_codes("[21~"), 213 | KeyCode::F(11) => get_special_key_codes("[23~"), 214 | KeyCode::F(12) => get_special_key_codes("[24~"), 215 | 216 | _ => vec![], //其他按键不处理 217 | } 218 | } 219 | 220 | fn get_special_key_codes(s : &str) -> Vec { 221 | let mut v = vec![0x1B]; 222 | let mut b = s.as_bytes().to_vec(); 223 | v.append(&mut b); 224 | v 225 | } 226 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{io::{self, Write}, sync::mpsc}; 2 | 3 | use crate::uart_readout::read_loop; 4 | mod args_parse; 5 | mod uart_readout; 6 | mod key_listener; 7 | 8 | fn main() { 9 | let args = args_parse::get_args(); 10 | 11 | let (tx, rx) = mpsc::channel(); 12 | 13 | //清屏 14 | print!("\x1bc"); 15 | io::stdout().flush().unwrap(); 16 | 17 | let port = read_loop(tx.clone(), &args); 18 | 19 | key_listener::listen_keys(port); 20 | 21 | loop { 22 | let r = rx.recv().unwrap(); 23 | if r.len() == 0 {//串口异常 24 | println!("serial port error! exit!"); 25 | break; 26 | } 27 | let s = String::from_utf8_lossy(&r).to_string(); 28 | io::stdout().write(s.as_bytes()).unwrap(); 29 | io::stdout().flush().ok(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/uart_readout.rs: -------------------------------------------------------------------------------- 1 | use std::{sync::mpsc::Sender, io::Read, thread}; 2 | use serialport::SerialPort; 3 | use crate::args_parse::Args; 4 | 5 | //读取串口数据的线程 6 | pub fn read_loop(tx: Sender>, args : &Args) -> Box { 7 | let mut port = serialport::new(&args.port, args.baud_rate) 8 | .timeout(std::time::Duration::from_millis(10)).flow_control(serialport::FlowControl::None) 9 | .open().unwrap(); 10 | port.write_request_to_send(args.rts != 0).unwrap(); 11 | port.write_data_terminal_ready(args.dtr != 0).unwrap(); 12 | let mut buff : [u8;4096] = [0;4096]; 13 | let mut port_loop = port.try_clone().unwrap(); 14 | thread::spawn(move || { 15 | loop { 16 | let len = match port_loop.read(&mut buff) { 17 | Err(e) if e.kind() == std::io::ErrorKind::TimedOut => 0, 18 | Err(e) => { 19 | println!("error: {:?}", e); 20 | tx.send(vec![].to_vec()).unwrap();//发送空数据,表示串口异常 21 | 0 22 | }, 23 | Ok(e) => e, 24 | }; 25 | //没数据,不往下跑 26 | if len == 0 { 27 | continue; 28 | } 29 | tx.send(buff[0..len].to_vec()).unwrap(); 30 | } 31 | }); 32 | port 33 | } 34 | --------------------------------------------------------------------------------