serialport-rs
is a general-purpose cross-platform serial port library for Rust. It provides ablocking I/O interface and port enumeration on POSIX and Windows systems.
For async I/O functionality, see the mio-serial andtokio-serial crates.
Join the discussion on Matrix!#serialport-rs:matrix.org
This project is looking for maintainers! Especially for Windows. If you are interested please letus know on Matrix, or by creating adiscussion.
The library exposes cross-platform serial port functionality through the SerialPort
trait. Thislibrary is structured to make this the simplest API to use to encourage cross-platform developmentby default. Working with the resultant Box<dyn SerialPort>
type is therefore recommended. Toexpose additional platform-specific functionality use the platform-specific structs directly:TTYPort
for POSIX systems and COMPort
for Windows.
Serial enumeration is provided on most platforms. The implementation on Linux using glibc
relieson libudev
, an external dynamic library that will need to be available on the system the finalbinary is running on. Enumeration will still be available if this feature is disabled, but won'texpose as much information and may return ports that don't exist physically. However this dependencycan be removed by disabling the default libudev
feature:
$ cargo build --no-default-features
It should also be noted that on macOS, both the Callout (/dev/cu.*
) and Dial-in ports(/dev/tty.*
) ports are enumerated, resulting in two available ports per connected serial device.
Listing available ports:
let ports = serialport::available_ports().expect("No ports found!");for p in ports { println!("{}", p.port_name);}
Opening and configuring a port:
let port = serialport::new("/dev/ttyUSB0", 115_200) .timeout(Duration::from_millis(10)) .open().expect("Failed to open port");
Writing to a port:
let output = "This is a test. This is only a test.".as_bytes();port.write(output).expect("Write failed!");
Reading from a port (default is blocking with a 0ms timeout):
let mut serial_buf: Vec<u8> = vec![0; 32];port.read(serial_buf.as_mut_slice()).expect("Found no data!");
Some platforms expose additional functionality, which is opened using the open_native()
method:
let port = serialport::new("/dev/ttyUSB0", 115_200) .open_native().expect("Failed to open port");
Closing a port:
serialport-rs
uses the Resource Acquisition Is Initialization (RAII) paradigm and so closing aport is done when the SerialPort
object is Drop
ed either implicitly or explicitly usingstd::mem::drop
(std::mem::drop(port)
).
There are several included examples, which help demonstrate the functionality of this library andcan help debug software or hardware errors.
- clear_input_buffer - Demonstrates querying and clearing the driver input buffer.
- clear_output_buffer - Demonstrates querying and clearing the driver output buffer.
- duplex - Tests that a port can be successfully cloned.
- hardware_check - Checks port/driver functionality for a single port or a pair of ports connectedto each other.
- list_ports - Lists available serial ports.
- pseudo_terminal - Unix only. Tests that a pseudo-terminal pair can be created.
- receive_data - Output data received on a port.
- transmit - Transmits data regularly on a port with various port configurations. Useful fordebugging.
Rust versions 1.59.0 and higher are supported by the library itself. There areexamples requiring newer versions of Rust.
For GNU/Linux pkg-config
headers are required:
- Ubuntu:
sudo apt install pkg-config
- Fedora:
sudo dnf install pkgconf-pkg-config
For other distros they may provide pkg-config
through the pkgconf
package instead.
For GNU/Linux libudev
headers are required as well (unless you disable the default libudev
feature):
- Ubuntu:
sudo apt install libudev-dev
- Fedora:
sudo dnf install systemd-devel
Builds and tests for all supported targets are run in CI. Failures of either block the inclusion ofnew code. This library should be compatible with additional targets not listed below, but noguarantees are made. Additional platforms may be added in the future if there is a need and/ordemand.
- Android
arm-linux-androideabi
(no serial enumeration)armv7-linux-androideabi
(no serial enumeration)
- FreeBSD
x86_64-unknown-freebsd
- Linux
aarch64-unknown-linux-gnu
aarch64-unknown-linux-musl
i686-unknown-linux-gnu
i686-unknown-linux-musl
x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl
- macOS/iOS
aarch64-apple-darwin
aarch64-apple-ios
x86_64-apple-darwin
- NetBSD
x86_64-unknown-netbsd
(no serial enumeration)
- Windows
i686-pc-windows-gnu
i686-pc-windows-msvc
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
This library has been developed to support all serial port devices across all supported platforms.To determine how well your platform is supported, please run the hardware_check
example providedwith this library. It will test the driver to confirm that all possible settings are supported for aport. Additionally, it will test that data transmission is correct for those settings if you havetwo ports physically configured to communicate. If you experience problems with your devices, pleasefile a bug and identify the hardware, OS, and driver in use.
Known issues:
Hardware | OS | Driver | Issues |
---|---|---|---|
FTDI TTL-232R | Linux | ftdi_sio, Linux 4.14.11 | Hardware doesn't support 5 or 6 data bits, but the driver lies about supporting 5. |
Licensed under the Mozilla Public License, version 2.0.
Please open an issue or pull request on GitHub to contribute. Code contributions submitted forinclusion in the work by you, as defined in the MPL2.0 license, shall be licensed as the abovewithout any additional terms or conditions.
This is the continuation of the development at https://gitlab.com/susurrus/serialport-rs. Thanksto susurrus and all other contributors to the original project on GitLab.
Special thanks to dcuddeback, willem66745, and apoloval who wrote the original serial-rs librarywhich this library heavily borrows from.