mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 19:54:57 +08:00
Fixed some issues I found while testing my code, also implemented the drain, flush, set/send Break, get {CTS, RI, CD, DSR}, set {RTS, DTR}
This commit is contained in:
parent
99bf74faae
commit
11807e407b
16
Makefile
16
Makefile
@ -1,5 +1,11 @@
|
||||
ifdef ROS_ROOT
|
||||
include $(shell rospack find mk)/cmake.mk
|
||||
else
|
||||
include serial.makefile
|
||||
endif
|
||||
CXX=clang++
|
||||
CXXFLAGS=-g -I./include
|
||||
|
||||
test: tests/serial_tests.o src/serial.o src/impl/unix.o
|
||||
$(CXX) -o test tests/serial_tests.o src/serial.o src/impl/unix.o
|
||||
|
||||
# ifdef ROS_ROOT
|
||||
# include $(shell rospack find mk)/cmake.mk
|
||||
# else
|
||||
# include serial.makefile
|
||||
# endif
|
||||
|
||||
@ -66,14 +66,14 @@ public:
|
||||
void flushInput ();
|
||||
void flushOutput ();
|
||||
|
||||
void sendBreak();
|
||||
void setBreak();
|
||||
void setRTS();
|
||||
void setDTR();
|
||||
void getCTS();
|
||||
void getDSR();
|
||||
void getRI();
|
||||
void getCD();
|
||||
void sendBreak(int duration);
|
||||
void setBreak(bool level);
|
||||
void setRTS(bool level);
|
||||
void setDTR(bool level);
|
||||
bool getCTS();
|
||||
bool getDSR();
|
||||
bool getRI();
|
||||
bool getCD();
|
||||
|
||||
void setPort (const string &port);
|
||||
string getPort () const;
|
||||
|
||||
@ -373,6 +373,18 @@ public:
|
||||
flowcontrol_t
|
||||
getFlowcontrol () const;
|
||||
|
||||
void flush();
|
||||
void flushInput();
|
||||
void flushOutput();
|
||||
void sendBreak(int duration);
|
||||
void setBreak(bool level = true);
|
||||
void setRTS(bool level = true);
|
||||
void setDTR(bool level = true);
|
||||
bool getCTS();
|
||||
bool getDSR();
|
||||
bool getRI();
|
||||
bool getCD();
|
||||
|
||||
private:
|
||||
// Disable copy constructors
|
||||
Serial(const Serial&);
|
||||
|
||||
109
src/impl/unix.cc
109
src/impl/unix.cc
@ -33,7 +33,8 @@ Serial::SerialImpl::SerialImpl (const string &port, int baudrate,
|
||||
timeout_(timeout), bytesize_(bytesize), parity_(parity), stopbits_(stopbits),
|
||||
flowcontrol_(flowcontrol)
|
||||
{
|
||||
if (port_.empty() == false) {
|
||||
printf("Got port: %s\n", port.c_str());
|
||||
if (!port_.empty()) {
|
||||
this->open();
|
||||
}
|
||||
}
|
||||
@ -44,18 +45,20 @@ Serial::SerialImpl::~SerialImpl () {
|
||||
|
||||
void
|
||||
Serial::SerialImpl::open () {
|
||||
if (port_.empty() == false) {
|
||||
if (port_.empty()) {
|
||||
printf("Port was empty\n");
|
||||
throw "error";
|
||||
}
|
||||
if (isOpen_ == false) {
|
||||
if (isOpen_ == true) {
|
||||
printf("Port already opened\n");
|
||||
throw "error";
|
||||
}
|
||||
|
||||
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
|
||||
if (fd_ == -1) {
|
||||
// printf("Error opening serial port %s - %s(%d).\n",
|
||||
// port.c_str(), strerror(errno), errno);
|
||||
printf("Error opening serial port %s - %s(%d).\n",
|
||||
port_.c_str(), strerror(errno), errno);
|
||||
throw "Error"; // Error
|
||||
}
|
||||
|
||||
@ -213,7 +216,7 @@ Serial::SerialImpl::read (size_t size) {
|
||||
throw "PortNotOpenError()"; //
|
||||
}
|
||||
string message = "";
|
||||
char buf[1024];
|
||||
char buf[1024]; // TODO(ash_gti): Should this be 1024? or...?
|
||||
fd_set readfds;
|
||||
while (message.length() < size) {
|
||||
FD_ZERO(&readfds);
|
||||
@ -221,7 +224,7 @@ Serial::SerialImpl::read (size_t size) {
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = timeout_ / 1000;
|
||||
timeout.tv_usec = timeout_ % 1000;
|
||||
int r = select(1, &readfds, NULL, NULL, &timeout);
|
||||
int r = select(fd_ + 1, &readfds, NULL, NULL, &timeout);
|
||||
|
||||
if (r == -1 && errno == EINTR)
|
||||
continue;
|
||||
@ -233,7 +236,7 @@ Serial::SerialImpl::read (size_t size) {
|
||||
|
||||
if (FD_ISSET(fd_, &readfds)) {
|
||||
memset(buf, 0, 1024);
|
||||
size_t bytes_read = ::read(fd_, buf, 1024);
|
||||
size_t bytes_read = ::read(fd_, buf, size-strlen(buf));
|
||||
// read should always return some data as select reported it was
|
||||
// ready to read when we get to this point.
|
||||
if (bytes_read < 1) {
|
||||
@ -336,6 +339,96 @@ Serial::SerialImpl::getFlowcontrol () const {
|
||||
}
|
||||
|
||||
|
||||
void Serial::SerialImpl::flush () {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
tcdrain(fd_);
|
||||
}
|
||||
void Serial::SerialImpl::flushInput () {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
tcflush(fd_, TCIFLUSH);
|
||||
}
|
||||
void Serial::SerialImpl::flushOutput () {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
tcflush(fd_, TCOFLUSH);
|
||||
}
|
||||
|
||||
void Serial::SerialImpl::sendBreak(int duration) {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
tcsendbreak(fd_, int(duration/4));
|
||||
}
|
||||
void Serial::SerialImpl::setBreak(bool level) {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
if (level) {
|
||||
ioctl(fd_, TIOCSBRK);
|
||||
}
|
||||
else {
|
||||
ioctl(fd_, TIOCCBRK);
|
||||
}
|
||||
}
|
||||
void Serial::SerialImpl::setRTS(bool level) {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
if (level) {
|
||||
ioctl(fd_, TIOCMBIS, TIOCM_RTS);
|
||||
}
|
||||
else {
|
||||
ioctl(fd_, TIOCMBIC, TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
void Serial::SerialImpl::setDTR(bool level) {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
if (level) {
|
||||
ioctl(fd_, TIOCMBIS, TIOCM_DTR);
|
||||
}
|
||||
else {
|
||||
ioctl(fd_, TIOCMBIC, TIOCM_DTR);
|
||||
}
|
||||
|
||||
}
|
||||
bool Serial::SerialImpl::getCTS() {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
int s = ioctl(fd_, TIOCMGET, 0);
|
||||
return (s & TIOCM_CTS) != 0;
|
||||
}
|
||||
bool Serial::SerialImpl::getDSR() {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
int s = ioctl(fd_, TIOCMGET, 0);
|
||||
return (s & TIOCM_DSR) != 0;
|
||||
}
|
||||
bool Serial::SerialImpl::getRI() {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
int s = ioctl(fd_, TIOCMGET, 0);
|
||||
return (s & TIOCM_RI) != 0;
|
||||
}
|
||||
bool Serial::SerialImpl::getCD() {
|
||||
if (isOpen_ == false) {
|
||||
throw "portNotOpen";
|
||||
}
|
||||
int s = ioctl(fd_, TIOCMGET, 0);
|
||||
return (s & TIOCM_CD) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ Serial::Serial (const string &port, int baudrate,
|
||||
: pimpl(new SerialImpl(port,baudrate,timeout,bytesize,parity,stopbits,
|
||||
flowcontrol))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Serial::~Serial () {
|
||||
@ -62,12 +61,12 @@ Serial::read (size_t size) {
|
||||
string
|
||||
Serial::readline(size_t size, string eol) {
|
||||
size_t leneol = eol.length();
|
||||
string line;
|
||||
string line = "";
|
||||
while (true) {
|
||||
string c = read(1);
|
||||
if (c.empty()) {
|
||||
line += c;
|
||||
if (line.substr(line.length() - leneol, leneol) == eol) {
|
||||
string c = pimpl->read(1);
|
||||
if (!c.empty()) {
|
||||
line.append(c);
|
||||
if (line.length() > leneol && line.substr(line.length() - leneol, leneol) == eol) {
|
||||
break;
|
||||
}
|
||||
if (line.length() >= size) {
|
||||
@ -186,6 +185,39 @@ Serial::getFlowcontrol () const {
|
||||
return this->pimpl->getFlowcontrol ();
|
||||
}
|
||||
|
||||
void Serial::flush() {
|
||||
this->pimpl->flush();
|
||||
}
|
||||
void Serial::flushInput() {
|
||||
this->pimpl->flushInput();
|
||||
}
|
||||
void Serial::flushOutput() {
|
||||
this->pimpl->flushOutput();
|
||||
}
|
||||
void Serial::sendBreak(int duration) {
|
||||
this->pimpl->sendBreak(duration);
|
||||
}
|
||||
void Serial::setBreak(bool level) {
|
||||
this->pimpl->setBreak(level);
|
||||
}
|
||||
void Serial::setRTS(bool level) {
|
||||
this->pimpl->setRTS(level);
|
||||
}
|
||||
void Serial::setDTR(bool level) {
|
||||
this->pimpl->setDTR(level);
|
||||
}
|
||||
bool Serial::getCTS() {
|
||||
return this->pimpl->getCTS();
|
||||
}
|
||||
bool Serial::getDSR() {
|
||||
return this->pimpl->getDSR();
|
||||
}
|
||||
bool Serial::getRI() {
|
||||
return this->pimpl->getRI();
|
||||
}
|
||||
bool Serial::getCD() {
|
||||
return this->pimpl->getCD();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
29
tests/serial_tests.cc
Normal file
29
tests/serial_tests.cc
Normal file
@ -0,0 +1,29 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
// OMG this is so nasty...
|
||||
// #define private public
|
||||
// #define protected public
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "serial/serial.h"
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using serial::Serial;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Serial s("/dev/tty.usbserial-A900adHq", 9600, 2000);
|
||||
s.flush();
|
||||
int count = 0;
|
||||
while (count < 10) {
|
||||
size_t available = s.available();
|
||||
cout << "avialable: " << available << endl;
|
||||
string line = s.readline();
|
||||
cout << count << ": " << line;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user