distortos  v0.7.0
object-oriented C++ RTOS for microcontrollers
distortos::devices::SerialPort Class Reference

#include "distortos/devices/communication/SerialPort.hpp"

Inheritance diagram for distortos::devices::SerialPort:
[legend]
Collaboration diagram for distortos::devices::SerialPort:
[legend]

Classes

class  CircularBuffer
 Thread-safe, lock-free circular buffer for one-producer and one-consumer. More...
 

Public Member Functions

constexpr SerialPort (UartLowLevel &uart, void *const readBuffer, const size_t readBufferSize, void *const writeBuffer, const size_t writeBufferSize)
 SerialPort's constructor. More...
 
 ~SerialPort () override
 SerialPort's destructor. More...
 
int close ()
 Closes SerialPort. More...
 
int open (uint32_t baudRate, uint8_t characterLength, UartParity parity, bool _2StopBits)
 Opens SerialPort. More...
 
std::pair< int, size_t > read (void *buffer, size_t size, size_t minSize=1, const TickClock::time_point *timePoint=nullptr)
 Reads data from SerialPort. More...
 
std::pair< int, size_t > tryReadFor (const TickClock::duration duration, void *const buffer, const size_t size, const size_t minSize=1)
 Wrapper for read() with relative timeout. More...
 
template<typename Rep , typename Period >
std::pair< int, size_t > tryReadFor (const std::chrono::duration< Rep, Period > duration, void *const buffer, const size_t size, const size_t minSize=1)
 Wrapper for read() with relative timeout. More...
 
std::pair< int, size_t > tryReadUntil (const TickClock::time_point timePoint, void *const buffer, const size_t size, const size_t minSize=1)
 Wrapper for read() with absolute timeout. More...
 
template<typename Duration >
std::pair< int, size_t > tryReadUntil (const std::chrono::time_point< TickClock, Duration > timePoint, void *const buffer, const size_t size, const size_t minSize=1)
 Wrapper for read() with absolute timeout. More...
 
std::pair< int, size_t > tryWriteFor (const TickClock::duration duration, const void *const buffer, const size_t size, const size_t minSize=SIZE_MAX)
 Wrapper for write() with relative timeout. More...
 
template<typename Rep , typename Period >
std::pair< int, size_t > tryWriteFor (const std::chrono::duration< Rep, Period > duration, const void *const buffer, const size_t size, const size_t minSize=SIZE_MAX)
 Wrapper for write() with relative timeout. More...
 
std::pair< int, size_t > tryWriteUntil (const TickClock::time_point timePoint, const void *const buffer, const size_t size, const size_t minSize=SIZE_MAX)
 Wrapper for write() with absolute timeout. More...
 
template<typename Duration >
std::pair< int, size_t > tryWriteUntil (const std::chrono::time_point< TickClock, Duration > timePoint, const void *const buffer, const size_t size, const size_t minSize=SIZE_MAX)
 Wrapper for write() with absolute timeout. More...
 
std::pair< int, size_t > write (const void *buffer, size_t size, size_t minSize=SIZE_MAX, const TickClock::time_point *timePoint=nullptr)
 Writes data to SerialPort. More...
 

Protected Member Functions

void readCompleteEvent (size_t bytesRead) override
 "Read complete" event More...
 
void receiveErrorEvent (ErrorSet errorSet) override
 "Receive error" event More...
 
void transmitCompleteEvent () override
 "Transmit complete" event More...
 
void transmitStartEvent () override
 "Transmit start" event More...
 
void writeCompleteEvent (size_t bytesWritten) override
 "Write complete" event More...
 

Private Member Functions

int readFromCircularBufferAndStartRead (CircularBuffer &buffer)
 Reads data from circular buffer and calls startReadWrapper(). More...
 
int readImplementation (CircularBuffer &buffer, size_t minSize, const TickClock::time_point *timePoint)
 Implementation of basic read() functionality. More...
 
int startReadWrapper ()
 Wrapper for UartLowLevel::startRead() More...
 
int startWriteWrapper ()
 Wrapper for UartLowLevel::startWrite() More...
 
size_t stopReadWrapper ()
 Wrapper for UartLowLevel::stopRead() More...
 
size_t stopWriteWrapper ()
 Wrapper for UartLowLevel::stopWrite() More...
 
int writeImplementation (CircularBuffer &buffer, size_t minSize, const TickClock::time_point *timePoint)
 Implementation of basic write() functionality. More...
 
int writeToCircularBufferAndStartWrite (CircularBuffer &buffer)
 Writes data to circular buffer and calls startWriteWrapper(). More...
 
- Private Member Functions inherited from distortos::devices::UartBase
virtual ~UartBase ()=default
 UartBase's destructor. More...
 

Private Attributes

Mutex readMutex_
 mutex used to serialize access to read(), close() and open() More...
 
Mutex writeMutex_
 mutex used to serialize access to write(), close() and open() More...
 
CircularBuffer readBuffer_
 internal instance of circular buffer for read operations More...
 
CircularBuffer writeBuffer_
 internal instance of circular buffer for write operations More...
 
CircularBuffer *volatile currentReadBuffer_
 pointer to current circular buffer for read operations, always valid More...
 
CircularBuffer *volatile currentWriteBuffer_
 pointer to current circular buffer for write operations, always valid More...
 
CircularBuffer *volatile nextReadBuffer_
 pointer to next circular buffer for read operations, used when currentReadBuffer_ becomes full More...
 
CircularBuffer *volatile nextWriteBuffer_
 pointer to next circular buffer for write operations, used when currentWriteBuffer_ becomes empty More...
 
Semaphore *volatile readSemaphore_
 pointer to semaphore used for "read complete" event notifications More...
 
Semaphore *volatile transmitSemaphore_
 pointer to semaphore used for "transmit complete" event notifications More...
 
Semaphore *volatile writeSemaphore_
 pointer to semaphore used for "write complete" event notifications More...
 
volatile size_t readLimit_
 size limit of read operations, 0 if no limiting is needed, bytes More...
 
volatile size_t writeLimit_
 size limit of write operations, 0 if no limiting is needed, bytes More...
 
UartLowLeveluart_
 reference to low-level implementation of UartLowLevel interface More...
 
uint32_t baudRate_
 current baud rate, bps More...
 
uint8_t characterLength_
 current character length, bits More...
 
UartParity parity_
 current parity More...
 
bool _2StopBits_
 current configuration of stop bits: 1 (false) or 2 (true) More...
 
uint8_t openCount_
 number of times this device was opened but not yet closed More...
 
volatile bool readInProgress_
 "read in progress" flag More...
 
volatile bool transmitInProgress_
 "transmit in progress" flag More...
 
volatile bool writeInProgress_
 "write in progress" flag More...
 

Additional Inherited Members

- Private Types inherited from distortos::devices::UartBase
enum  ErrorBits {
  framingError, noiseError, overrunError, parityError,
  errorBitsMax
}
 indexes of error bits in ErrorSet More...
 
using ErrorSet = std::bitset< errorBitsMax >
 set of error bits More...
 

Detailed Description

SerialPort class is a serial port with an interface similar to standard files

Constructor & Destructor Documentation

◆ SerialPort()

constexpr distortos::devices::SerialPort::SerialPort ( UartLowLevel uart,
void *const  readBuffer,
const size_t  readBufferSize,
void *const  writeBuffer,
const size_t  writeBufferSize 
)
inline

SerialPort's constructor.

Parameters
[in]uartis a reference to low-level implementation of UartLowLevel interface
[in]readBufferis a buffer for read operations
[in]readBufferSizeis the size of readBuffer, bytes, should be even, must be greater than or equal to 2
[in]writeBufferis a buffer to write operations
[in]writeBufferSizeis the size of writeBuffer, bytes, should be even, must be greater than or equal to 2

◆ ~SerialPort()

distortos::devices::SerialPort::~SerialPort ( )
override

SerialPort's destructor.

Does nothing if all users already closed this device. If they did not, performs forced close of device.

Warning
This function must not be called from interrupt context!
Here is the call graph for this function:

Member Function Documentation

◆ close()

int distortos::devices::SerialPort::close ( )

Closes SerialPort.

Does nothing if any user still has this device opened. Otherwise all transfers and low-level driver are stopped. If any write transfer is still in progress, this function will wait for physical end of transmission before shutting the device down.

If the function is interrupted by a signal, the device is not closed - the user should try to close it again.

Warning
This function must not be called from interrupt context!
Returns
0 on success, error code otherwise:
  • EBADF - the device is already completely closed;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • error codes returned by UartLowLevel::stop();
Here is the call graph for this function:

◆ open()

int distortos::devices::SerialPort::open ( uint32_t  baudRate,
uint8_t  characterLength,
UartParity  parity,
bool  _2StopBits 
)

Opens SerialPort.

Does nothing if any user already has this device opened. Otherwise low-level driver and buffered reads are started.

Warning
This function must not be called from interrupt context!
Parameters
[in]baudRateis the desired baud rate, bps
[in]characterLengthselects character length, bits
[in]parityselects parity
[in]_2StopBitsselects whether 1 (false) or 2 (true) stop bits are used
Returns
0 on success, error code otherwise:
  • EINVAL - provided arguments don't match current configuration of already opened device;
  • EMFILE - this device is already opened too many times;
  • ENOBUFS - read and/or write buffers are too small;
  • error codes returned by UartLowLevel::start();
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:

◆ read()

std::pair< int, size_t > distortos::devices::SerialPort::read ( void *  buffer,
size_t  size,
size_t  minSize = 1,
const TickClock::time_point timePoint = nullptr 
)

Reads data from SerialPort.

Similar to POSIX read() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html#

This function will block until at least minSize bytes can be read (but no more than size). When minSize is equal to 1 (or 2 when character length is greater than 8 bits) - which is the default value - the behavior of this function is similar to POSIX read() with O_NONBLOCK flag cleared. If minSize is 0, then the function will not block at all and only read what is available in the buffer - in this case it is similar to POSIX read() with O_NONBLOCK flag set.

Warning
This function must not be called from interrupt context!
Parameters
[out]bufferis the buffer to which the data will be written
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of read, bytes, default - 1
[in]timePointis a pointer to the time point at which the wait will be terminated without reading minSize, nullptr to wait indefinitely, default - nullptr
Returns
pair with return code (0 on success, error code otherwise) and number of read bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be read without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ readCompleteEvent()

void distortos::devices::SerialPort::readCompleteEvent ( size_t  bytesRead)
overrideprotectedvirtual

"Read complete" event

Called by low-level UART driver when whole read buffer is filled.

  • updates position of read circular buffer;
  • changes current buffer to next one (if there is any next buffer and if current one is full);
  • updates size limit of read operations;
  • notifies any thread waiting for this event (if size limit of read operations reached 0);
  • clears "read in progress" flag;
  • starts next read operation if current read buffer is not full;
Parameters
[in]bytesReadis the number of bytes read by low-level UART driver (and written to read buffer)

Implements distortos::devices::UartBase.

Here is the call graph for this function:

◆ readFromCircularBufferAndStartRead()

int distortos::devices::SerialPort::readFromCircularBufferAndStartRead ( CircularBuffer buffer)
private

Reads data from circular buffer and calls startReadWrapper().

Parameters
[out]bufferis a reference to circular buffer to which the data will be written
Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

◆ readImplementation()

int distortos::devices::SerialPort::readImplementation ( CircularBuffer buffer,
size_t  minSize,
const TickClock::time_point timePoint 
)
private

Implementation of basic read() functionality.

Parameters
[out]bufferis a reference to circular buffer to which the data will be written
[in]minSizeis the minimum size of read, bytes
[in]timePointis a pointer to the time point at which the wait will be terminated without reading minSize, nullptr to wait indefinitely
Returns
0 on success, error code otherwise:
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ receiveErrorEvent()

void distortos::devices::SerialPort::receiveErrorEvent ( ErrorSet  errorSet)
overrideprotectedvirtual

"Receive error" event

Called by low-level UART driver when the last character was received with an error. This character is written to the read buffer before this function is called.

Does nothing.

Parameters
[in]errorSetis the set of error bits

Implements distortos::devices::UartBase.

◆ startReadWrapper()

int distortos::devices::SerialPort::startReadWrapper ( )
private

Wrapper for UartLowLevel::startRead()

Does nothing if read is already in progress or if read circular buffer is full. Otherwise sets "read in progress" flag, starts read operation with size that is the smallest of: size of first available write block, half the size of read circular buffer (only for internal buffer) and current size limit of read operations (only if it's not equal to 0).

Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

◆ startWriteWrapper()

int distortos::devices::SerialPort::startWriteWrapper ( )
private

Wrapper for UartLowLevel::startWrite()

Does nothing if write is already in progress or if write circular buffer is empty. Otherwise sets "write in progress" flag, starts write operation with size that is the smallest of: size of first available read block, half the size of write circular buffer (only for internal buffer) and current size limit of write operations (only if it's not equal to 0).

Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stopReadWrapper()

size_t distortos::devices::SerialPort::stopReadWrapper ( )
private

Wrapper for UartLowLevel::stopRead()

Stops read operation, updates position of read circular buffer, updates size limit of read operations and clears "read in progress" flag.

Returns
values returned by UartLowLevel::stopRead();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stopWriteWrapper()

size_t distortos::devices::SerialPort::stopWriteWrapper ( )
private

Wrapper for UartLowLevel::stopWrite()

Stops write operation, updates position of write circular buffer, updates size limit of write operations and clears "write in progress" flag.

Returns
values returned by UartLowLevel::stopWrite();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmitCompleteEvent()

void distortos::devices::SerialPort::transmitCompleteEvent ( )
overrideprotectedvirtual

"Transmit complete" event

Called by low-level UART driver when the transmission is physically finished.

Notifies any thread waiting for this event and clears "transmit in progress" flag.

Implements distortos::devices::UartBase.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmitStartEvent()

void distortos::devices::SerialPort::transmitStartEvent ( )
overrideprotectedvirtual

"Transmit start" event

Called by low-level UART driver when new transmission starts.

Sets "transmit in progress" flag.

Implements distortos::devices::UartBase.

Here is the caller graph for this function:

◆ tryReadFor() [1/2]

std::pair<int, size_t> distortos::devices::SerialPort::tryReadFor ( const TickClock::duration  duration,
void *const  buffer,
const size_t  size,
const size_t  minSize = 1 
)
inline

Wrapper for read() with relative timeout.

Warning
This function must not be called from interrupt context!
Parameters
[in]durationis the duration after which the wait will be terminated without reading minSize
[out]bufferis the buffer to which the data will be written
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of read, bytes, default - 1
Returns
pair with return code (0 on success, error code otherwise) and number of read bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be read without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tryReadFor() [2/2]

template<typename Rep , typename Period >
std::pair<int, size_t> distortos::devices::SerialPort::tryReadFor ( const std::chrono::duration< Rep, Period >  duration,
void *const  buffer,
const size_t  size,
const size_t  minSize = 1 
)
inline

Wrapper for read() with relative timeout.

Templated variant of tryReadFor(TickClock::duration, void*, size_t, size_t)

Warning
This function must not be called from interrupt context!
Template Parameters
Repis type of tick counter
Periodis std::ratio type representing the tick period of the clock, seconds
Parameters
[in]durationis the duration after which the wait will be terminated without reading minSize
[out]bufferis the buffer to which the data will be written
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of read, bytes, default - 1
Returns
pair with return code (0 on success, error code otherwise) and number of read bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be read without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:

◆ tryReadUntil() [1/2]

std::pair<int, size_t> distortos::devices::SerialPort::tryReadUntil ( const TickClock::time_point  timePoint,
void *const  buffer,
const size_t  size,
const size_t  minSize = 1 
)
inline

Wrapper for read() with absolute timeout.

Warning
This function must not be called from interrupt context!
Parameters
[in]timePointis the time point at which the wait will be terminated without reading minSize
[out]bufferis the buffer to which the data will be written
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of read, bytes, default - 1
Returns
pair with return code (0 on success, error code otherwise) and number of read bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be read without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tryReadUntil() [2/2]

template<typename Duration >
std::pair<int, size_t> distortos::devices::SerialPort::tryReadUntil ( const std::chrono::time_point< TickClock, Duration >  timePoint,
void *const  buffer,
const size_t  size,
const size_t  minSize = 1 
)
inline

Wrapper for read() with absolute timeout.

Template variant of tryReadUntil(TickClock::time_point, void*, size_t, size_t)

Warning
This function must not be called from interrupt context!
Template Parameters
Durationis a std::chrono::duration type used to measure duration
Parameters
[in]timePointis the time point at which the wait will be terminated without reading minSize
[out]bufferis the buffer to which the data will be written
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of read, bytes, default - 1
Returns
pair with return code (0 on success, error code otherwise) and number of read bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be read without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be read before the specified timeout expired;
  • error codes returned by UartLowLevel::startRead();
Here is the call graph for this function:

◆ tryWriteFor() [1/2]

std::pair<int, size_t> distortos::devices::SerialPort::tryWriteFor ( const TickClock::duration  duration,
const void *const  buffer,
const size_t  size,
const size_t  minSize = SIZE_MAX 
)
inline

Wrapper for write() with relative timeout.

Warning
This function must not be called from interrupt context!
Parameters
[in]durationis the duration after which the wait will be terminated without writing minSize
[in]bufferis the buffer with data that will be transmitted
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of write, bytes, default - SIZE_MAX
Returns
pair with return code (0 on success, error code otherwise) and number of written bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be written without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tryWriteFor() [2/2]

template<typename Rep , typename Period >
std::pair<int, size_t> distortos::devices::SerialPort::tryWriteFor ( const std::chrono::duration< Rep, Period >  duration,
const void *const  buffer,
const size_t  size,
const size_t  minSize = SIZE_MAX 
)
inline

Wrapper for write() with relative timeout.

Template variant of tryWriteFor(TickClock::duration, const void*, size_t, size_t)

Warning
This function must not be called from interrupt context!
Template Parameters
Repis type of tick counter
Periodis std::ratio type representing the tick period of the clock, seconds
Parameters
[in]durationis the duration after which the wait will be terminated without writing minSize
[in]bufferis the buffer with data that will be transmitted
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of write, bytes, default - SIZE_MAX
Returns
pair with return code (0 on success, error code otherwise) and number of written bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be written without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:

◆ tryWriteUntil() [1/2]

std::pair<int, size_t> distortos::devices::SerialPort::tryWriteUntil ( const TickClock::time_point  timePoint,
const void *const  buffer,
const size_t  size,
const size_t  minSize = SIZE_MAX 
)
inline

Wrapper for write() with absolute timeout.

Warning
This function must not be called from interrupt context!
Parameters
[in]timePointis the time point at which the wait will be terminated without writing minSize
[in]bufferis the buffer with data that will be transmitted
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of write, bytes, default - SIZE_MAX
Returns
pair with return code (0 on success, error code otherwise) and number of written bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be written without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tryWriteUntil() [2/2]

template<typename Duration >
std::pair<int, size_t> distortos::devices::SerialPort::tryWriteUntil ( const std::chrono::time_point< TickClock, Duration >  timePoint,
const void *const  buffer,
const size_t  size,
const size_t  minSize = SIZE_MAX 
)
inline

Wrapper for write() with absolute timeout.

Templated variant of tryWriteUntil(TickClock::time_point, const void*, size_t, size_t)

Warning
This function must not be called from interrupt context!
Parameters
[in]timePointis the time point at which the wait will be terminated without writing minSize
[in]bufferis the buffer with data that will be transmitted
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of write, bytes, default - SIZE_MAX
Returns
pair with return code (0 on success, error code otherwise) and number of written bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be written without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:

◆ write()

std::pair< int, size_t > distortos::devices::SerialPort::write ( const void *  buffer,
size_t  size,
size_t  minSize = SIZE_MAX,
const TickClock::time_point timePoint = nullptr 
)

Writes data to SerialPort.

Similar to POSIX write() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html#

This function will block until at least minSize bytes can be written (but no more than size). When minSize is greater than or equal to size - for example SIZE_MAX, which is the default value - the behavior of this function is similar to POSIX write() with O_NONBLOCK flag cleared. If minSize is 0, then the function will not block at all and only writes up to buffer's available free space - in this case it is similar to POSIX write() with O_NONBLOCK flag set.

Warning
This function must not be called from interrupt context!
Parameters
[in]bufferis the buffer with data that will be transmitted
[in]sizeis the size of buffer, bytes, must be even if selected character length is greater than 8 bits
[in]minSizeis the minimum size of write, bytes, default - SIZE_MAX
[in]timePointis a pointer to the time point at which the wait will be terminated without writing minSize, nullptr to wait indefinitely, default - nullptr
Returns
pair with return code (0 on success, error code otherwise) and number of written bytes (valid even when error code is returned); error codes:
  • EAGAIN - no data can be written without blocking and non-blocking operation was requested (minSize is 0);
  • EBADF - the device is not opened;
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • EINVAL - buffer and/or size are invalid;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeCompleteEvent()

void distortos::devices::SerialPort::writeCompleteEvent ( size_t  bytesWritten)
overrideprotectedvirtual

"Write complete" event

Called by low-level UART driver when whole write buffer was transferred - the transmission may still be in progress.

  • updates position of write circular buffer;
  • changes current buffer to next one (if there is any next buffer and if current one is empty);
  • updates size limit of write operations;
  • clears "write in progress" flag;
  • notifies any thread waiting for this event (if size limit of write operations reached 0);
  • starts next write operation if current write buffer is not empty;
Parameters
[in]bytesWrittenis the number of bytes written by low-level UART driver (and read from write buffer)

Implements distortos::devices::UartBase.

Here is the call graph for this function:

◆ writeImplementation()

int distortos::devices::SerialPort::writeImplementation ( CircularBuffer buffer,
size_t  minSize,
const TickClock::time_point timePoint 
)
private

Implementation of basic write() functionality.

Parameters
[in]bufferis a reference to circular buffer from which the data will be read
[in]minSizeis the minimum size of write, bytes
[in]timePointis a pointer to the time point at which the wait will be terminated without writing minSize, nullptr to wait indefinitely
Returns
0 on success, error code otherwise:
  • EINTR - the wait was interrupted by an unmasked, caught signal;
  • ETIMEDOUT - required amount of data could not be written before the specified timeout expired;
  • error codes returned by UartLowLevel::startWrite();
Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeToCircularBufferAndStartWrite()

int distortos::devices::SerialPort::writeToCircularBufferAndStartWrite ( CircularBuffer buffer)
private

Writes data to circular buffer and calls startWriteWrapper().

Parameters
[in]bufferis a reference to circular buffer from which the data will be read
Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ _2StopBits_

bool distortos::devices::SerialPort::_2StopBits_
private

current configuration of stop bits: 1 (false) or 2 (true)

◆ baudRate_

uint32_t distortos::devices::SerialPort::baudRate_
private

current baud rate, bps

◆ characterLength_

uint8_t distortos::devices::SerialPort::characterLength_
private

current character length, bits

◆ currentReadBuffer_

CircularBuffer* volatile distortos::devices::SerialPort::currentReadBuffer_
private

pointer to current circular buffer for read operations, always valid

◆ currentWriteBuffer_

CircularBuffer* volatile distortos::devices::SerialPort::currentWriteBuffer_
private

pointer to current circular buffer for write operations, always valid

◆ nextReadBuffer_

CircularBuffer* volatile distortos::devices::SerialPort::nextReadBuffer_
private

pointer to next circular buffer for read operations, used when currentReadBuffer_ becomes full

◆ nextWriteBuffer_

CircularBuffer* volatile distortos::devices::SerialPort::nextWriteBuffer_
private

pointer to next circular buffer for write operations, used when currentWriteBuffer_ becomes empty

◆ openCount_

uint8_t distortos::devices::SerialPort::openCount_
private

number of times this device was opened but not yet closed

◆ parity_

UartParity distortos::devices::SerialPort::parity_
private

current parity

◆ readBuffer_

CircularBuffer distortos::devices::SerialPort::readBuffer_
private

internal instance of circular buffer for read operations

◆ readInProgress_

volatile bool distortos::devices::SerialPort::readInProgress_
private

"read in progress" flag

◆ readLimit_

volatile size_t distortos::devices::SerialPort::readLimit_
private

size limit of read operations, 0 if no limiting is needed, bytes

◆ readMutex_

Mutex distortos::devices::SerialPort::readMutex_
private

mutex used to serialize access to read(), close() and open()

◆ readSemaphore_

Semaphore* volatile distortos::devices::SerialPort::readSemaphore_
private

pointer to semaphore used for "read complete" event notifications

◆ transmitInProgress_

volatile bool distortos::devices::SerialPort::transmitInProgress_
private

"transmit in progress" flag

◆ transmitSemaphore_

Semaphore* volatile distortos::devices::SerialPort::transmitSemaphore_
private

pointer to semaphore used for "transmit complete" event notifications

◆ uart_

UartLowLevel& distortos::devices::SerialPort::uart_
private

reference to low-level implementation of UartLowLevel interface

◆ writeBuffer_

CircularBuffer distortos::devices::SerialPort::writeBuffer_
private

internal instance of circular buffer for write operations

◆ writeInProgress_

volatile bool distortos::devices::SerialPort::writeInProgress_
private

"write in progress" flag

◆ writeLimit_

volatile size_t distortos::devices::SerialPort::writeLimit_
private

size limit of write operations, 0 if no limiting is needed, bytes

◆ writeMutex_

Mutex distortos::devices::SerialPort::writeMutex_
private

mutex used to serialize access to write(), close() and open()

◆ writeSemaphore_

Semaphore* volatile distortos::devices::SerialPort::writeSemaphore_
private

pointer to semaphore used for "write complete" event notifications


The documentation for this class was generated from the following files: