mirror of
https://github.com/vsergeev/c-periphery.git
synced 2026-08-20 21:28:32 +08:00
serial: add support for termios timeout to serial_read()
see vsergeev/python-periphery#28, vsergeev/python-periphery#30.
This commit is contained in:
@@ -96,6 +96,8 @@ Read up to `len` number of bytes from the serial port into the `buf` buffer with
|
||||
|
||||
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](#return-value) on failure.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
struct serial_handle {
|
||||
int fd;
|
||||
bool use_termios_timeout;
|
||||
|
||||
struct {
|
||||
int c_errno;
|
||||
@@ -234,6 +235,8 @@ int serial_open_advanced(serial_t *serial, const char *path, uint32_t baudrate,
|
||||
return _serial_error(serial, SERIAL_ERROR_CONFIGURE, errsv, "Setting serial port attributes");
|
||||
}
|
||||
|
||||
serial->use_termios_timeout = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -261,6 +264,10 @@ int serial_read(serial_t *serial, uint8_t *buf, size_t len, int timeout_ms) {
|
||||
if ((ret = read(serial->fd, buf + bytes_read, len - bytes_read)) < 0)
|
||||
return _serial_error(serial, SERIAL_ERROR_IO, errno, "Reading serial port");
|
||||
|
||||
/* If we're using VMIN or VMIN+VTIME semantics for end of read, return now */
|
||||
if (serial->use_termios_timeout)
|
||||
return ret;
|
||||
|
||||
/* Empty read */
|
||||
if (ret == 0 && len != 0)
|
||||
return _serial_error(serial, SERIAL_ERROR_IO, 0, "Reading serial port: unexpected empty read");
|
||||
@@ -576,6 +583,8 @@ int serial_set_vmin(serial_t *serial, unsigned int vmin) {
|
||||
if (tcsetattr(serial->fd, TCSANOW, &termios_settings) < 0)
|
||||
return _serial_error(serial, SERIAL_ERROR_CONFIGURE, errno, "Setting serial port attributes");
|
||||
|
||||
serial->use_termios_timeout = vmin > 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user