Пример #1
0
Serial::Serial(const char * device_name, unsigned long baud_rate)
{
  struct termios options;
  std::cout << ">> starting Serial::Serial(.)" << std::endl;
  fd = open(device_name, O_RDWR | O_NOCTTY | O_NDELAY);
  if(fd == -1)
    throw SerialException("Could not open serial device.\n", errno);
  std::cout << " -- serial device is open, fd: " << fd << std::endl;

  fcntl(fd, F_SETFL, 0); // blocking
  std::cout << " -- blocking" << std::endl;
  tcgetattr(fd, &options); // get the current options // TODO: restore on destruction of the object
  std::cout << " -- got the current options" << std::endl;

  tcgetattr(fd, &options);
  options.c_cflag=B57600;
  tcsetattr(fd, TCSANOW, &options);
  std::cout << " -- set baud rate uart0_filestream" << std::endl;

#ifndef __APPLE__
  if(cfsetispeed(&options, B57600) != 0)
    throw SerialException("Could not set baud rate for input", errno);
  std::cout << " -- set baud rate for input" << std::endl;
  if(cfsetospeed(&options, B57600) != 0)
    throw SerialException("Could not set baud rate for output", errno);
  std::cout << " -- set baud rate for output" << std::endl;
#endif

  options.c_cflag |= (CS8 | CLOCAL | CREAD);
  options.c_iflag = IGNPAR;
  options.c_oflag = 0;
  options.c_lflag = 0;
  options.c_cc[VMIN]  = 0;
  options.c_cc[VTIME] = 1;    // tenth of seconds allowed between bytes of serial data
  // but since VMIN = 0 we will wait at most 1/10 s for data then return
  tcflush(fd, TCIOFLUSH);
  tcsetattr(fd, TCSANOW, &options);   // set the options

#ifdef __APPLE__
  cfmakeraw(&options); // necessary for ioctl to function; must come after setattr
  const speed_t TGTBAUD = baud_rate;
  int ret = ioctl(fd, IOSSIOSPEED, &TGTBAUD); // sets also non-standard baud rates
  if (ret)
    throw SerialException("Could not set baud rate", errno);
  std::cout << " -- set baud rate for output" << std::endl;
#endif
}
Пример #2
0
size_t Serial::read(char* data, size_t length) {
    waitForData();
    logger.debug(MODULE, "Reading data");
    ssize_t br = ::read(fd, data, length);
    logger.debug(MODULE, "Read %u bytes", br);
    if (br == -1) {
        throw SerialException("Could not read data");
    }
    return br;
}
Пример #3
0
void Serial::waitToWrite() {
    fd_set writeset;
    int result;

    logger.debug(MODULE, "Waiting to write");

    do {
        FD_ZERO(&writeset);
        FD_SET(fd, &writeset);
        timeval timeout = {0, 100};
        result = select(fd + 1, nullptr, &writeset, nullptr, &timeout);
    } while (result == 0 && !abortFlag);

    if (abortFlag) {
        throw SerialException("Aborted by client request");
    }

    if (result < 0) {
        throw SerialException("Lost serial connection during select");
    }
}
Пример #4
0
Serial::Serial(const std::string& device, Logger& logger) : logger(logger), abortFlag(false) {
    fd = open(device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);

    if (-1 == fd) {
        throw SerialException("Could not open device");
    }

    if (!isatty(fd)) {
        close(fd);
        throw SerialException("Specified device is not a TTY");
    }

    termios termAttr;
    if (-1 == tcgetattr(fd, &termAttr)) {
        close(fd);
        throw SerialException("Could not get device attributes");
    }

    termAttr.c_cc[VTIME] = 0;
    termAttr.c_cc[VMIN] = 0;

    termAttr.c_iflag = 0;
    termAttr.c_oflag = 0;
    termAttr.c_cflag = CS8 | CREAD | CLOCAL;
    termAttr.c_lflag = 0;

    if (0 > cfsetispeed(&termAttr, B115200) ||
        0 > cfsetospeed(&termAttr, B115200)) {

        close(fd);
        throw SerialException("Could not set device baud rate");
    }

    if (-1 == tcsetattr(fd, TCSAFLUSH, &termAttr)) {
        close(fd);
        throw SerialException("Could not set device attributes");
    }
}
Пример #5
0
void Serial::write(const char* data, size_t length) {
    ssize_t bw = 0;
    logger.debug(MODULE, "Writing %u bytes", length);
    while (length > 0) {
        waitToWrite();
        bw  = ::write(fd, data, length);
        if (-1 == bw) {
            throw SerialException("Could not write data");
        }

        length -= bw;
        data += bw;
    }
}
Пример #6
0
void Serial::waitForData() {
    fd_set readset;
    int result;

    logger.debug(MODULE, "Waiting for data");

    do {
        FD_ZERO(&readset);
        FD_SET(fd, &readset);
        timeval timeout = {0, 100};
        result = select(fd + 1, &readset, nullptr, nullptr, &timeout);
    } while (result == 0 && !abortFlag);

    logger.debug(MODULE, "Got some data? %d %d %s", result, errno, abortFlag ? "true" : "false");

    if (abortFlag) {
        throw SerialException("Aborted by client request");
    }

    if (result < 0) {
        throw SerialException("Lost serial connection during select");
    }
}