From 6853f8c05db6aa183e0dec674649f9508a937fc9 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Sat, 4 Feb 2012 21:56:10 -0600 Subject: [PATCH] Fixing a reading buffer bug and expanding the example --- examples/serial_example.cc | 149 +++++++++++++++++++++++++++---------- src/impl/unix.cc | 3 +- 2 files changed, 110 insertions(+), 42 deletions(-) diff --git a/examples/serial_example.cc b/examples/serial_example.cc index 3ba886b..93de9af 100644 --- a/examples/serial_example.cc +++ b/examples/serial_example.cc @@ -1,3 +1,21 @@ +/*** + * This example expects the serial port has a loopback on it. + * + * Alternatively, you could use an Arduino: + * + *
+ *  setup() {
+ *    Serial.begin();
+ *  }
+ * 
+ *  loop() {
+ *    if (Serial.available()) {
+ *      Serial.write(Serial.read());
+ *    }
+ *  }
+ * 
+ */ + #include #include #include @@ -27,48 +45,97 @@ void my_sleep(unsigned long milliseconds) { int run(int argc, char **argv) { - if(argc < 3) { - cerr << "Usage: test_serial "; - cerr << " [test string]" << endl; - return 0; - } - // Argument 1 is the serial port - string port(argv[1]); - - // Argument 2 is the baudrate - unsigned long baud = 0; - sscanf(argv[2], "%lu", &baud); - - // port, baudrate, timeout in milliseconds - serial::Serial serial(port, baud, 1000); - - cout << "Is the serial port open?"; - if(serial.isOpen()) - cout << " Yes." << endl; - else - cout << " No." << endl; - - int count = 0; - string test_string; - if (argc == 4) { - test_string = argv[3]; - } else { - test_string = "Testing."; - } - while (true) { - size_t bytes_wrote = serial.write(test_string); - - string result = serial.read(test_string.length()); - - cout << "Iteration: " << count << ", Bytes written: "; - cout << bytes_wrote << ", Bytes read: "; - cout << result.length() << ", String read: " << result << endl; - - count += 1; - my_sleep(10); - } - + if(argc < 3) { + cerr << "Usage: test_serial "; + cerr << " [test string]" << endl; return 0; + } + // Argument 1 is the serial port + string port(argv[1]); + + // Argument 2 is the baudrate + unsigned long baud = 0; + sscanf(argv[2], "%lu", &baud); + + // port, baudrate, timeout in milliseconds + serial::Serial my_serial(port, baud, 1000); + + cout << "Is the serial port open?"; + if(my_serial.isOpen()) + cout << " Yes." << endl; + else + cout << " No." << endl; + + // Get the Test string + int count = 0; + string test_string; + if (argc == 4) { + test_string = argv[3]; + } else { + test_string = "Testing."; + } + + // Test the timeout, there should be 1 second between prints + cout << "Timeout == 1000ms, asking for 1 more byte than written." << endl; + while (count < 10) { + size_t bytes_wrote = my_serial.write(test_string); + + string result = my_serial.read(test_string.length()+1); + + cout << "Iteration: " << count << ", Bytes written: "; + cout << bytes_wrote << ", Bytes read: "; + cout << result.length() << ", String read: " << result << endl; + + count += 1; + } + + // Test the timeout at 250ms + my_serial.setTimeout(250); + count = 0; + cout << "Timeout == 250ms, asking for 1 more byte than written." << endl; + while (count < 10) { + size_t bytes_wrote = my_serial.write(test_string); + + string result = my_serial.read(test_string.length()+1); + + cout << "Iteration: " << count << ", Bytes written: "; + cout << bytes_wrote << ", Bytes read: "; + cout << result.length() << ", String read: " << result << endl; + + count += 1; + } + + // Test the timeout at 250ms, but asking exactly for what was written + count = 0; + cout << "Timeout == 250ms, asking for exactly what was written." << endl; + while (count < 10) { + size_t bytes_wrote = my_serial.write(test_string); + + string result = my_serial.read(test_string.length()); + + cout << "Iteration: " << count << ", Bytes written: "; + cout << bytes_wrote << ", Bytes read: "; + cout << result.length() << ", String read: " << result << endl; + + count += 1; + } + + // Test the timeout at 250ms, but asking for 1 less than what was written + count = 0; + cout << "Timeout == 250ms, asking for 1 less than was written." << endl; + while (count < 10) { + size_t bytes_wrote = my_serial.write(test_string); + + string result = my_serial.read(test_string.length()-1); + + cout << "Iteration: " << count << ", Bytes written: "; + cout << bytes_wrote << ", Bytes read: "; + cout << result.length() << ", String read: " << result << endl; + + count += 1; + } + + return 0; } int main(int argc, char **argv) { diff --git a/src/impl/unix.cc b/src/impl/unix.cc index cb84943..b8038a6 100644 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -454,7 +454,8 @@ Serial::SerialImpl::read (unsigned char* buf, size_t size) if (FD_ISSET (fd_, &readfds)) { // This should be non-blocking returning only what is avaialble now // Then returning so that select can block again. - ssize_t bytes_read_now = ::read (fd_, buf, size-bytes_read); + ssize_t bytes_read_now = + ::read (fd_, buf+bytes_read, size-bytes_read); // read should always return some data as select reported it was // ready to read when we get to this point. if (bytes_read_now < 1)