Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linux usb gadget serialport, get Not a typewriter #243

Open
cppcoffee opened this issue Jan 22, 2025 · 4 comments
Open

linux usb gadget serialport, get Not a typewriter #243

cppcoffee opened this issue Jan 22, 2025 · 4 comments

Comments

@cppcoffee
Copy link

cppcoffee commented Jan 22, 2025

Open the usb gadget serialport, get an error occurs.

The source code is as follows:

use serialport::{DataBits, Parity, StopBits};
use std::io::Read;
use std::io::{self, Write};
use std::time::Duration;

fn main() {
    let mut port = serialport::new("/dev/ttyGS0", 9600)
        .parity(Parity::None)
        .stop_bits(StopBits::One)
        .data_bits(DataBits::Eight)
        .timeout(Duration::from_secs(120))
        .open_native()
        .unwrap();       // Not a typewriter
...

Error message:

thread 'main' panicked at src/main.rs:13:10:
called `Result::unwrap()` on an `Err` value: Error { kind: Unknown, description: "Not a typewriter" }
@cppcoffee cppcoffee changed the title Not a typewriter linux usb gadget serialport, get Not a typewriter Jan 22, 2025
@sirhcel
Copy link
Contributor

sirhcel commented Jan 22, 2025

Sorry to hear that @cppcoffee! Let's dig into what's causing this. How do you set up the USB gadget device in question? Could you run your example with RUST_BACKTRACE set to 1? For example by setting in beforehand like:

$ export RUST_BACKTRACE=1

@asmforce
Copy link

asmforce commented Jan 22, 2025

It's not the same issue but seems to be related: 4.7.0 fails to work with virtual serial port created by socat utility while 4.6.1 works perfectly fine:

$ cargo build --release
   Compiling proc-macro2 v1.0.93
   Compiling unicode-ident v1.0.14
   Compiling libc v0.2.169
   Compiling pkg-config v0.3.31
   Compiling thiserror v1.0.69
   Compiling bitflags v1.3.2
   Compiling cfg-if v1.0.0
   Compiling bitflags v2.8.0
   Compiling scopeguard v1.2.0
   Compiling libudev-sys v0.1.4
   Compiling quote v1.0.38
   Compiling syn v2.0.96
   Compiling nix v0.26.4
   Compiling libudev v0.3.0
   Compiling thiserror-impl v1.0.69
   Compiling unescaper v0.1.5
   Compiling serialport v4.7.0
   Compiling experiments-rs v1.0.0 (/home/asmforce/work/experiments-rs)
    Finished `release` profile [optimized] target(s) in 2.52s
$ ./target/release/experiments-rs 
Error: Custom { kind: Other, error: "Not a typewriter" }
$ cargo update serialport
    Updating crates.io index
     Locking 1 package to latest compatible version
 Downgrading serialport v4.7.0 -> v4.6.1 (available: v4.7.0)
$ cargo build --release
   Compiling serialport v4.6.1
   Compiling experiments-rs v1.0.0 (/home/asmforce/work/experiments-rs)
    Finished `release` profile [optimized] target(s) in 0.52s
$ ./target/release/experiments-rs 
Written 4 bytes
Success

Here's the app's source code:

use std::io::{Error, Write};
use std::time::Duration;
use serialport::{FlowControl, DataBits, Parity, StopBits};

fn main() -> Result<(), Error> {
    let path = "/dev/ttyTEST";
    let builder = serialport::new(path, 9600)
        .flow_control(FlowControl::None)
        .data_bits(DataBits::Eight)
        .parity(Parity::None)
        .stop_bits(StopBits::One)
        .timeout(Duration::from_millis(1000));

    let mut port = builder.open()?;

    let data = [12u8, 23u8, 34u8, 45u8];
    match port.write(&data) {
        Ok(count) => println!("Written {} bytes", count),
        Err(e) => println!("{}", e)
    }

    match port.flush() {
        Ok(()) => println!("Success"),
        Err(e) => println!("{}", e)
    }

    Ok(())
}

And here is the command to create a virtual serial port:

sudo socat -d -d pty,link=/tmp/cvsimulator_sp,echo=0,perm=0777,b9600 pty,link=/dev/ttyTEST,echo=0,perm=0777,b9600

@sirhcel
Copy link
Contributor

sirhcel commented Jan 22, 2025

Thank you for bringing up the issue with Linux pseudo terminals @asmforce!

At a first glance, I have no idea how to reliably detect whether the actual device is supposed to support setting control lines. But trying on best-effort looks like a way to go. See sirhcel@9b56161.

@cppcoffee
Copy link
Author

cppcoffee commented Jan 23, 2025

Hi @sirhcel , testing revealed issues with serialport version 4.7.0, while version 4.6.1 works normally.

The test code is as follows:

fn test_serial() {
    let mut buf = [0; 4096];

    let mut port = serialport::new("/dev/ttyGS0", 1_500_000)
        .parity(Parity::Even)
        .stop_bits(StopBits::One)
        .data_bits(DataBits::Eight)
        .timeout(Duration::from_secs(120))
        .open_native()
        .unwrap();

    loop {
        let _n = port.read(&mut buf).unwrap();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants