Serial#
Hardware Interface#
Defined in namespace hal
#include <libhal/serial.hpp>
-
class serial#
Hardware abstract interface for the serial communication protocol.
Use this interface for hardware that implements a serial protocol like UART, RS232, RS485 and others that use a similar communication protocol but may use different voltage schemes.
This interface only works 8-bit serial data frames.
Due to the asynchronous and unformatted nature of serial communication protocols, all implementations of serial devices must be buffered. Buffered, in this case, is defined as automatic storage of received bytes without direct application intervention.
All implementations MUST allow the user to supply their own buffer of arbitrary size up to the limits of what hardware can support. This allows a developer the ability to tailored the buffer size to the needs of the application.
Examples of buffering schemes are:
Using DMA to copy data from a serial peripheral to a region of memory
Using interrupts when a serial peripheralβs queue has filled to a point
Subclassed by hal::soft::inert_serial
Public Functions
-
inline void configure(const settings &p_settings)#
Configure serial to match the settings supplied.
Implementing drivers must verify if the settings can be applied to hardware before modifying the hardware. This will ensure that if this operation fails, the state of the serial device has not changed.
- Parameters:
p_settings β - settings to apply to serial driver
- Throws:
hal::operation_not_supported β - if the settings could not be achieved.
-
inline write_t write(std::span<const hal::byte> p_data)#
Write data to the transmitter line of the serial port.
- Parameters:
p_data β - data to be transmitted over the serial port
- Returns:
write_t - serial write response
-
inline read_t read(std::span<hal::byte> p_data)#
Copy bytes from working buffer into passed buffer.
This operation copies the bytes from the serial driverβs internal working buffer to the buffer supplied.
The buffer will be filled up either to the end of the buffer or until there are no more bytes left in the working buffer. The remaining portion of the input buffer is returned in
read_t::remaining
.If a frame error has occurred at any point during serial reception, this function will throw a
hal::io_error
value. The contents of the internal working buffer will stay the same. No information from the internal working buffer will be copied into the supplied buffer and no data will be removed from the internal working buffer. The frame error status will be internally cleared after its occurrence. Subsequent calls of this function will read out the contents of the buffer although the data inside may be corrupt.When an hal::io_error occurs the options available are to flush the buffer and attempt reception again or read out the potentially corrupted data and parse it as needed. The choice of operation is application/driver specific.
-
inline void flush()#
Flush working buffer.
The behavior of flushing the internal working buffer is this:
Sets the serial portβs internal working buffer to an βemptyβ state.
Clear any received data stored in hardware registers.
Use the fastest available option to perform these operations, meaning that the contents of the internal working buffer will not be zeroed out.
-
struct read_t#
Return type for serial read operations.
Public Members
-
std::span<hal::byte> data#
The filled portion of the input buffer from the serial port.
The size of this buffer indicates the number of bytes read The address points to the start of the buffer passed into the read() function.
-
size_t available#
Number of enqueued and available to be read out bytes.
This value can be equal to or exceed the value of capacity. In this situation, the number of bytes above the capacity are bytes that have been dropped. Not all drivers will indicate the number of bytes lost. It is up to the driver or application to decide what to do in this situation.
-
size_t capacity#
The maximum number of bytes that the serial port can queue up.
-
std::span<hal::byte> data#
-
struct settings#
Generic settings for a standard serial device.
Public Types
-
enum class stop_bits : uint8_t#
Set of available stop bits options.
Values:
-
enumerator one#
-
enumerator two#
-
enumerator one#
-
enum class parity : uint8_t#
Set of parity bit options.
Values:
-
enumerator none#
Disable parity bit as part of the frame.
-
enumerator odd#
Enable parity and set 1 (HIGH) when the number of bits is odd.
-
enumerator even#
Enable parity and set 1 (HIGH) when the number of bits is even.
-
enumerator forced1#
Enable parity bit and always return 1 (HIGH) for ever frame.
-
enumerator forced0#
Enable parity bit and always return 0 (LOW) for ever frame.
-
enumerator none#
-
enum class stop_bits : uint8_t#
-
struct write_t#
Return type for serial write operations.
Utilities#
Defined in namespace hal
#include <libhal-util/serial.hpp>
- group Serial
Functions
-
constexpr auto operator==(const serial::settings &p_lhs, const serial::settings &p_rhs)#
Compares two serial objects via their settings.
- Parameters:
p_lhs β A serial object
p_rhs β A serial object
- Returns:
A boolean if they are the same or not.
-
inline serial::write_t write_partial(serial &p_serial, std::span<const hal::byte> p_data_out)#
Write bytes to a serial port.
- Parameters:
p_serial β - the serial port that will be written to
p_data_out β - the data to be written out the port
- Returns:
serial::write_t - information about the write_t operation.
-
inline void write(serial &p_serial, std::span<const hal::byte> p_data_out, timeout auto p_timeout)#
Write bytes to a serial port.
Unlike write_partial, this function will attempt to write bytes to the serial port until the timeout time has expired.
- Parameters:
p_serial β - the serial port that will be written to
p_data_out β - the data to be written out the port
p_timeout β - timeout callable that throws a std::errc::timed_out exception when the timeout expires.
- Throws:
std::errc::timed_out β - if p_timeout expires
-
inline void write(serial &p_serial, std::string_view p_data_out, timeout auto p_timeout)#
Write std::span of const char to a serial port.
- Parameters:
p_serial β - the serial port that will be written to
p_data_out β - chars to be written out the port
p_timeout β - timeout callable that throws a std::errc::timed_out exception when the timeout expires.
- Throws:
std::errc::timed_out β - if p_timeout expires
-
inline void read(serial &p_serial, std::span<hal::byte> p_data_in, timeout auto p_timeout)#
Read bytes from a serial port.
- Parameters:
p_serial β - the serial port that will be read from
p_data_in β - buffer to have bytes from the serial port read into. When this function completes, the full contents of p_data_in should contain
p_timeout β - timeout callable that throws a std::errc::timed_out exception when the timeout expires.
- Throws:
std::errc::timed_out β - if p_timeout expires
-
template<size_t bytes_to_read>
std::array<hal::byte, bytes_to_read> read(serial &p_serial, timeout auto p_timeout)# Read bytes from a serial port and return an array.
This call eliminates the boiler plate of creating an array and then passing that to the read function.
- Template Parameters:
bytes_to_read β - the number of bytes to be read from the serial port.
- Parameters:
p_serial β - the serial port to be read from
p_timeout β - timeout callable that throws a std::errc::timed_out exception when the timeout expires.
- Throws:
std::errc::timed_out β - if p_timeout expires
- Returns:
std::array<hal::byte, bytes_to_read> - array containing the bytes read from the serial port.
-
inline void write_then_read(serial &p_serial, std::span<const hal::byte> p_data_out, std::span<hal::byte> p_data_in, timeout auto p_timeout)#
Perform a write then read transaction over serial.
This is especially useful for devices that use a command and response method of communication.
- Parameters:
p_serial β - the serial port to have the transaction occur on
p_data_out β - the data to be written to the port
p_data_in β - a buffer to receive the bytes back from the port
p_timeout β - timeout callable that throws a std::errc::timed_out exception when the timeout expires.
- Throws:
std::errc::timed_out β - if p_timeout expires
-
template<size_t bytes_to_read>
std::array<hal::byte, bytes_to_read> write_then_read(serial &p_serial, std::span<const hal::byte> p_data_out, timeout auto p_timeout)# Perform a write then read transaction over serial.
This is especially useful for devices that use a command and response method of communication.
- Template Parameters:
bytes_to_read β - the number of bytes to read back
- Parameters:
p_serial β - the serial port to have the transaction occur on
p_data_out β - the data to be written to the port
p_timeout β - timeout callable that indicates when to bail out of the read operation.
- Throws:
std::errc::timed_out β - if p_timeout expires
- Returns:
std::array<hal::byte, bytes_to_read> - array containing the bytes read from the serial port.
-
template<typename byte_array_t>
void print(serial &p_serial, byte_array_t &&p_data)# Write data to serial buffer and drop return value.
Only use this with serial ports with infallible write operations, meaning they will never return an error result.
- Template Parameters:
byte_array_t β - data array type
- Parameters:
p_serial β - serial port to write data to
p_data β - data to be sent over the serial port
-
template<size_t buffer_size, typename ...Parameters>
void print(serial &p_serial, const char *p_format, Parameters... p_parameters)# Write formatted string data to serial buffer and drop return value.
Uses snprintf internally and writes to a local statically allocated an array. This function will never dynamically allocate like how standard std::printf does.
This function does NOT include the NULL character when transmitting the data over the serial port.
- Template Parameters:
buffer_size β - Size of the buffer to allocate on the stack to store the formatted message.
Parameters β - printf arguments
- Parameters:
p_serial β - serial port to write data to
p_format β - printf style null terminated format string
p_parameters β - printf arguments
-
constexpr auto operator==(const serial::settings &p_lhs, const serial::settings &p_rhs)#
Coroutines#
#include <libhal-util/serial_coroutines.hpp>
- group SerialCoroutines
A collection of functions and other utilities used for asynchronous coroutines with serial communication.
Functions
-
inline skip_past(serial &p_serial, std::span<const hal::byte> p_sequence, size_t p_read_limit = 32)#
Construct a new skip beyond object.
- Parameters:
p_serial β - serial port to skip through
p_sequence β - sequence to search for. The lifetime of this data pointed to by this span must outlive this object, or not be used when the lifetime of that data is no longer available.
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline result<work_state> operator()()#
skip data from the serial port until the sequence is reached.
This function will return if the sequence is found or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
result<work_state> - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
result<work_state> - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline read_into(serial &p_serial, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
Construct a new read_into object.
- Parameters:
p_serial β - serial port to skip through
p_buffer β - buffer to read data into
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()
read data into the buffer.
This function will return if the read limit is reached or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
work_state - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline read_upto(serial &p_serial, std::span<const hal::byte> p_sequence, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
Construct a new skip beyond object.
- Parameters:
p_serial β - serial port to skip through
p_sequence β - sequence to search for. The lifetime of this data pointed to by this span must outlive this object, or not be used when the lifetime of that data is no longer available.
p_buffer β - buffer to fill data into
p_read_limit β - the maximum number of bytes to read off from the serial port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()
read data into the buffer.
This function will return if the read limit is reached or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
work_state - work_state::failed if the sequence wasnβt found before the buffer was filled completely.
- Returns:
work_state - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline read_uint32(serial &p_serial, size_t p_read_limit = 32)#
Construct a new read_uint32 object.
- Parameters:
p_serial β - serial port to skip through
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()
parse serial data and convert to an integer
This function will return if an integer ws found or no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress - if an integer hasnβt been found
- Returns:
work_state - work_state::finished - integer has been found and a non-integer byte has also been found.
-
class skip_past#
- #include <serial_coroutines.hpp>
Discard received bytes until the sequence is found.
Public Functions
-
inline skip_past(serial &p_serial, std::span<const hal::byte> p_sequence, size_t p_read_limit = 32)#
Construct a new skip beyond object.
- Parameters:
p_serial β - serial port to skip through
p_sequence β - sequence to search for. The lifetime of this data pointed to by this span must outlive this object, or not be used when the lifetime of that data is no longer available.
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline result<work_state> operator()()#
skip data from the serial port until the sequence is reached.
This function will return if the sequence is found or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
result<work_state> - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
result<work_state> - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline skip_past(serial &p_serial, std::span<const hal::byte> p_sequence, size_t p_read_limit = 32)#
-
class read_into#
- #include <serial_coroutines.hpp>
Non-blocking callable for reading serial data into a buffer.
Public Functions
-
inline read_into(serial &p_serial, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
Construct a new read_into object.
- Parameters:
p_serial β - serial port to skip through
p_buffer β - buffer to read data into
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()#
read data into the buffer.
This function will return if the read limit is reached or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
work_state - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline read_into(serial &p_serial, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
-
class read_upto#
- #include <serial_coroutines.hpp>
Discard received bytes until the sequence is found.
Public Functions
-
inline read_upto(serial &p_serial, std::span<const hal::byte> p_sequence, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
Construct a new skip beyond object.
- Parameters:
p_serial β - serial port to skip through
p_sequence β - sequence to search for. The lifetime of this data pointed to by this span must outlive this object, or not be used when the lifetime of that data is no longer available.
p_buffer β - buffer to fill data into
p_read_limit β - the maximum number of bytes to read off from the serial port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()#
read data into the buffer.
This function will return if the read limit is reached or if there are no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress if the sequence hasnβt been met and the buffer still has space.
- Returns:
work_state - work_state::failed if the sequence wasnβt found before the buffer was filled completely.
- Returns:
work_state - work_state::finished if the sequence was found before the buffer was filled completely.
-
inline read_upto(serial &p_serial, std::span<const hal::byte> p_sequence, std::span<hal::byte> p_buffer, size_t p_read_limit = 32)#
-
class read_uint32#
- #include <serial_coroutines.hpp>
Read bytes from serial port and convert to integer.
Public Functions
-
inline read_uint32(serial &p_serial, size_t p_read_limit = 32)#
Construct a new read_uint32 object.
- Parameters:
p_serial β - serial port to skip through
p_read_limit β - the maximum number read attempts from the port before returning. A value 0 will result in no reads from the serial port.
-
inline work_state operator()()#
parse serial data and convert to an integer
This function will return if an integer ws found or no more bytes in the serial port.
Call this function again to resume reading from the port.
- Returns:
work_state - work_state::in_progress - if an integer hasnβt been found
- Returns:
work_state - work_state::finished - integer has been found and a non-integer byte has also been found.
-
inline std::optional<uint32_t> get()#
- Returns:
std::optional<uint32_t> - integer if the parsing is finished or std::nullopt
-
inline read_uint32(serial &p_serial, size_t p_read_limit = 32)#
-
inline skip_past(serial &p_serial, std::span<const hal::byte> p_sequence, size_t p_read_limit = 32)#