From: <ean...@us...> - 2012-09-16 17:08:28
|
Revision: 11035 http://octave.svn.sourceforge.net/octave/?rev=11035&view=rev Author: eandrius Date: 2012-09-16 17:08:22 +0000 (Sun, 16 Sep 2012) Log Message: ----------- instrument-control: serial, implemented interrupt signal and fixed return value for srl_read Modified Paths: -------------- trunk/octave-forge/main/instrument-control/src/serial/serial.cc trunk/octave-forge/main/instrument-control/src/serial/serial.h trunk/octave-forge/main/instrument-control/src/serial/srl_close.cc trunk/octave-forge/main/instrument-control/src/serial/srl_read.cc trunk/octave-forge/main/instrument-control/src/serial/srl_timeout.cc Modified: trunk/octave-forge/main/instrument-control/src/serial/serial.cc =================================================================== --- trunk/octave-forge/main/instrument-control/src/serial/serial.cc 2012-09-16 07:35:06 UTC (rev 11034) +++ trunk/octave-forge/main/instrument-control/src/serial/serial.cc 2012-09-16 17:08:22 UTC (rev 11035) @@ -112,6 +112,7 @@ unsigned short stopbits = 1; int oflags = O_RDWR | O_NOCTTY | O_SYNC; // O_SYNC - All writes immediately effective, no buffering + // O_NOCTTY - Don't make serial terminal the controlling terminal for the process if (!type_loaded) { @@ -172,11 +173,7 @@ } retval->set_baudrate(baud_rate); - - if (timeout >= 0) { - retval->set_timeout(timeout); - } - + retval->set_timeout(timeout); retval->set_parity(parity); retval->set_bytesize(bytesize); retval->set_stopbits(stopbits); Modified: trunk/octave-forge/main/instrument-control/src/serial/serial.h =================================================================== --- trunk/octave-forge/main/instrument-control/src/serial/serial.h 2012-09-16 07:35:06 UTC (rev 11034) +++ trunk/octave-forge/main/instrument-control/src/serial/serial.h 2012-09-16 17:08:22 UTC (rev 11035) @@ -37,7 +37,7 @@ int write(unsigned char*, int); int read(char *, unsigned int); - + int close(); int flush(unsigned short); @@ -79,7 +79,7 @@ int fd; struct termios config; - bool blocking_read; + volatile bool blocking_read; DECLARE_OCTAVE_ALLOCATOR DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA Modified: trunk/octave-forge/main/instrument-control/src/serial/srl_close.cc =================================================================== --- trunk/octave-forge/main/instrument-control/src/serial/srl_close.cc 2012-09-16 07:35:06 UTC (rev 11034) +++ trunk/octave-forge/main/instrument-control/src/serial/srl_close.cc 2012-09-16 17:08:22 UTC (rev 11035) @@ -61,11 +61,11 @@ int octave_serial::close() { - if (this->get_fd() < 0) + /*if (this->get_fd() < 0) { error("serial: Interface must be opened first..."); return -1; - } + }*/ int retval = ::close(this->get_fd()); this->fd = -1; Modified: trunk/octave-forge/main/instrument-control/src/serial/srl_read.cc =================================================================== --- trunk/octave-forge/main/instrument-control/src/serial/srl_read.cc 2012-09-16 07:35:06 UTC (rev 11034) +++ trunk/octave-forge/main/instrument-control/src/serial/srl_read.cc 2012-09-16 17:08:22 UTC (rev 11035) @@ -14,8 +14,8 @@ // along with this program; if not, see <http://www.gnu.org/licenses/>. #include <octave/oct.h> -#include <octave/ov-int32.h> -#include <octave/ov-uint8.h> +#include <octave/uint8NDArray.h> +#include <octave/sighandlers.h> #include <iostream> #include <string> @@ -34,8 +34,16 @@ #include "serial.h" +volatile bool read_interrupt = false; + +void read_sighandler(int sig) +{ + printf("srl_read: Interrupting...\n\r"); + read_interrupt = true; +} + DEFUN_DLD (srl_read, args, nargout, -"-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } srl_read (@var{serial}, @var{n})\n \ \n\ Read from serial interface.\n \ @@ -46,28 +54,25 @@ The srl_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { - if (args.length() < 1 || args.length() > 2 || args(0).type_id() != octave_serial::static_type_id()) + if (args.length() != 2 || args(0).type_id() != octave_serial::static_type_id()) { print_usage(); return octave_value(-1); } - char *buffer = NULL; - unsigned int buffer_len = 1; + unsigned int buffer_len = 0; - if (args.length() > 1) + if ( !(args(1).is_integer_type() || args(1).is_float_type()) ) { - if ( !(args(1).is_integer_type() || args(1).is_float_type()) ) - { - print_usage(); - return octave_value(-1); - } - - buffer_len = args(1).int_value(); + print_usage(); + return octave_value(-1); } - buffer = new char[buffer_len+1]; + buffer_len = args(1).int_value(); + char *buffer = NULL; + buffer = new char[buffer_len + 1]; + if (buffer == NULL) { error("srl_read: cannot allocate requested memory: %s\n", strerror(errno)); @@ -79,24 +84,26 @@ const octave_base_value& rep = args(0).get_rep(); serial = &((octave_serial &)rep); - int buffer_read = 0, read_retval = -1; + // Register custom interrupt signal handler + octave_set_signal_handler(SIGINT, read_sighandler); + read_interrupt = false; + + // Read data + int bytes_read = serial->read(buffer, buffer_len); - // While buffer not full and not timeout - while (buffer_read < buffer_len && read_retval != 0) - { - read_retval = serial->read(buffer + buffer_read, buffer_len - buffer_read); - buffer_read += read_retval; - } + // Restore default signal handling + // TODO: a better way? + install_signal_handlers(); - octave_value_list return_list; - uint8NDArray data(buffer_read); - - // TODO: clean this up - for (int i = 0; i < buffer_read; i++) + // Convert data to octave type variables + octave_value_list return_list(2); + uint8NDArray data( dim_vector(1, bytes_read) ); + + for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; - return_list(1) = buffer_read; return_list(0) = data; + return_list(1) = bytes_read; delete[] buffer; @@ -107,9 +114,38 @@ { if (this->get_fd() < 0) { - error("serial: Interface must be opened first..."); - return -1; + error("srl_read: Interface must be opened first..."); + return 0; } - - return ::read(get_fd(), buf, len); + + int bytes_read = 0, read_retval = -1; + + // While not interrupted in blocking mode + while (!read_interrupt) + { + read_retval = ::read(this->get_fd(), (void *)(buf + bytes_read), len - bytes_read); + //printf("read_retval: %d\n\r", read_retval); + + if (read_retval < 0) + { + error("srl_read: Error while reading: %s\n", strerror(errno)); + break; + } + + bytes_read += read_retval; + + // Required number of bytes read + if (bytes_read >= len) + break; + + // Timeout while in non-blocking mode + if (read_retval == 0 && !this->blocking_read) + break; + } + + return bytes_read; } + +/*int octave_serial::readline(char *buf, unsigned int len) +{ +}*/ Modified: trunk/octave-forge/main/instrument-control/src/serial/srl_timeout.cc =================================================================== --- trunk/octave-forge/main/instrument-control/src/serial/srl_timeout.cc 2012-09-16 07:35:06 UTC (rev 11034) +++ trunk/octave-forge/main/instrument-control/src/serial/srl_timeout.cc 2012-09-16 17:08:22 UTC (rev 11035) @@ -34,14 +34,14 @@ #include "serial.h" DEFUN_DLD (srl_timeout, args, nargout, -"-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} srl_timeout (@var{serial}, @var{timeout})\n \ @deftypefnx {Loadable Function} {@var{t} = } srl_timeout (@var{serial})\n \ \n\ Set new or get existing serial interface timeout parameter used for srl_read() requests. The timeout value is specified in tenths of a second.\n \ \n\ @var{serial} - instance of @var{octave_serial} class.@*\ -@var{timeout} - srl_read() timeout value in tenths of a second. Maximum value of 255 (i.e. 25.5 seconds).\n \ +@var{timeout} - srl_read() timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).\n \ \n\ If @var{timeout} parameter is omitted, the srl_timeout() shall return current timeout value as the result @var{t}.\n \ @end deftypefn") @@ -51,7 +51,7 @@ print_usage(); return octave_value(-1); } - + octave_serial* serial = NULL; const octave_base_value& rep = args(0).get_rep(); @@ -82,36 +82,35 @@ error("serial: Interface must be opened first..."); return -1; } - - if (timeout < 0 || timeout > 255) + + if (timeout < -1 || timeout > 255) { - error("srl_timeout: timeout value must be between [0..255]..."); - return false; + error("srl_timeout: timeout value must be between [-1..255]..."); + return -1; } - /* - // Disable timeout, enable blocking read + // Disable custom timeout, enable blocking read if (timeout < 0) { this->blocking_read = true; - BITMASK_SET(this->config.c_lflag, ICANON); // Set canonical mode - this->config.c_cc[VMIN] = 1; - this->config.c_cc[VTIME] = 0; + timeout = 5; + } + // Enable custom timeout, disable blocking read + else + { + this->blocking_read = false; } - */ - // Enable timeout, disable blocking read - this->blocking_read = false; BITMASK_CLEAR(this->config.c_lflag, ICANON); // Set non-canonical mode this->config.c_cc[VMIN] = 0; this->config.c_cc[VTIME] = (unsigned) timeout; // Set timeout of 'timeout * 10' seconds if (tcsetattr(this->get_fd(), TCSANOW, &this->config) < 0) { error("srl_timeout: error setting stop bits..."); - return false; + return -1; } - return true; + return 1; } int octave_serial::get_timeout() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |