mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 11:44:53 +08:00
Fixed some memory problems on destruction. Serial listener maybe working, serial's read doesn't seem to return anything or block at all.
This commit is contained in:
parent
2f36f14e1a
commit
48a30ec4ff
@ -13,9 +13,9 @@ void callback(std::string token) {
|
|||||||
std::cout << "callback got a: " << token << std::endl;
|
std::cout << "callback got a: " << token << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int run() {
|
||||||
// Assuming this device prints the string 'pre-substr-post\r' at 100Hz
|
// Assuming this device prints the string 'pre-substr-post\r' at 100Hz
|
||||||
Serial serial("/dev/tty.usbmodemfd1231", 115200);
|
Serial serial("/dev/tty.usbserial-A900cfJA", 115200);
|
||||||
|
|
||||||
SerialListener listener;
|
SerialListener listener;
|
||||||
listener.startListening(serial);
|
listener.startListening(serial);
|
||||||
@ -40,7 +40,7 @@ int main(void) {
|
|||||||
listener.createBlockingFilter(SerialListener::endsWith("post"));
|
listener.createBlockingFilter(SerialListener::endsWith("post"));
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
std::string token = f2->wait(100); // Wait for 100 ms or a matched token
|
std::string token = f2->wait(100); // Wait for 100 ms or a matched token
|
||||||
if (token == "")
|
if (token != "")
|
||||||
std::cout << "Found something ending with 'post'" << std::endl;
|
std::cout << "Found something ending with 'post'" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "Did not find something ending with 'post'" << std::endl;
|
std::cout << "Did not find something ending with 'post'" << std::endl;
|
||||||
@ -82,3 +82,12 @@ int main(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
try {
|
||||||
|
return run();
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -814,12 +814,10 @@ private:
|
|||||||
class BlockingFilter
|
class BlockingFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlockingFilter (ComparatorType comparator,
|
BlockingFilter (ComparatorType comparator, SerialListener &listener) {
|
||||||
boost::shared_ptr<SerialListener> listener)
|
this->listener = &listener;
|
||||||
: listener(listener)
|
|
||||||
{
|
|
||||||
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
|
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
|
||||||
this->filter_ptr = listener->createFilter(comparator, cb);
|
this->filter_ptr = this->listener->createFilter(comparator, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BlockingFilter () {
|
virtual ~BlockingFilter () {
|
||||||
@ -851,7 +849,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<SerialListener> listener;
|
SerialListener * listener;
|
||||||
boost::condition_variable cond;
|
boost::condition_variable cond;
|
||||||
boost::mutex mutex;
|
boost::mutex mutex;
|
||||||
std::string result;
|
std::string result;
|
||||||
@ -877,12 +875,13 @@ private:
|
|||||||
class BufferedFilter
|
class BufferedFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BufferedFilter (ComparatorType comparator, size_t buffer_size,
|
BufferedFilter (ComparatorType comparator, size_t buffer_size,
|
||||||
boost::shared_ptr<SerialListener> listener)
|
SerialListener &listener)
|
||||||
: listener(listener), buffer_size(buffer_size)
|
: buffer_size(buffer_size)
|
||||||
{
|
{
|
||||||
|
this->listener = &listener;
|
||||||
DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1);
|
DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1);
|
||||||
this->filter_ptr = listener->createFilter(comparator, cb);
|
this->filter_ptr = this->listener->createFilter(comparator, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BufferedFilter () {
|
virtual ~BufferedFilter () {
|
||||||
@ -944,7 +943,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
boost::shared_ptr<SerialListener> listener;
|
SerialListener * listener;
|
||||||
ConcurrentQueue<std::string> queue;
|
ConcurrentQueue<std::string> queue;
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ IF(EXISTS /usr/bin/clang)
|
|||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||||
# set(CMAKE_CXX_FLAGS "-ferror-limit=5 -std=c++0x -stdlib=libc++")
|
# set(CMAKE_CXX_FLAGS "-ferror-limit=5 -std=c++0x -stdlib=libc++")
|
||||||
set(CMAKE_CXX_FLAGS "-ferror-limit=5")
|
set(CMAKE_CXX_FLAGS "-ferror-limit=5")
|
||||||
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
ENDIF(EXISTS /usr/bin/clang)
|
ENDIF(EXISTS /usr/bin/clang)
|
||||||
|
|
||||||
option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF)
|
option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF)
|
||||||
|
|||||||
@ -22,6 +22,20 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class UnhandledException : public std::exception {
|
||||||
|
const char * e_what;
|
||||||
|
public:
|
||||||
|
UnhandledException(const char * e_what) {this->e_what = e_what;}
|
||||||
|
|
||||||
|
virtual const char* what() const throw() {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Unhandled Exception: " << this->e_what;
|
||||||
|
return ss.str().c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef UnhandledException e;
|
||||||
|
|
||||||
using ::serial::Serial;
|
using ::serial::Serial;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
@ -42,20 +56,20 @@ Serial::SerialImpl::~SerialImpl () {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::open () {
|
Serial::SerialImpl::open () {
|
||||||
if (port_.empty() == false) throw "error";
|
if (port_.empty() == true) throw e("error");
|
||||||
if (isOpen_ == false) throw "error";
|
if (isOpen_ == true) throw e("error");
|
||||||
|
|
||||||
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||||
|
|
||||||
if (fd_ == -1) throw "Error";
|
if (fd_ == -1) throw "Error";
|
||||||
|
|
||||||
reconfigurePort();
|
reconfigurePort();
|
||||||
isOpen_ = true;
|
isOpen_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::reconfigurePort () {
|
Serial::SerialImpl::reconfigurePort () {
|
||||||
if (fd_ == -1) throw "Error"; // Can only operate on a valid file descriptor
|
if (fd_ == -1) throw e("Error"); // Can only operate on a valid file descriptor
|
||||||
|
|
||||||
struct termios options; // The current options for the file descriptor
|
struct termios options; // The current options for the file descriptor
|
||||||
struct termios originalTTYAttrs; // The orignal file descriptor options
|
struct termios originalTTYAttrs; // The orignal file descriptor options
|
||||||
@ -66,7 +80,7 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
vtime = int(interCharTimeout_ * 10);
|
vtime = int(interCharTimeout_ * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcgetattr(fd_, &originalTTYAttrs) == -1) throw "Error";
|
if (tcgetattr(fd_, &originalTTYAttrs) == -1) throw e("Error");
|
||||||
|
|
||||||
options = originalTTYAttrs;
|
options = originalTTYAttrs;
|
||||||
|
|
||||||
@ -99,7 +113,7 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
else if (bytesize_ == FIVEBITS)
|
else if (bytesize_ == FIVEBITS)
|
||||||
options.c_cflag |= CS5;
|
options.c_cflag |= CS5;
|
||||||
else
|
else
|
||||||
throw "ValueError(Invalid char len: %%r)";
|
throw e("ValueError(Invalid char len: %%r)");
|
||||||
// setup stopbits
|
// setup stopbits
|
||||||
if (stopbits_ == STOPBITS_ONE)
|
if (stopbits_ == STOPBITS_ONE)
|
||||||
options.c_cflag &= ~(CSTOPB);
|
options.c_cflag &= ~(CSTOPB);
|
||||||
@ -108,7 +122,7 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
else if (stopbits_ == STOPBITS_TWO)
|
else if (stopbits_ == STOPBITS_TWO)
|
||||||
options.c_cflag |= (CSTOPB);
|
options.c_cflag |= (CSTOPB);
|
||||||
else
|
else
|
||||||
throw "ValueError(Invalid stop bit specification:)";
|
throw e("ValueError(Invalid stop bit specification:)");
|
||||||
// setup parity
|
// setup parity
|
||||||
options.c_iflag &= ~(INPCK|ISTRIP);
|
options.c_iflag &= ~(INPCK|ISTRIP);
|
||||||
if (parity_ == PARITY_NONE) {
|
if (parity_ == PARITY_NONE) {
|
||||||
@ -122,7 +136,7 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
options.c_cflag |= (PARENB|PARODD);
|
options.c_cflag |= (PARENB|PARODD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "ValueError(Invalid parity:";
|
throw e("ValueError(Invalid parity:");
|
||||||
}
|
}
|
||||||
// setup flow control
|
// setup flow control
|
||||||
// xonxoff
|
// xonxoff
|
||||||
@ -188,13 +202,13 @@ Serial::SerialImpl::available () {
|
|||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return count;
|
return count;
|
||||||
} else {
|
} else {
|
||||||
throw "Error";
|
throw e("Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
Serial::SerialImpl::read (size_t size) {
|
Serial::SerialImpl::read (size_t size) {
|
||||||
if (!isOpen_) throw "PortNotOpenError()";
|
if (!isOpen_) throw e("PortNotOpenError()");
|
||||||
string message = "";
|
string message = "";
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
@ -223,7 +237,7 @@ Serial::SerialImpl::read (size_t size) {
|
|||||||
// Disconnected devices, at least on Linux, show the
|
// Disconnected devices, at least on Linux, show the
|
||||||
// behavior that they are always ready to read immediately
|
// behavior that they are always ready to read immediately
|
||||||
// but reading returns nothing.
|
// but reading returns nothing.
|
||||||
throw "SerialException('device reports readiness to read but returned no data (device disconnected?)')";
|
throw e("SerialException('device reports readiness to read but returned no data (device disconnected?)')");
|
||||||
}
|
}
|
||||||
message.append(buf, bytes_read);
|
message.append(buf, bytes_read);
|
||||||
}
|
}
|
||||||
@ -236,12 +250,12 @@ Serial::SerialImpl::read (size_t size) {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
Serial::SerialImpl::write (const string &data) {
|
Serial::SerialImpl::write (const string &data) {
|
||||||
if (isOpen_ == false) throw "portNotOpenError";
|
if (isOpen_ == false) throw e("portNotOpenError");
|
||||||
|
|
||||||
size_t t = data.length();
|
size_t t = data.length();
|
||||||
size_t n = ::write(fd_, data.c_str(), data.length());
|
size_t n = ::write(fd_, data.c_str(), data.length());
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
throw "Write error";
|
throw e("Write error");
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,6 +64,8 @@ SerialListener::callback() {
|
|||||||
std::pair<FilterPtr,TokenPtr> pair;
|
std::pair<FilterPtr,TokenPtr> pair;
|
||||||
while (this->listening) {
|
while (this->listening) {
|
||||||
if (this->callback_queue.timed_wait_and_pop(pair, 10)) {
|
if (this->callback_queue.timed_wait_and_pop(pair, 10)) {
|
||||||
|
std::cout << "Got something off the callback queue: ";
|
||||||
|
std::cout << (*pair.second) << std::endl;
|
||||||
if (this->listening) {
|
if (this->listening) {
|
||||||
try {
|
try {
|
||||||
pair.first->callback((*pair.second));
|
pair.first->callback((*pair.second));
|
||||||
@ -133,6 +135,7 @@ SerialListener::readSomeData(std::string &temp, size_t this_many) {
|
|||||||
this->handle_exc(SerialListenerException("Serial port not open."));
|
this->handle_exc(SerialListenerException("Serial port not open."));
|
||||||
}
|
}
|
||||||
temp = this->serial_port->read(this_many);
|
temp = this->serial_port->read(this_many);
|
||||||
|
std::cout << "Read(" << temp.length() << "): " << temp << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -199,7 +202,7 @@ SerialListener::createFilter(ComparatorType comparator, DataCallback callback)
|
|||||||
BlockingFilterPtr
|
BlockingFilterPtr
|
||||||
SerialListener::createBlockingFilter(ComparatorType comparator) {
|
SerialListener::createBlockingFilter(ComparatorType comparator) {
|
||||||
return BlockingFilterPtr(
|
return BlockingFilterPtr(
|
||||||
new BlockingFilter(comparator, boost::shared_ptr<SerialListener>(this)));
|
new BlockingFilter(comparator, (*this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedFilterPtr
|
BufferedFilterPtr
|
||||||
@ -207,9 +210,7 @@ SerialListener::createBufferedFilter(ComparatorType comparator,
|
|||||||
size_t buffer_size)
|
size_t buffer_size)
|
||||||
{
|
{
|
||||||
return BufferedFilterPtr(
|
return BufferedFilterPtr(
|
||||||
new BufferedFilter(comparator,
|
new BufferedFilter(comparator, buffer_size, (*this)));
|
||||||
buffer_size,
|
|
||||||
boost::shared_ptr<SerialListener>(this)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user