/** .============.* // M A K E / \* // C++ DEV / \* // E A S Y / \/ \* ++ ----------. \/\ .* \\ \ \ /\ /* \\ \ \ /* \\ \ \ /* -============'** Copyright (c) 2018 Hevake and contributors, all rights reserved.** This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox)* Use of this source code is governed by MIT license that can be found* in the LICENSE file in the root of the source tree. All contributing* project authors may be found in the CONTRIBUTORS.md file in the root* of the source tree.*/#include "uart.h"#include <termios.h>#include <fcntl.h>#include <tbox/base/log.h>#include <tbox/util/string_to.h>#undef MODULE_ID#define MODULE_ID "tbox.uart"namespace tbox {namespace network {Uart::Uart(event::Loop *wp_loop) :buff_fd_(wp_loop){ }bool Uart::initialize(const std::string &dev, const std::string &mode){if (!openDevice(dev))return false;return setMode(mode);}bool Uart::initialize(const std::string &dev, const Mode &mode){if (!openDevice(dev))return false;return setMode(mode);}namespace {int Baudrate2Enum(int baudrate){switch (baudrate) {#ifdef B50case (50): return B50;#endif /* B50 */#ifdef B75case (75): return B75;#endif /* B75 */#ifdef B110case (110): return B110;#endif /* B110 */#ifdef B134case (134): return B134;#endif /* B134 */#ifdef B150case (150): return B150;#endif /* B150 */#ifdef B200case (200): return B200;#endif /* B200 */#ifdef B300case (300): return B300;#endif /* B300 */#ifdef B600case (600): return B600;#endif /* B600 */#ifdef B1200case (1200): return B1200;#endif /* B1200 */#ifdef B1800case (1800): return B1800;#endif /* B1800 */#ifdef B2400case (2400): return B2400;#endif /* B2400 */#ifdef B4800case (4800): return B4800;#endif /* B4800 */#ifdef B9600case (9600): return B9600;#endif /* B9600 */#ifdef B19200case (19200): return B19200;#endif /* B19200 */#ifdef B38400case (38400): return B38400;#endif /* B38400 */#ifdef B57600case (57600): return B57600;#endif /* B57600 */#ifdef B115200case (115200): return B115200;#endif /* B115200 */#ifdef B230400case (230400): return B230400;#endif /* B230400 */#ifdef B345600case (345600): return B345600;#endif /* B345600 */#ifdef B460800case (460800): return B460800;#endif /* B460800 */#ifdef B500000case (500000): return B500000;#endif /* B500000 */#ifdef B576000case (576000): return B576000;#endif /* B576000 */#ifdef B921600case (921600): return B921600;#endif /* B921600 */#ifdef B1000000case (1000000): return B1000000;#endif /* B1000000 */#ifdef B1152000case (1152000): return B1152000;#endif /* B1152000 */#ifdef B1500000case (1500000): return B1500000;#endif /* B1500000 */#ifdef B2000000case (2000000): return B2000000;#endif /* B2000000 */#ifdef B2500000case (2500000): return B2500000;#endif /* B2500000 */#ifdef B3000000case (3000000): return B3000000;#endif /* B3000000 */#ifdef B3500000case (3500000): return B3500000;#endif /* B3500000 */#ifdef B4000000case (4000000): return B4000000;#endif /* B4000000 */default:return -1;}}}bool Uart::setMode(const Mode &mode){if (fd_.get() < 0) {LogErr("please open first");return false;}int baud = Baudrate2Enum(mode.baudrate);if (baud == -1) {LogErr("baudrate %d not support", mode.baudrate);return false;}struct termios options;if (tcgetattr(fd_.get(), &options) == -1) {LogErr("tcgetattr fail, errno:%d", errno);return false;}options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IUCLC | IXON | IXANY | IXOFF);options.c_iflag |= IGNBRK | IGNPAR;options.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);options.c_cflag &= ~(CRTSCTS);options.c_cflag |= CREAD | HUPCL | CLOCAL;options.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);options.c_cflag &= ~CSIZE;if (mode.data_bit == DataBit::k8bits)options.c_cflag |= CS8;elseoptions.c_cflag |= CS7;options.c_cflag &= ~PARENB;options.c_iflag &= ~(INPCK | ISTRIP);if (mode.parity != ParityEnd::kNoEnd) {options.c_cflag |= PARENB;options.c_iflag |= (INPCK | ISTRIP);if (mode.parity == ParityEnd::kOddEnd)options.c_cflag |= PARODD;elseoptions.c_cflag &= ~PARODD;}if (mode.stop_bit == StopBit::k1bits)options.c_cflag &= ~CSTOPB;elseoptions.c_cflag |= CSTOPB;cfsetispeed(&options, baud);cfsetospeed(&options, baud);if (tcsetattr(fd_.get(), TCSAFLUSH, &options) == -1) {LogErr("tcsetattr fail, errno:%d", errno);return false;}return true;}//! 解析如:"115200 8n1" 这样的字串bool Uart::setMode(const std::string &mode_str){using namespace std;if (mode_str.empty()) {LogErr("mode_str is empty");return false;}size_t pos = mode_str.find_first_of(' ', 0);if ((pos == string::npos) || ((pos + 4) < mode_str.size())) {LogErr("mode_str format invalid");return false;}//! 提取各字段string baudrate_str = mode_str.substr(0, pos);char data_bits_ch = mode_str[pos + 1];char parity_ch = toupper(mode_str[pos + 2]);char stop_bits_ch = mode_str[pos + 3];Mode mode;//! 波特率if (!util::StringTo(baudrate_str, mode.baudrate)) {LogErr("baudrate must be number");return false;}//! 数据位if (data_bits_ch == '8')mode.data_bit = DataBit::k8bits;else if (data_bits_ch == '7')mode.data_bit = DataBit::k7bits;else {LogErr("unsupport databit %c", data_bits_ch);return false;}//! 奇偶校验位if (parity_ch == 'N')mode.parity = ParityEnd::kNoEnd;else if (parity_ch == 'O')mode.parity = ParityEnd::kOddEnd;else if (parity_ch == 'E')mode.parity = ParityEnd::kEvenEnd;else {LogErr("unsupport parity %c", parity_ch);return false;}//! 停止位if (stop_bits_ch == '1')mode.stop_bit = StopBit::k1bits;else if (stop_bits_ch == '2')mode.stop_bit = StopBit::k2bits;else {LogErr("unsupport stopbit %c", stop_bits_ch);return false;}return setMode(mode);}void Uart::setReceiveCallback(const ReceiveCallback &cb, size_t threshold){buff_fd_.setReceiveCallback(cb, threshold);}void Uart::setSendCompleteCallback(const SendCompleteCallback &cb){buff_fd_.setSendCompleteCallback(cb);}bool Uart::send(const void *data_ptr, size_t data_size){return buff_fd_.send(data_ptr, data_size);}void Uart::bind(ByteStream *receiver){buff_fd_.bind(receiver);}void Uart::unbind(){buff_fd_.unbind();}Buffer* Uart::getReceiveBuffer(){return buff_fd_.getReceiveBuffer();}bool Uart::enable(){if (fd_.isNull()) {LogErr("please initialize first");return false;}return buff_fd_.enable();}bool Uart::disable(){if (fd_.isNull()) {LogErr("please initialize first");return false;}return buff_fd_.disable();}bool Uart::openDevice(const std::string &dev){Fd fd = Fd::Open(dev.c_str(), O_RDWR | O_NOCTTY);if (fd.isNull()) {LogErr("Uart open fail");return false;}fd_ = std::move(fd);return buff_fd_.initialize(fd_);}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型