Closed Sieyalixnet closed 1 year ago
Could you tell me a bit more? Which serial port device are you trying to change the settings for? What is the name of the device on the system, and what is the name according to the vendor?
And could you share a minimum example showing that the settings are not updated as expected without raising an error?
I am sorry, here's the code
fn main() {
let mut port = SerialPort::open("/dev/cu.usbserial-0001", 115200).unwrap();
let mut settings1 = port.get_configuration().unwrap().clone();
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings1.get_char_size(),
settings1.get_flow_control(),
settings1.get_parity(),
settings1.get_stop_bits(),
settings1.get_baud_rate()
);
settings1.set_baud_rate(9600);
settings1.set_char_size(serial2::CharSize::Bits5);
settings1.set_flow_control(serial2::FlowControl::XonXoff);
port.set_configuration(&settings1);
let mut settings2 = port.get_configuration().unwrap().clone();
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings2.get_char_size(),
settings2.get_flow_control(),
settings2.get_parity(),
settings2.get_stop_bits(),
settings2.get_baud_rate()
);
}
in terminal, the output is
Ok(Bits8),Ok(None),Ok(None),Ok(One),Ok(115200)
Ok(Bits8),Ok(None),Ok(None),Ok(One),Ok(9600)
I changed the library to serialport, but it works.
Hmm, you're not checking for errors when setting the configuration.
Could you try that to see if it reports an error?
port.set_configuration(&settings1).unwrap();
If I set "serial2::FlowControl::RtsCts" for flow control, it will crash. So here I try to set other settings.
However it will success, but still perform like above:
fn main() {
let mut port = SerialPort::open("/dev/cu.Bluetooth-Incoming-Port", 115200).unwrap();// I have not USB serial device now.
let mut settings1 = port.get_configuration().unwrap().clone();
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings1.get_char_size(),
settings1.get_flow_control(),
settings1.get_parity(),
settings1.get_stop_bits(),
settings1.get_baud_rate()
);
settings1.set_baud_rate(9600).unwrap();
settings1.set_char_size(serial2::CharSize::Bits5);
settings1.set_parity(serial2::Parity::Even);
settings1.set_stop_bits(serial2::StopBits::Two);
//settings1.set_flow_control(serial2::FlowControl::RtsCts);
port.set_configuration(&settings1).unwrap();//!!!! I added unwrap() here
let mut settings2 = port.get_configuration().unwrap().clone();
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings2.get_char_size(),
settings2.get_flow_control(),
settings2.get_parity(),
settings2.get_stop_bits(),
settings2.get_baud_rate()
);
}
In terminal :
Ok(Bits8),Ok(None),Ok(None),Ok(One),Ok(115200)
Ok(Bits8),Ok(None),Ok(None),Ok(Two),Ok(9600)
Even i added unwrap, it was successful to set the configuration. but the char size and parity didn't change.
Not all hardware is required to support all formats. It may be baudot code is not supported, its super old and very little used.
If its not supported though, I'd expect the set_configuration to return an error.?
Looking, it appears set_on_file uses an ioctl on linux instead of tcsetattr. Any reason why?
Also it says it allows the buffer to drain before applying settings.
From here:
https://manpages.debian.org/testing/manpages-dev/ioctl_tty.2.en.html
The following four ioctls, added in Linux 2.6.20, are just like TCGETS, TCSETS, TCSETSW, TCSETSF, except that they take a struct termios2 * instead of a struct termios *. If the structure member c_cflag contains the flag BOTHER, then the baud rate is stored in the structure members c_ispeed and c_ospeed as integer values. These ioctls are not supported on all architectures.
Okay, it looks like termios2 is being used.
Yeah, but this issue is about macOS, so it's somewhat different.
One annoying thing: the underlying syscall for setting TTY settings reports success if it applied any of the settings, not if it applied all of the settings.
I don't have a macOS device, so I can't really debug this myself.
What would help is to try and set each setting one at a time, and see if we get a failure then:
fn main() {
let mut port = SerialPort::open("/dev/cu.Bluetooth-Incoming-Port", 115200).unwrap();
let mut settings = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_baud_rate(9600).unwrap();
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_char_size(serial2::CharSize::Bits5);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_parity(serial2::Parity::Even);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_stop_bits(serial2::StopBits::Two);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
// settings1.set_flow_control(serial2::FlowControl::RtsCts);
// port.set_configuration(&settings).unwrap();
// let mut setting = port.get_configuration().unwrap();
}
fn print_settings(settings: &serial2::Settings) {
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings.get_char_size(),
settings.get_flow_control(),
settings.get_parity(),
settings.get_stop_bits(),
settings.get_baud_rate()
);
}
Setting flow control to RtsCts will be crashed, but it is ok if I set XonXoff. So I add this setting. Here's the code:
use serial2::SerialPort;
fn main() {
let mut port = SerialPort::open("/dev/cu.usbserial-110", 115200).unwrap();
let mut settings = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_baud_rate(9600).unwrap();
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_char_size(serial2::CharSize::Bits5);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_parity(serial2::Parity::Even);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_stop_bits(serial2::StopBits::Two);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
print_settings(&settings);
settings.set_flow_control(serial2::FlowControl::XonXoff);
port.set_configuration(&settings).unwrap();
let mut setting = port.get_configuration().unwrap();
}
fn print_settings(settings: &serial2::Settings) {
println!(
"{:?},{:?},{:?},{:?},{:?}",
settings.get_char_size(),
settings.get_flow_control(),
settings.get_parity(),
settings.get_stop_bits(),
settings.get_baud_rate()
);
}
Here's the output:
Ok(Bits8),Ok(None),Ok(None),Ok(One),Ok(115200)
Ok(Bits8),Ok(None),Ok(None),Ok(One),Ok(9600)
Ok(Bits5),Ok(None),Ok(None),Ok(One),Ok(9600)
Ok(Bits5),Ok(None),Ok(Odd),Ok(One),Ok(9600)
Ok(Bits5),Ok(None),Ok(Odd),Ok(Two),Ok(9600)
It is quite strange in setting the flow control and parity.
Ah, I found a bug in reporting the parity setting. It was reporting Odd and Even flipped. Setting it did actually work though.
Released 0.1.10 and 0.2.1 with a fix.
Regarding flow control, my guess is that the adapter doesn't support it? Or have you been able to get hardware flow control to work with other libraries?
Also, thank you for the reports, they are very useful!
Yes, the flow control can not be set maybe caused by the hardware. I try to set flow control by another library named serialport, it also doesn't work.(But in that library, both of them (FlowControl::Hardware, FlowControl::Software) can not be set.)
Environment: apple M2 and rust edition = "2021".
I used many method to set the Settings including implement the
apply_to_settings
trait, get theSettings
from a port and then modify it by using likeset_char_size
and then apply it byset_configuration
. And then I useget_configuration
to check it, but the settings do not change even I usedset_configuration
to modified it. I modify most of settings like baud rate, char size and stop bits..., but it ONLY works when I was modifying the baud rate. It do not throw an exception when I useset_configuration
.