Class: OpenC3::PosixSerialDriver
- Defined in:
- lib/openc3/io/posix_serial_driver.rb
Overview
Serial driver for use on Posix serial ports found on UNIX based systems
Instance Method Summary collapse
-
#close ⇒ Object
Disconnects the driver from the comm port.
-
#closed? ⇒ Boolean
Whether the serial port has been closed.
-
#initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil, flow_control = :NONE, data_bits = 8) ⇒ PosixSerialDriver
constructor
A new instance of PosixSerialDriver.
-
#read ⇒ String
Binary data read from the serial port.
-
#read_nonblock ⇒ String
Binary data read from the serial port.
- #write(data) ⇒ Object
Constructor Details
#initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil, flow_control = :NONE, data_bits = 8) ⇒ PosixSerialDriver
Returns a new instance of PosixSerialDriver.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 31 def initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil, flow_control = :NONE, data_bits = 8) # Convert Baud Rate into Termios constant begin baud_rate = Object.const_get("Termios::B#{baud_rate}") rescue NameError raise(ArgumentError, "Invalid Baud Rate, Not Defined by Termios: #{baud_rate}") end # Verify Parameters raise(ArgumentError, "Invalid Data Bits: #{data_bits}") unless [5, 6, 7, 8].include?(data_bits) raise(ArgumentError, "Invalid parity: #{parity}") if parity and !SerialDriver::VALID_PARITY.include?(parity) raise(ArgumentError, "Invalid Stop Bits: #{stop_bits}") unless [1, 2].include?(stop_bits) @write_timeout = write_timeout @read_timeout = read_timeout parity = nil if parity == :NONE # Open the serial Port @handle = Kernel.open(port_name, File::RDWR | File::NONBLOCK) flags = @handle.fcntl(Fcntl::F_GETFL, 0) @handle.fcntl(Fcntl::F_SETFL, flags & ~File::NONBLOCK) @handle.extend Termios # Configure the serial Port tio = Termios.new_termios() iflags = 0 iflags |= Termios::IGNPAR unless parity cflags = 0 cflags |= Termios::CREAD # Enable receiver cflags |= Termios.const_get("CS#{data_bits}") # data bits cflags |= Termios::CLOCAL # Ignore Modem Control Lines cflags |= Termios::CSTOPB if stop_bits == 2 cflags |= Termios::PARENB if parity cflags |= Termios::PARODD if parity == :ODD cflags |= Termios::CRTSCTS if flow_control == :RTSCTS tio.iflag = iflags tio.oflag = 0 tio.cflag = cflags tio.lflag = 0 tio.cc[Termios::VTIME] = 0 tio.cc[Termios::VMIN] = 1 tio.ispeed = baud_rate tio.ospeed = baud_rate @handle.tcflush(Termios::TCIOFLUSH) @handle.tcsetattr(Termios::TCSANOW, tio) @pipe_reader, @pipe_writer = IO.pipe @readers = [@handle, @pipe_reader] end |
Instance Method Details
#close ⇒ Object
Disconnects the driver from the comm port
91 92 93 94 95 96 97 98 99 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 91 def close if @handle # Close the serial Port @pipe_writer.write('.') @pipe_writer.close @handle.close @handle = nil end end |
#closed? ⇒ Boolean
Returns Whether the serial port has been closed.
102 103 104 105 106 107 108 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 102 def closed? if @handle false else true end end |
#read ⇒ String
Returns Binary data read from the serial port.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 136 def read begin data = @handle.read_nonblock(65535) rescue Errno::EAGAIN, Errno::EWOULDBLOCK begin read_ready, _ = IO.fast_select(@readers, nil, nil, @read_timeout) rescue IOError @pipe_reader.close unless @pipe_reader.closed? return "" end if read_ready if read_ready.include?(@pipe_reader) @pipe_reader.close unless @pipe_reader.closed? return "" else retry end else raise Timeout::Error, "Read Timeout" end end data end |
#read_nonblock ⇒ String
Returns Binary data read from the serial port.
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 162 def read_nonblock data = '' begin data = @handle.read_nonblock(65535) rescue Errno::EAGAIN, Errno::EWOULDBLOCK # Do Nothing end data end |
#write(data) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/openc3/io/posix_serial_driver.rb', line 111 def write(data) num_bytes_to_send = data.length total_bytes_sent = 0 bytes_sent = 0 data_to_send = data loop do begin bytes_sent = @handle.write_nonblock(data_to_send) rescue Errno::EAGAIN, Errno::EWOULDBLOCK result = IO.fast_select(nil, [@handle], nil, @write_timeout) if result retry else raise Timeout::Error, "Write Timeout" end end total_bytes_sent += bytes_sent break if total_bytes_sent >= num_bytes_to_send data_to_send = data[total_bytes_sent..-1] end end |