serial_pos.hpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9  ** Ifdefs
10  *****************************************************************************/
11 
12 #ifndef ECL_DEVICES_SERIAL_POS_HPP_
13 #define ECL_DEVICES_SERIAL_POS_HPP_
14 
15 /*****************************************************************************
16  ** Platform Check
17  *****************************************************************************/
18 
19 #include <ecl/config.hpp>
20 #if defined(ECL_IS_POSIX)
21 
22 /*****************************************************************************
23  ** Includes
24  *****************************************************************************/
25 
26 #include <string>
27 #include <termios.h>
30 #include <ecl/time/snooze.hpp>
33 #include "detail/error_handler.hpp"
35 #include "serial_parameters.hpp"
36 #include "traits.hpp"
37 
38 /*****************************************************************************
39  ** Namespaces
40  *****************************************************************************/
41 
42 namespace ecl
43 {
44 
45  /*****************************************************************************
46  ** Interface [Serial]
47  *****************************************************************************/
131  class Serial
132  {
133  public:
134  /*********************
135  ** C&D
136  **********************/
144  Serial() : is_open(false), error_handler(NoError)
145  {};
163  Serial(const std::string& port_name, const BaudRate &baud_rate = BaudRate_115200, const DataBits &data_bits = DataBits_8,
164  const StopBits &stop_bits = StopBits_1, const Parity &parity = NoParity );
165 
171  virtual ~Serial();
172 
173  /*********************
174  ** Open/Close
175  **********************/
210  bool open(const std::string& port_name, const BaudRate &baud_rate = BaudRate_115200, const DataBits &data_bits = DataBits_8,
211  const StopBits &stop_bits = StopBits_1, const Parity &parity = NoParity );
212 
220  void close();
230  bool open();
231 
232  /*********************
233  ** Writing
234  **********************/
244  template <typename Byte>
245  long write(const Byte &byte);
246 
257  template <typename Byte>
258  long write(const Byte *bytes, const unsigned long &n);
259 
266  void flush()
267  {}
268 
269  /*********************
270  ** Reading Modes
271  **********************/
290  void block(const unsigned long &timeout = 500);
297  void unblock();
298 
299  /*********************
300  ** Reading
301  **********************/
309  long remaining();
323  template <typename Byte>
324  long read(Byte &byte);
339  template <typename Byte>
340  long read(Byte *bytes, const unsigned long &n);
341 
342  /*********************
343  ** Serial Specific
344  **********************/
351  void clear()
352  { tcflush(file_descriptor,TCIOFLUSH);}
358  void clearInputBuffer()
359  { tcflush(file_descriptor,TCIFLUSH);}
365  void clearOutputBuffer()
366  { tcflush(file_descriptor,TCOFLUSH);}
367 
374  const Error& error() const
375  { return error_handler;}
376  private:
377  /*********************
378  ** Constants
379  **********************/
380  enum {
381  NonBlocking = -1
382  };
383  /*********************
384  ** Variables
385  **********************/
386  int file_descriptor;
387  termios options;
388  std::string port;
389  unsigned long read_timeout_ms;
390  ecl::Snooze fake_snooze;
391  unsigned int fake_loop_count;
392  bool is_open;
393  ecl::Error error_handler;
394  };
395 
396  /*****************************************************************************
397  ** Template Implementations
398  *****************************************************************************/
399 
400  template <typename Byte>
401  long Serial::write(const Byte &byte)
402  {
404  if ( !is_open ) // internal check only, don't worry about doing the full device filename check here (we need speed)
405  {
406  ecl_debug_throw( StandardException(LOC, OpenError, std::string("Port ") + port + std::string(" is not open.")));
407  error_handler = OpenError;
408  return -1;
409  }
410  ssize_t no_written = ::write(file_descriptor, &byte, 1);
411  if ( no_written < 0 )
412  {
414  error_handler = devices::write_error();
415  return -1;
416  }
417  error_handler = NoError;
418  return no_written;
419  }
420 
421  template <typename Byte>
422  long Serial::write(const Byte *bytes, const unsigned long &n)
423  {
425  if ( !is_open ) // internal check only, don't worry about doing the full device filename check here (we need speed)
426  {
427  ecl_debug_throw( StandardException(LOC, OpenError, std::string("Port ") + port + std::string(" is not open.")));
428  error_handler = OpenError;
429  return -1;
430  }
431  ssize_t no_written = ::write(file_descriptor, bytes, n);
432  if ( no_written < 0 )
433  {
435  error_handler = devices::write_error();
436  return -1;
437  }
438  error_handler = NoError;
439  return no_written;
440  }
441 
442  template <typename Byte>
443  long Serial::read(Byte &byte)
444  {
446  if ( !is_open ) // internal check only, don't worry about doing the full device filename check here (we need speed)
447  {
448  ecl_debug_throw( StandardException(LOC, OpenError, std::string("Port ") + port + std::string(" is not open.")));
449  error_handler = OpenError;
450  return -1;
451  }
452  ssize_t no_read;
453  if ( ( read_timeout_ms != NonBlocking ) && ( read_timeout_ms < 100 ) )
454  {
455  fake_snooze.initialise();
456  for ( unsigned int i = 0; i < fake_loop_count; ++i )
457  {
458  no_read = ::read(file_descriptor, &byte, 1);
459  if ( no_read != 0 )
460  {
461  break;
462  }
463  fake_snooze();
464  }
465  }
466  else
467  {
468  no_read = ::read(file_descriptor, &byte, 1);
469  }
470  if ( no_read < 0 )
471  {
473  error_handler = devices::read_error();
474  return -1;
475  }
476  error_handler = NoError;
477  return no_read;
478 
479  }
480 
481  template <typename Byte>
482  long Serial::read(Byte *bytes, const unsigned long &n)
483  {
485  if ( !is_open ) // internal check only, don't worry about doing the full device filename check here (we need speed)
486  {
487  ecl_debug_throw( StandardException(LOC, OpenError, std::string("Port ") + port + std::string(" is not open.")));
488  error_handler = OpenError;
489  return -1;
490  }
491  ssize_t no_read = 0;
492  if ( ( read_timeout_ms != NonBlocking ) && ( read_timeout_ms < 100 ) )
493  {
494  fake_snooze.initialise();
495  for ( unsigned int i = 0; i < fake_loop_count; ++i )
496  {
497  no_read = ::read(file_descriptor, bytes, n);
498  if ( no_read != 0 )
499  {
500  break;
501  }
502  fake_snooze();
503  }
504  }
505  else
506  {
507  no_read = ::read(file_descriptor, bytes, n);
508  }
509  if ( no_read < 0 )
510  {
512  error_handler = devices::read_error();
513  return -1;
514  }
515  error_handler = NoError;
516  return no_read;
517  }
518 
519  /*****************************************************************************
520  ** Traits [Serial]
521  *****************************************************************************/
527  template <>
528  class is_sink<Serial> : public True
529  {};
530 
536  template <>
537  class is_source<Serial> : public True
538  {};
539 
545  template <>
546  class is_sourcesink<Serial> : public True
547  {};
548 
549 } // namespace ecl
550 
551 #endif /* ECL_IS_POSIX */
552 #endif /* ECL_DEVICES_SERIAL_POS_HPP_ */
ecl::OpenError
OpenError
ecl::DataBits_8
@ DataBits_8
Definition: serial_parameters.hpp:64
snooze.hpp
ecl::BaudRate_115200
@ BaudRate_115200
Definition: serial_parameters.hpp:55
serial_parameters.hpp
Cross-platform abstractions for the serial class.
ecl::devices::write_exception
StandardException write_exception(const char *loc)
Definition: exception_handler_pos.cpp:85
ecl::Error
ecl::Bool::value
static const bool value
ecl::Parity
Parity
Parity of the serial packet.
Definition: serial_parameters.hpp:83
ecl::NoParity
@ NoParity
Definition: serial_parameters.hpp:84
error_handler.hpp
Defines error handlers for posix devices.
parameter.hpp
ecl::NoError
NoError
True
Bool< true > True
ecl::DataBits
DataBits
Data bits used in a serial packet.
Definition: serial_parameters.hpp:60
ecl::devices::read_error
ecl::Error read_error()
Definition: error_handler.cpp:86
fundamental_types.hpp
ecl::devices::read_exception
StandardException read_exception(const char *loc)
Definition: exception_handler_pos.cpp:107
config.hpp
ecl::BaudRate
BaudRate
Serial connection baud rate.
Definition: serial_parameters.hpp:38
standard_exception.hpp
exception_handler_pos.hpp
Defines exception handlers for posix devices.
ecl::StopBits_1
@ StopBits_1
Definition: serial_parameters.hpp:73
ecl::devices::write_error
ecl::Error write_error()
Definition: error_handler.cpp:69
ecl_compile_time_assert
#define ecl_compile_time_assert(logical_expression)
ecl
Embedded control libraries.
compile_time_assert.hpp
ecl::StopBits
StopBits
Stop bits used in a serial packet.
Definition: serial_parameters.hpp:72
ecl_debug_throw
#define ecl_debug_throw(exception)


ecl_devices
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:45