A cross-platform serial port library in Rust. Provides a blocking I/O interface and port enumeration including USB device information.

Overview

crates.io version badge Documentation GitHub Workflow Status

Note: This is a fork of the original serialport-rs project on GitLab. Please note there have been some changes to both the supported targets and which Tier some targets are in, and there may be further changes to this made. Additionally, all relevant issues have been migrated to this repository.

Join the discussion on Matrix! #serialport-rs:matrix.org

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 and tokio-serial crates.

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 encourate 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, 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:

$ cargo build --no-default-features

Usage

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 a port is done when the SerialPort object is Droped 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.56.0 and higher are supported.

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 tests for all supported 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-gnu
    • 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.

Contributing

Please open an issue or merge request on GitLab to contibute. 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

Special thanks to dcuddeback, willem66745, and apoloval who wrote the original serial-rs library which this library heavily borrows from.

Additional thanks to susurrus and all other contributors to the original serialport-rs project on GitLab.

Comments
  • Update dev-dependecy clap to v4.0

    Update dev-dependecy clap to v4.0

    This PR updates clap dependency to its latest version (3.1.6 => 4.0).

    The clap update needed some changes in the code because of function deprecation in the clap v3.2.0 and clap v4.0.0 releases.

    This PR is a follow-up of https://github.com/serialport/serialport-rs/pull/72.

    MSRV

    Furthermore bump the MSRV to 1.60.0 as this is required by clap v4.0.0 (see https://github.com/clap-rs/clap/pull/4060). https://github.com/serialport/serialport-rs/commit/0a743546848cffd27da9851aea98980b18f05b95 reduced the MSRV because of a Yocto dependency. Currently following rust versions are used in the maintained yocto project versions:

    Therefore this MSRV change (1.46.0 => 1.60.0) will drop kirkstone support, which is the current LTS release, supported until April 2024 at least (according to https://wiki.yoctoproject.org/wiki/Releases).

    opened by g0hl1n 2
  • bufReader read_until not handled correctly on Windows

    bufReader read_until not handled correctly on Windows

    Using the following code:

     let mut reader = BufReader::new(connection);
     let mut my_str = vec![];
    
    if let Err(error) = reader.read_until(0xA, &mut my_str) {....}
    

    Where I am reading some data from a serial connection. On Linux & Mac I see the read_until function executing quite fast, but on Windows (11) I see the serial connection's timeout (500ms) is what is ending the read_until command -- Which does then proceed to do the correct thing after with the correct value in the buffer. It is just comparatively slow.

    An example of the output I am seeing:

    Successfully sent write to serial: CONFIG
    Successfully read from serial "0\n"
    Successfully sent write to serial: ILLUMDAY
    Successfully read from serial "10\n"
    Successfully sent write to serial: ILLUMNIGHT
    Successfully read from serial "25\n"
    Successfully sent write to serial: ILLUMMODE
    Successfully read from serial "0\n"
    Successfully sent write to serial: ECHO
    Successfully read from serial "0\n"
    Successfully sent write to serial: ANIM
    Successfully read from serial "0\n"
    

    Is this some kind of bug with Windows or am I missing something obvious? Thanks for any input!

    windows 
    opened by craigkai 4
  • Re-activate more build targets for CI jobs

    Re-activate more build targets for CI jobs

    • When migrating from GitLab to GitHub we've reduced the amount of build targets in error because we assumed that we could have only 20 of them
    • We recently learned that this is a limit for parallel builds
    • Let's reactivate at least popular ones (for example an OpenBSD build could have prevented #68)
    CI 
    opened by sirhcel 1
  • Enumate the serialport not correct in raspberry CM4

    Enumate the serialport not correct in raspberry CM4

    let ports = serialport::available_ports().expect("No ports found!"); for p in ports { println!("{}", p.port_name); }

    After run the code ,I got the serial port name. The port name is not correct. "/sys/class" is redundant. There are other serial port such as /dev/ttyAMA1 /dev/AMA2,but it does't enumerate all serial port actually. pi@raspberrypi:~ $ sudo ./rpidemo Blinking an LED on a Raspberry Pi Compute Module 4. /sys/class/tty/ttyUSB3 /sys/class/tty/ttyUSB1 /sys/class/tty/ttyUSB2 /sys/class/tty/ttyUSB0

    opened by zrz4066 0
  • BufRead::read_line() doesn't work when timeout is set to 0

    BufRead::read_line() doesn't work when timeout is set to 0

    Hello

    I have a code like this:

    let port = serialport::new(port_name, baud_rate)
        .timeout(Duration::from_millis(0)) // ----- NO TIMEOUT HERE
        .open()
        .expect("Error: ");
    
    let mut port = BufReader::new(port);
    let mut line_buffer = String::new();
    
    match port.read_line(&mut line_buffer) {
        Ok(size) => println!("{} bytes read -> {:?}", size, line_buffer),
        Err(e) => eprintln!("Error while reading: {:?}", e),
    }
    

    It will never receive a line. Change the timeout to any value and the line will be received (apparently, when the timeout expires).

    This behavior doesn't seem intuitive to me.

    opened by Bktero 0
Owner
Serialport
Providing serial port access for the open web.
Serialport
Code for connecting an RP2040 to a Bosch BNO055 IMU and having the realtime orientation data be sent to the host machine via serial USB

Code for connecting an RP2040 (via Raspberry Pi Pico) to a Bosch BNO055 IMU (via an Adafruit breakout board) and having the realtime orientation data be sent to the host machine via serial USB.

Gerald Nash 3 Nov 4, 2022
Create virtual serial ports, connect them to physical serial ports, and create routes between them all.

Virtual Serial Port Router (vsp-router) Create virtual serial ports, connect them to physical serial ports, and create routes between them all. vsp-ro

Rob Donnelly 3 Nov 24, 2022
esp-serial-dbg - debugging of esp-hal based applications via serial

esp-serial-dbg - debugging of esp-hal based applications via serial About This is still work in progress! At least the contained examples should work

Björn Quentin 3 Aug 23, 2022
Rust usb-device support for ATmega chips

atmega-usbd usb_device support for ATmega microcontrollers. NOTE: This is an experimental library, and certainly not production-ready. Expect bugs, an

Adam Gausmann 20 Jan 8, 2023
Log defmt messages over the serial port.

defmt-serial A defmt target for logging over a serial port. Messages can e.g. be read using socat and passed through defmt-print, see example-artemis

Gaute Hope 10 Oct 5, 2022
Fast, compact and all-around subdomain enumeration tool written in Rust

Fast, compact and all-around subdomain enumeration tool written in Rust, which uses dns bruteforce, internet search and recursive http content search.

foreseon 16 Dec 10, 2022
Fusion is a cross-platform App Dev ToolKit build on Rust . Fusion lets you create Beautiful and Fast apps for mobile and desktop platform.

Fusion is a cross-platform App Dev ToolKit build on Rust . Fusion lets you create Beautiful and Fast apps for mobile and desktop platform.

Fusion 1 Oct 19, 2021
Rust wrapping serial communication with ōRouter

orouter-serial (ōRouter serial protocol) This crate provides typed messages used for serial communication between host and oRouter. It also contains c

Overline Network 5 Dec 20, 2023
🖥 Simple Arduino Serial Monitor

Born out of the desire to connect to an Arduino without having to run the whole Arduino suite.

Robin Schroer 2 Mar 19, 2022
A Rust crate that provides a simple interface for LZMA compression and decompression.

rust-lzma Documentation This crate provides a simple interface to liblzma. LZMA is more commonly known as XZ or 7zip, (as in, files with the .xz or .7

null 52 Nov 26, 2022
This plugin provides an interface for storing unencrypted values on the application cache folder.

Tauri Plugin Store This plugin provides an interface for storing unencrypted values on the application cache folder. Architecture This repo shape migh

Tauri 128 Jan 1, 2023
Cross-platform Window library in Rust for Tauri. [WIP]

Cross-platform application window creation library in Rust that supports all major platforms like Windows, macOS, Linux, iOS and Android. Built for you, maintained for Tauri.

Tauri 899 Jan 1, 2023
Open-source NI maschine device handling

Open-source NI maschine device handling

william light 69 Dec 1, 2022
AVR device definitions

avrd AVR device definitons in Rust. Documentation This crate exposes information about different AVR microcontrollers so it can be used pragmatically.

The AVR-Rust project 32 Dec 28, 2022
Build and deploy cross platform bioinformatic utilities with Rust.

The Bioinformatics Toolkit RUST-backed utilities for bioinformatic data processing. Get started The fastest way to get started it to download the appl

null 5 Sep 8, 2023
Interface definitions for the Compute@Edge platform in witx.

?? compute-at-edge-abi This repository contains witx definitions for the Compute@Edge platform ABI. About witx The witx file format is an experimental

Fastly 14 Apr 5, 2022
A rewrite of Phonelink for Windows Forms written in Rust, with cross-platform support.

phonelink-rs A rewrite of Phonelink for Windows Forms written in Rust, with cross-platform support. Usage Clone the repository and build, or download

ahsan-a 4 Aug 6, 2022
Cross-platform bookmarks manager for your shell

shellmark: bookmark manager for shell THIS IS AN EARLY ALPHA. It works for me, but requires better UX and more polish. shellmark is a cross-platform b

Artem Pyanykh 25 Nov 10, 2022
A cross platform tool which instantly notifies about COVID vaccine availability.

?? CoWIN Notifier ?? A cross-platform tool written in rust, which instantly notifies users about COVID-19 vaccine availability at their regions. Curre

Sanskar Jaiswal 20 May 20, 2021