Skip to content

Latest commit

 

History

History
326 lines (228 loc) · 12.2 KB

serial.md

File metadata and controls

326 lines (228 loc) · 12.2 KB

NAME

Serial wrapper functions for Linux userspace termios tty devices.

SYNOPSIS

#include <periphery/serial.h>

/* Primary Functions */
serial_t *serial_new(void);
int serial_open(serial_t *serial, const char *path, uint32_t baudrate);
int serial_open_advanced(serial_t *serial, const char *path, uint32_t baudrate,
                         unsigned int databits, serial_parity_t parity,
                         unsigned int stopbits, bool xonxoff, bool rtscts);
int serial_read(serial_t *serial, uint8_t *buf, size_t len, int timeout_ms);
int serial_write(serial_t *serial, const uint8_t *buf, size_t len);
int serial_flush(serial_t *serial);
int serial_input_waiting(serial_t *serial, unsigned int *count);
int serial_output_waiting(serial_t *serial, unsigned int *count);
int serial_poll(serial_t *serial, int timeout_ms);
int serial_close(serial_t *serial);
void serial_free(serial_t *serial);

/* Getters */
int serial_get_baudrate(serial_t *serial, uint32_t *baudrate);
int serial_get_databits(serial_t *serial, unsigned int *databits);
int serial_get_parity(serial_t *serial, serial_parity_t *parity);
int serial_get_stopbits(serial_t *serial, unsigned int *stopbits);
int serial_get_xonxoff(serial_t *serial, bool *xonxoff);
int serial_get_rtscts(serial_t *serial, bool *rtscts);

/* Setters */
int serial_set_baudrate(serial_t *serial, uint32_t baudrate);
int serial_set_databits(serial_t *serial, unsigned int databits);
int serial_set_parity(serial_t *serial, enum serial_parity parity);
int serial_set_stopbits(serial_t *serial, unsigned int stopbits);
int serial_set_xonxoff(serial_t *serial, bool enabled);
int serial_set_rtscts(serial_t *serial, bool enabled);

/* Miscellaneous */
int serial_fd(serial_t *serial);
int serial_tostring(serial_t *serial, char *str, size_t len);

/* Error Handling */
int serial_errno(serial_t *serial);
const char *serial_errmsg(serial_t *serial);

ENUMERATIONS

  • serial_parity_t
    • PARITY_NONE: No parity
    • PARITY_ODD: Odd parity
    • PARITY_EVEN: Even parity

DESCRIPTION

serial_t *serial_new(void);

Allocate a Serial handle.

Returns a valid handle on success, or NULL on failure.


int serial_open(serial_t *serial, const char *path, uint32_t baudrate);

Open the tty device at the specified path (e.g. "/dev/ttyUSB0"), with the specified baudrate, and the defaults of 8 data bits, no parity, 1 stop bit, software flow control (xonxoff) off, hardware flow control (rtscts) off.

serial should be a valid pointer to an allocated Serial handle structure.

Returns 0 on success, or a negative Serial error code on failure.


int serial_open_advanced(serial_t *serial, const char *path, uint32_t baudrate,
                         unsigned int databits, serial_parity_t parity,
                         unsigned int stopbits, bool xonxoff, bool rtscts);

Open the tty device at the specified path (e.g. "/dev/ttyUSB0"), with the specified baudrate, data bits, parity, stop bits, software flow control (xonxoff), and hardware flow control (rtscts) settings.

serial should be a valid pointer to an allocated Serial handle structure. databits can be 5, 6, 7, or 8. parity can be PARITY_NONE, PARITY_ODD, or PARITY_EVEN as defined above. stopbits can be 1 or 2.

Returns 0 on success, or a negative Serial error code on failure.


int serial_read(serial_t *serial, uint8_t *buf, size_t len, int timeout_ms);

Read up to len number of bytes from the serial port into the buf buffer with the specified millisecond timeout. timeout_ms can be positive for a blocking read with a timeout in milliseconds, zero for a non-blocking read, or negative for a blocking read that will block until length number of bytes are read.

For a non-blocking or timeout-bound read, serial_read() may return less than the requested number of bytes.

For a blocking read with the VMIN setting configured, serial_read() will block until at least VMIN bytes are read. For a blocking read with both VMIN and VTIME settings configured, serial_read() will block until at least VMIN bytes are read or the VTIME interbyte timeout expires after the last byte read. In either case, serial_read() may return less than the requested number of bytes.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced(). timeout_ms can be positive for a blocking read with a timeout in milliseconds, zero for a non-blocking read, or negative for a blocking read.

Returns the number of bytes read on success, 0 on timeout, or a negative Serial error code on failure.


int serial_write(serial_t *serial, const uint8_t *buf, size_t len);

Write len number of bytes from the buf buffer to the serial port.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns the number of bytes written on success, or a negative Serial error code on failure.


int serial_flush(serial_t *serial);

Flush the write buffer of the serial port (i.e. force its write immediately).

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


int serial_input_waiting(serial_t *serial, unsigned int *count);

Get the number of bytes waiting to be read from the serial port.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


int serial_output_waiting(serial_t *serial, unsigned int *count);

Get the number of bytes waiting to be written to the serial port.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


bool serial_poll(serial_t *serial, int timeout_ms);

Poll for data available for reading from the serial port.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced(). timeout_ms can be positive for a timeout in milliseconds, zero for a non-blocking poll, or negative for a blocking poll.

Returns 1 on success (data available for reading), 0 on timeout, or a negative Serial error code on failure.


int serial_close(serial_t *serial);

Close the tty device.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


void serial_free(serial_t *serial);

Free a Serial handle.


int serial_get_baudrate(serial_t *serial, uint32_t *baudrate);
int serial_get_databits(serial_t *serial, unsigned int *databits);
int serial_get_parity(serial_t *serial, serial_parity_t *parity);
int serial_get_stopbits(serial_t *serial, unsigned int *stopbits);
int serial_get_xonxoff(serial_t *serial, bool *xonxoff);
int serial_get_rtscts(serial_t *serial, bool *rtscts);

Get the baudrate, data bits, parity, stop bits, software flow control (xonxoff), or hardware flow control (rtscts), respectively, of the underlying tty device.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


int serial_set_baudrate(serial_t *serial, uint32_t baudrate);
int serial_set_databits(serial_t *serial, unsigned int databits);
int serial_set_parity(serial_t *serial, enum serial_parity parity);
int serial_set_stopbits(serial_t *serial, unsigned int stopbits);
int serial_set_xonxoff(serial_t *serial, bool enabled);
int serial_set_rtscts(serial_t *serial, bool enabled);

Set the baudrate, data bits, parity, stop bits, software flow control (xonxoff), or hardware flow control (rtscts), respectively, on the underlying tty device.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

Returns 0 on success, or a negative Serial error code on failure.


int serial_get_vmin(serial_t *serial, unsigned int *vmin);
int serial_get_vtime(serial_t *serial, float *vtime);
int serial_set_vmin(serial_t *serial, unsigned int vmin);
int serial_set_vtime(serial_t *serial, float vtime);

Get or set the termios VMIN and VTIME settings, respectively, of the underlying tty device.

VMIN specifies the minimum number of bytes returned from a blocking read. VTIME specifies the timeout in seconds of a blocking read.

When both VMIN and VTIME settings are configured, VTIME acts as an interbyte timeout that restarts on every byte received, and a blocking read will block until either VMIN bytes are read or the VTIME timeout expires after the last byte read. See the termios man page for more information.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced(). vmin can be between 0 and 255. vtime can be between 0 and 25.5 seconds, with a resolution of 0.1 seconds.

Returns 1 on success, or a negative Serial error code on failure.


int serial_fd(serial_t *serial);

Return the file descriptor (for the underlying tty device) of the Serial handle.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

This function is a simple accessor to the Serial handle structure and always succeeds.


int serial_tostring(serial_t *serial, char *str, size_t len);

Return a string representation of the Serial handle.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

This function behaves and returns like snprintf().


int serial_errno(serial_t *serial);

Return the libc errno of the last failure that occurred.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().


const char *serial_errmsg(serial_t *serial);

Return a human readable error message of the last failure that occurred.

serial should be a valid pointer to a Serial handle opened with serial_open() or serial_open_advanced().

RETURN VALUE

The periphery Serial functions return 0 on success or one of the negative error codes below on failure.

The libc errno of the failure in an underlying libc library call can be obtained with the serial_errno() helper function. A human readable error message can be obtained with the serial_errmsg() helper function.

Error Code Description
SERIAL_ERROR_ARG Invalid arguments
SERIAL_ERROR_OPEN Opening serial port
SERIAL_ERROR_QUERY Querying serial port attributes
SERIAL_ERROR_CONFIGURE Configuring serial port attributes
SERIAL_ERROR_IO Reading/writing serial port
SERIAL_ERROR_CLOSE Closing serial port

EXAMPLE

#include <stdio.h>
#include <stdlib.h>

#include "serial.h"

int main(void) {
    serial_t *serial;
    const char *s = "Hello World!";
    char buf[128];
    int ret;

    serial = serial_new();

    /* Open /dev/ttyUSB0 with baudrate 115200, and defaults of 8N1, no flow control */
    if (serial_open(serial, "/dev/ttyUSB0", 115200) < 0) {
        fprintf(stderr, "serial_open(): %s\n", serial_errmsg(serial));
        exit(1);
    }

    /* Write to the serial port */
    if (serial_write(serial, s, strlen(s)) < 0) {
        fprintf(stderr, "serial_write(): %s\n", serial_errmsg(serial));
        exit(1);
    }

    /* Read up to buf size or 2000ms timeout */
    if ((ret = serial_read(serial, buf, sizeof(buf), 2000)) < 0) {
        fprintf(stderr, "serial_read(): %s\n", serial_errmsg(serial));
        exit(1);
    }

    printf("read %d bytes: _%s_\n", ret, buf);

    serial_close(serial);

    serial_free(serial);

    return 0;
}