1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
[](https://crates.io/crates/serialport)
[](https://docs.rs/serialport)
[](https://github.com/serialport/serialport-rs/actions)
[](https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html)
# Introduction
`serialport-rs` is a general-purpose cross-platform serial port library for Rust. It provides a
blocking I/O interface and port enumeration on POSIX and Windows systems.
For async I/O functionality, see the [mio-serial](https://github.com/berkowski/mio-serial) and
[tokio-serial](https://github.com/berkowski/tokio-serial) crates.
Join the discussion on Matrix!
[#serialport-rs:matrix.org](https://matrix.to/#/#serialport-rs:matrix.org)
**This project is looking for maintainers! Especially for Windows. If you are interested please let
us know on Matrix, or by [creating a
discussion](https://github.com/serialport/serialport-rs/discussions/new).**
# Overview
The library exposes cross-platform serial port functionality through the `SerialPort` trait. This
library is structured to make this the simplest API to use to encourage cross-platform development
by default. Working with the resultant `Box<dyn SerialPort>` type is therefore recommended. To
expose 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` relies
on `libudev` (unless you disable the default `libudev` feature), an external dynamic library that
will need to be available on the system the final binary is running on. Enumeration will still be
available if this feature is disabled, but won't expose as much information and may return ports
that don't exist physically. However this dependency can be removed by disabling the default
`libudev` feature:
```shell
$ 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.
# Usage
## Listing Available Ports:
```rust
let ports = serialport::available_ports().expect("No ports found!");
for p in ports {
println!("{}", p.port_name);
}
```
## Opening and Configuring a Port
```rust
let port = serialport::new("/dev/ttyUSB0", 115_200)
.timeout(Duration::from_millis(10))
.open()
.expect("Failed to open port");
```
Some platforms expose additional functionality, which is opened using the `open_native()` method:
```rust
let port = serialport::new("/dev/ttyUSB0", 115_200)
.open_native()
.expect("Failed to open port");
```
There are devices which wait for DTR before sending any data. Configure
automatically setting DTR when opening a port by the builder:
```rust
let port = serialport::new("/dev/ttyUSB0", 115_200)
.dtr_on_open(true)
.open()
.expect("Failed to open port");
```
## Writing to a Port
```rust
let output = "This is a test. This is only a test.".as_bytes();
port.write(output).expect("Write failed!");
```
## Reading from a Port
The port operates in blocking mode with a default timeout of 0 ms.
```rust
let mut serial_buf: Vec<u8> = vec![0; 32];
port.read(serial_buf.as_mut_slice()).expect("Found no data!");
```
## Closing a Port
`serialport-rs` uses the Resource Acquisition Is Initialization (RAII) paradigm and so closing a
port is done when the `SerialPort` object is `Drop`ed either implicitly or explicitly using
`std::mem::drop` (`std::mem::drop(port)`).
# Examples
There are several included examples, which help demonstrate the functionality of this library and
can 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 connected
to 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 for
debugging.
# Dependencies
Rust versions 1.59.0 and higher are supported by the library itself. There are
examples 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`
# Platform Support
Builds and some tests (not requiring actual hardware) for major targets are run
in CI. Failures of either block the inclusion of new code. This library should
be compatible with additional targets not listed below, but no guarantees are
made. Additional platforms may be added in the future if there is a need and/or
demand.
- 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-msvc`
- `x86_64-pc-windows-gnu`
- `x86_64-pc-windows-msvc`
# Hardware Support
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 provided
with this library. It will test the driver to confirm that all possible settings are supported for a
port. Additionally, it will test that data transmission is correct for those settings if you have
two ports physically configured to communicate. If you experience problems with your devices, please
file 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. |
# Licensing
Licensed under the [Mozilla Public License, version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).
# Contributing
Please open an issue or pull request on GitHub to contribute. Code contributions submitted for
inclusion in the work by you, as defined in the MPL2.0 license, shall be licensed as the above
without any additional terms or conditions.
# Acknowledgments
This is the continuation of the development at <https://gitlab.com/susurrus/serialport-rs>. Thanks
to susurrus and all other contributors to the original project on GitLab.
Special thanks to dcuddeback, willem66745, and apoloval who wrote the original serial-rs library
which this library heavily borrows from.
|