class io.Serial
Overview
This class provides high-level asynchronous interface for accessing hardware or virtual serial ports. More…
import "io_base.jncx" import "io_Serial.jnc" class Serial { // fields io.SerialEvents readonly volatile m_activeEvents; std.Error const* readonly volatile m_ioError; bool readonly m_isOpen; // properties uint_t autoget property m_baudRate; io.SerialFlowControl autoget property m_flowControl; uint_t autoget property m_dataBits; io.SerialStopBits autoget property m_stopBits; io.SerialParity autoget property m_parity; io.SerialStatusLines const property m_statusLines; bool autoget property m_dtr; bool autoget property m_rts; bool autoget property m_breakCondition; uint_t autoget property m_updateInterval; uint_t autoget property m_readInterval; uint_t autoget property m_readParallelism; size_t autoget property m_readBlockSize; size_t autoget property m_readBufferSize; size_t autoget property m_writeBufferSize; io.SerialOptions autoget property m_options; uintptr_t const property m_osHandle; // construction construct(); destruct(); // methods bool errorcode open(string_t name); void close(); bool errorcode setupDevice( uint_t baudRate, uint_t dataBits = 8, io.SerialStopBits stopBits = SerialStopBits._1, io.SerialParity parity = SerialParity.None, io.SerialFlowControl flowControl = SerialFlowControl.None, uint_t readInterval = 0, bool dtr = false, bool rts = false ); io.SerialLineErrors clearLineErrors(); size_t errorcode read( void* p, size_t size ); size_t errorcode write( void const* p, size_t size ); long errorcode wait( io.SerialEvents eventMask, void function* handler(io.SerialEvents triggeredEvents) ); bool errorcode cancelWait(long handle); io.SerialEvents blockingWait( io.SerialEvents eventMask, uint_t timeout = -1 ); io.SerialEvents async asyncWait(io.SerialEvents eventMask); // aliases alias dispose = close; };
Detailed Documentation
This class provides high-level asynchronous interface for accessing hardware or virtual serial ports.
Serial ports are represented as files in most operating systems, so
working with serial port looks pretty much the same as working with any
other file stream. However, besides read
and write
operations serial
port files also expose a set of serial-specific properties such as baud
rate, status and control lines and so on.
A typical sequence of steps when working with a serial port usually looks like this:
Open a serial port with
open
method;Assign IO event handler with
wait
method. You would probably also want to schedule your event handler to be run in particular environment(e.g., in a specific thread) and partially apply some syncrhonization ID to discard late events;Configure serial port settings(
m_baudRate
,m_dataBits
etc)When
io.SerialEvents.IncomingData
event is fired, read from the serial port usingread
method;Write to the serial port stream using
write
method;Suspend writing if the return value of
write
is less than requested;Resume writing on
io.SerialEvents.WriteBufferReady
event;Close the serial port when no longer needed with
close
method.
Sample code:
class MyDialog { // ... io.Serial m_serial; uint_t m_syncId; void open( string_t portName, uint_t baudRate ); void close(); void waitSerialEvents(); void onWriteButtonClicked(); void onSerialEvent( uint_t syncId, io.SerialEvents triggeredEvents ); } MyDialog.open( string_t portName, uint_t baudRate ) { m_serial.open(portName); m_serial.m_baudRate = baudRate; m_serial.m_dataBits = 8; m_serial.m_stopBits = io.SerialStopBits._1; // ... waitSerialEvents(); catch: // handle the error... } MyDialog.close() { m_serial.close(); m_syncId++; // events past this point will be discarded as 'late' } MyDialog.waitSerialEvent() { io.SerialEvents eventMask = io.SerialEvents.IoError | io.SerialEvents.IncomingData; m_serial.wait(eventMask, onSerialEvent ~(++m_syncId) @ g_mainThreadScheduler); } MyDialog.onWriteButtonClicked() { static char data[] = "a quick brown fox jumps over the lazy dog"; m_serial.write(data, sizeof(data)); } MyDialog.onSerialEvent( uint_t syncId, io.SerialEvents triggeredEvents ) { if (syncId != m_syncId) // late event return; if (triggeredEvents & io.SerialEvents.IoError) { string_t errorString = m_fileStream.m_ioError.m_description; // ... } if (triggeredEvents & io.SerialEvents.IncomingData) { char buffer[256]; size_t size = m_fileStream.read(buffer, sizeof(buffer)); // ... } waitSerialEvents(); // restart wait }
See also:
io.SerialEvents
, io.File
, io.FileStream
Fields
bool readonly m_isOpen
Holds the open status for serial port, i.e. true
if opened;
false
otherwise.
Properties
uint_t autoget property m_baudRate
This property is used for getting and setting [1] baud rate, i.e. the number of signal changes per second, which directly affects the speed of data transmission.
Different hardware serial ports may or may not support some particular baud rates. Unfortunately, there is no reliable cross-platform method of building a list of supported baud rates, so the only way is to probe.
io.SerialFlowControl autoget property m_flowControl
This property is used for getting and setting [1] flow control, i.e. the protocol of attempted prevention of data loss during serial transmission which may happen when transmission side sends data faster than the receiving side is able to process it.
See io.SerialFlowControl
enumeration for the list of valid values.
uint_t autoget property m_dataBits
This property is used for getting and setting [1] byte size, i.e. the
number of bits in each character transmitted over the serial line. Valid
values range from 5
to 8
; normally 8
data bits are used.
io.SerialStopBits autoget property m_stopBits
This property is used for getting and setting [1] the number of
serial stop bits, i.e. auxillary(non-data) bits sent at the end of each
character to re-synchronize the receiver; normally 1 stop bit is used
(designated by io.SerialStopBits._1
)
See io.SerialStopBits
enumeration for the list of valid values.
io.SerialParity autoget property m_parity
This property is used for getting and setting [1] serial parity control, i.e. the protocol of attempted error detection during serial transmission. The idea is to send an extra parity bit so that the total number of one’s including data bits and this parity bit is always odd or always even.
This, however, is a rather weak error detection method; usually it’s much better to employ other checksums/hash checks after the data has been transmitted.
See io.SerialParity
for the list of valid values.
io.SerialStatusLines const property m_statusLines
This property is used for getting the values of serial status lines
(DSR
, CTS
, DCD
, RING
).
The returned value is a combination of io.SerialStatusLines
enumeration members, showing which status lines are high(or 0
if
all are low).
bool autoget property m_dtr
This property is used for getting and setting [1] DTR
(data-terminal-ready) serial control line.
bool autoget property m_rts
This property is used for getting and setting [1] RTS
(ready-to-send) serial control line.
bool autoget property m_breakCondition
This property is used for getting and setting [1] RTS
(ready-to-send) serial control line.
Methods
bool errorcode open(string_t name)
Opens a serial port.
The function accepts a single name
argument, which specifies the
name of the serial port device.
Returns true
on success. If serial port could not be opened, IO
error supplied by operating system is set and then the function
returns false
[2].
void close()
Closes a previously opened serial port, does nothing if the port is not opened. This function always succeeds.
Sometimes it may be convenient to use disposable pattern to ensure
timely invokation of close
[3].
size_t errorcode read( void* p, size_t size )
Attempts to read up to size
bytes from the serial port into the
buffer pointed to by p
.
Returns the actual amount of bytes read on success. If read operation
is unsuccessful, IO error supplied by the operating system is set and
then the function returns -1
[2].
Normally you would call this function from within your event handler for
IncomingData
event. If this function is called when there is no
incoming data, it blocks until either the data arrives, or the serial
port is closed.
size_t errorcode write( void const* p, size_t size )
Attempts to write size
bytes from the buffer pointed to by p
to the serial port.
Returns the actual amount of bytes written on success. If write
operation is unsuccessful, IO error supplied by the operating system is
set and then the function returns -1
[2].
If the return value shows less bytes than specified by size
argument, you should suspend further transmission until the file stream
is ready to accept more data. When this happens, WriteBufferReady
event is fired and transmission could be resumed.
Aliases
alias dispose = close
Effectively makes io.Serial
a disposable class [3].
Footnotes