c ++ IOCTL () не обнаруживает доступные байты в дескрипторе файла из последовательной связи - PullRequest
0 голосов
/ 23 октября 2018

Я программирую класс c ++ для последовательной связи между двумя устройствами в моей системе.Одно устройство - это компьютер с Linux, а другое - микроконтроллер (Arduino Uno).Класс используется на компьютере Linux.Класс soo far имеет только функции Begin () и Available ().

Существует проблема с функцией «Available ()», которая должна возвращать количество байтов, доступных для чтения.После того, как я отправил байты с микроконтроллера с командой 'Serial.print ln ("hello world") "(команда из встроенной библиотеки arduino), оператор" serial.Available () "в Linuxкомпьютер вернет число 12. Но когда я пропущу разрыв строки на стороне arduino ('Serial.print ()' вместо 'Serial.println ()'), serial.Available () вернет, что 0 байтов доступны длячтение.

Мое предположение, что я либо неправильно использую оператор 'ioctl ()' внутри функции 'serial.Available ()', либо что есть проблема в настройке последовательного порта в 'serial.Begin ()',Кто-нибудь знает, почему байты не считаются доступными, если я не печатаю разрыв строки на стороне arduino, также с помощью команды Arduino 'Serial.write ()'.

Любой совет будет оценен,

Спасибо

Редактировать: В вики прочитайте, что в используемом мной termios api есть два режима.Канноинкальный и неканонический.Первый будет выполнять построчную обработку, а второй будет возвращать отдельные символы.Но в моем конфиге я уверен, что я деактивировал канонический режим с заявлением:

SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);

serial.h

#ifndef SERIAL_H
#define SERIAL_H

#include <cstdio>
#include <cstdlib>
#include <fcntl.h>                                                      // File control definitions
#include <stdexcept>
#include <string>
#include <sys/ioctl.h>                                                  // Serial Port IO Controls
#include <termios.h>                                                    // POSIX terminal control definitions
#include <unistd.h>                                                     // UNIX standard function definitions

using namespace std;

class Serial
{
    private:
        int fd;                                                         // file descriptor
        int configured;
    public:
        Serial(const char * device);

        ~Serial()
        {
            close(fd);
        };     

        void Begin();
        int Available();                                                // returns the number of bytes that's available for reading
};

#endif

serial.cpp

#include "serial.h"

Serial::Serial(const char * device)
{
    configured = 0;
    fd = open(device,O_RDWR | O_NOCTTY);                                // open serial port (read/write, no terminal control, blocking mode)
    if (fd < 0)
    {
        perror("failed to open serial port");
        exit(EXIT_FAILURE);
    }
}

void Serial::Begin()
{
    struct termios SerialPortSettings;                                  // structure for serial port settings

    tcgetattr(fd, &SerialPortSettings);                                 // paste file descriptor's current settings to structure

    cfsetispeed(&SerialPortSettings,B9600);                             // set input baud rate
    cfsetospeed(&SerialPortSettings,B9600);                             // set output baud rate

    SerialPortSettings.c_cflag &= ~PARENB;                              // disable parity

    SerialPortSettings.c_cflag &= ~CSTOPB;                              // set number of stop bits to 1

    SerialPortSettings.c_cflag &= ~CSIZE;                               // clear the bitmask
    SerialPortSettings.c_cflag |=  CS8;                                 // set the number of data bits to 8 (byte)

    SerialPortSettings.c_cflag |= CREAD | CLOCAL;                       // turn receiver on 
    SerialPortSettings.c_cc[VMIN]  = 10;                                // read 10 characters (8 data bits and a start and stop bit)
    SerialPortSettings.c_cc[VTIME] = 0;                                 // wait indefinitely

    SerialPortSettings.c_cflag &= ~CRTSCTS;                             // disable hardware based flow control
    SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);              // disable software based flow control

    SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);      // set to non-cannonical operation mode

    int result = tcsetattr(fd,TCSANOW,&SerialPortSettings);             // set attribute changes

    if (result != 0)
    {
        close(fd);
        perror("failed to configure serial port");
        exit(EXIT_FAILURE);
    }
    configured = 1;
    Serial::Flush();                                                    // discard rx buffer
}

int Serial::Available()
{
    if (!configured)
    {
        return -1;
    }
    int bytes = 0;
    ioctl(fd, TIOCINQ, &bytes);
    return bytes;
}

main.cpp

#include <iostream>
#include "serial.h"

using namespace std;

int main()
{
    Serial serial = Serial("/dev/ttyUSB8");
    serial.Begin();
    while (true)
    {
        int available = serial.Available();
        cout << available << " bytes available" << endl;
    }
    return 1;
}

код Arduino

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(2000);
  Serial.print("hello world");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...