整理代码

This commit is contained in:
蒲爽 2026-09-28 21:33:04 +08:00
commit c7b4e178ec
364 changed files with 59691 additions and 0 deletions

313
hardware/SerialPort.cpp Normal file
View 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;
}
}