整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
313
hardware/SerialPort.cpp
Normal file
313
hardware/SerialPort.cpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "SerialPort.h"
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <Poco/Exception.h>
|
||||
#include <Poco/Format.h>
|
||||
|
||||
namespace Hardware
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
SerialPort::SerialPort(): _fd(-1)
|
||||
{
|
||||
}
|
||||
|
||||
SerialPort::~SerialPort()
|
||||
{
|
||||
if (isOpen())
|
||||
close();
|
||||
}
|
||||
|
||||
void SerialPort::open()
|
||||
{
|
||||
if (isOpen())
|
||||
return;
|
||||
|
||||
if (_path.empty())
|
||||
throw Poco::InvalidArgumentException("Empty path");
|
||||
|
||||
struct termios options = {0};
|
||||
options.c_cflag |= CLOCAL | getBaudRateFlag(_baudRate);
|
||||
switch (_dataBits)
|
||||
{
|
||||
case 5:
|
||||
options.c_cflag |= CS5;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
options.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
options.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
options.c_cflag |= CS8;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::InvalidArgumentException(Poco::format("Invalid data bits: %d", _dataBits));
|
||||
}
|
||||
|
||||
switch (_stopBits)
|
||||
{
|
||||
case 1:
|
||||
options.c_cflag &= ~CSTOPB;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
options.c_cflag |= CSTOPB;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 3:
|
||||
case 4:
|
||||
throw Poco::InvalidArgumentException(Poco::format("Invalid stop bits: %d", _stopBits));
|
||||
}
|
||||
|
||||
switch (_parity)
|
||||
{
|
||||
default:
|
||||
case Parity::NONE:
|
||||
options.c_cflag &= ~PARENB;
|
||||
options.c_iflag &= ~INPCK;
|
||||
break;
|
||||
|
||||
case Parity::ODD:
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag |= PARODD;
|
||||
options.c_iflag |= INPCK;
|
||||
options.c_iflag |= ISTRIP;
|
||||
break;
|
||||
|
||||
case Parity::EVEN:
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag &= ~PARODD;
|
||||
options.c_iflag |= INPCK;
|
||||
options.c_iflag |= ISTRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
options.c_cflag |= CREAD;
|
||||
|
||||
switch (_flowControl)
|
||||
{
|
||||
default:
|
||||
case FlowControl::NONE:
|
||||
options.c_cflag &= ~CRTSCTS;
|
||||
break;
|
||||
|
||||
case FlowControl::RTSCTS:
|
||||
options.c_cflag |= CRTSCTS;
|
||||
break;
|
||||
}
|
||||
|
||||
_fd = ::open(_path.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (_fd < 0)
|
||||
throw Poco::InvalidAccessException(Poco::format("Open '%s' FAIL: %d", _path, _fd));
|
||||
|
||||
tcflush(_fd, TCIOFLUSH);
|
||||
cfmakeraw(&options);
|
||||
tcsetattr(_fd, TCSANOW, &options);
|
||||
}
|
||||
|
||||
void SerialPort::close()
|
||||
{
|
||||
if (!isOpen())
|
||||
return;
|
||||
|
||||
::close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
|
||||
bool SerialPort::isOpen()
|
||||
{
|
||||
return _fd != -1;
|
||||
}
|
||||
|
||||
int SerialPort::write(const void* pData, uint32_t size)
|
||||
{
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
|
||||
return ::write(_fd, pData, size);
|
||||
}
|
||||
|
||||
int SerialPort::read(void* pBuffer, uint32_t length, uint32_t timeout)
|
||||
{
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
|
||||
struct timeval tm;
|
||||
tm.tv_sec = timeout / 1000;
|
||||
tm.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
fd_set reads;
|
||||
FD_ZERO(&reads);
|
||||
FD_SET(_fd, &reads);
|
||||
|
||||
int rc = ::select(_fd + 1, &reads, NULL, NULL, &tm);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
|
||||
if (FD_ISSET(_fd, &reads))
|
||||
return ::read(_fd, pBuffer, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setPath(const std::string& path)
|
||||
{
|
||||
_path = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setBaudRate(uint32_t baudRate)
|
||||
{
|
||||
_baudRate = baudRate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setParity(Parity parity)
|
||||
{
|
||||
_parity = parity;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setDataBits(uint32_t bits)
|
||||
{
|
||||
_dataBits = bits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setStopBits(uint32_t bits)
|
||||
{
|
||||
_stopBits = bits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SerialPort& SerialPort::setFlowControl(FlowControl flowControl)
|
||||
{
|
||||
_flowControl = flowControl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32_t SerialPort::getBaudRateFlag(uint32_t br)
|
||||
{
|
||||
uint32_t flag;
|
||||
|
||||
switch (br)
|
||||
{
|
||||
case 0:
|
||||
flag = B0;
|
||||
break;
|
||||
case 50:
|
||||
flag = B50;
|
||||
break;
|
||||
case 75:
|
||||
flag = B75;
|
||||
break;
|
||||
case 110:
|
||||
flag = B110;
|
||||
break;
|
||||
case 134:
|
||||
flag = B134;
|
||||
break;
|
||||
case 150:
|
||||
flag = B150;
|
||||
break;
|
||||
case 200:
|
||||
flag = B200;
|
||||
break;
|
||||
case 300:
|
||||
flag = B300;
|
||||
break;
|
||||
case 600:
|
||||
flag = B600;
|
||||
break;
|
||||
case 1200:
|
||||
flag = B1200;
|
||||
break;
|
||||
case 1800:
|
||||
flag = B1800;
|
||||
break;
|
||||
case 2400:
|
||||
flag = B2400;
|
||||
break;
|
||||
case 4800:
|
||||
flag = B4800;
|
||||
break;
|
||||
case 9600:
|
||||
flag = B9600;
|
||||
break;
|
||||
case 19200:
|
||||
flag = B19200;
|
||||
break;
|
||||
case 38400:
|
||||
flag = B38400;
|
||||
break;
|
||||
case 57600:
|
||||
flag = B57600;
|
||||
break;
|
||||
case 115200:
|
||||
flag = B115200;
|
||||
break;
|
||||
case 230400:
|
||||
flag = B230400;
|
||||
break;
|
||||
case 460800:
|
||||
flag = B460800;
|
||||
break;
|
||||
case 500000:
|
||||
flag = B500000;
|
||||
break;
|
||||
case 576000:
|
||||
flag = B576000;
|
||||
break;
|
||||
case 921600:
|
||||
flag = B921600;
|
||||
break;
|
||||
case 1000000:
|
||||
flag = B1000000;
|
||||
break;
|
||||
case 1152000:
|
||||
flag = B1152000;
|
||||
break;
|
||||
case 1500000:
|
||||
flag = B1500000;
|
||||
break;
|
||||
case 2000000:
|
||||
flag = B2000000;
|
||||
break;
|
||||
case 2500000:
|
||||
flag = B2500000;
|
||||
break;
|
||||
case 3000000:
|
||||
flag = B3000000;
|
||||
break;
|
||||
case 3500000:
|
||||
flag = B3500000;
|
||||
break;
|
||||
case 4000000:
|
||||
flag = B4000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
flag = B9600;
|
||||
break;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue