Linux在c ++中写入串口返回错误的文件描述符

时间:2015-12-31 01:30:41

标签: c++ linux serial-port

我正在编写一个c ++程序,用于从位于/ dev / ttyACM0的设备发送接收数据。我能够从设备中读取没有问题,我可以从命令行写入它,但我无法在我的c ++程序中写入它。以下是我到目前为止的情况:

#include "SerialComms.h"
#include <errno.h>
#include <string.h>
SerialComms::SerialComms() {
    serial_filestream = -1;

    //CONFIGURE THE PORT
    //The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
    //  Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
    //  CSIZE:- CS5, CS6, CS7, CS8
    //  CLOCAL - Ignore modem status lines
    //  CREAD - Enable receiver
    //  IGNPAR = Ignore characters with parity errors
    //  ICRNL - Map CR to NL on input
    //  PARENB - Parity enable
    //  PARODD - Odd parity (else even)
    tcgetattr(serial_filestream, &options);
    options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;     //<Set baud rate
    options.c_iflag = IGNPAR;
    options.c_oflag = 0;
    options.c_lflag = 0;
}

bool SerialComms::Init(string type){
    //The flags (defined in fcntl.h):
    //  Access modes (use 1 of these):
    //      O_RDONLY - Open for reading only.
    //      O_RDWR - Open for reading and writing.
    //      O_WRONLY - Open for writing only.
    //
    //  O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
    //                                          if there is no input immediately available (instead of blocking). Likewise, write requests can also return
    //                                          immediately with a failure status if the output can't be written immediately.
    //
    //  O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
    if (type == "USB"){  //if type equals USB, open USB
        serial_filestream = open(USBSerial, O_RDWR | O_NOCTTY | O_NDELAY);      //Open in non blocking read/write mode
    }else if (type == "UART1"){
        serial_filestream = open(UART1, O_RDWR | O_NOCTTY | O_NDELAY);      //Open in non blocking read/write mode
    }

    if (serial_filestream == -1)
    {
        //ERROR - CAN'T OPEN SERIAL PORT
        printf("Error - Unable to open: %s\n", type.c_str());
    }else{
        printf("Opened serial type: %s\n", type.c_str());
    }
    tcflush(serial_filestream, TCIFLUSH);
    tcsetattr(serial_filestream, TCSANOW, &options);
    printf("Serial Comms for type: %s intialized", type.c_str());
    return 1;
}

bool SerialComms::Ping(){
    WriteSerial("p,1,1;\n");
    return true;
}

 char* SerialComms::ReadSerial(){
    if (serial_filestream != -1)
    {
        // Read up to 255 characters from the port if they are there
        char rx_buffer[256];
        int rx_length = read(serial_filestream, (void*)rx_buffer, 255);     //Filestream, buffer to store in, number of bytes to read (max)
        if (rx_length < 0)
        {
            //An error occured (will occur if there are no bytes)
        }
        else if (rx_length == 0)
        {
            //No data waiting
        }
        else
        {
            //Bytes received
            rx_buffer[rx_length] = '\0';
            int j = 0;
            while (rx_buffer[j] != ';' && rx_buffer[j] != '\0' && rx_buffer[j] != '\n'){
                j++;
            }
            char rx_return[j+1];
            for(int i = 0; i < j+1; i++){
                rx_return[i] = rx_buffer[i];
            }
            rx_return[j+1] = '\0';
            return rx_return;
        }
    }
    return '\0';
}

bool SerialComms::WriteSerial(string data_out){
    const char * tx_buffer = data_out.c_str();
    if (serial_filestream != -1)
    {
        int wr = write(serial_filestream, tx_buffer, strlen(tx_buffer));
        if (wr < 0){
            printf("Error writing to Serial: %s \n", strerror(errno));
            return 0;
        } else{
            printf("WroteSerial: %s, %d \n", tx_buffer, strlen(tx_buffer));
            return 1;
        }
    }else{
        printf("Error writing to Serial filestream errors \n");
        return 0;
    }
    return 1;
}
SerialComms::~SerialComms() {
    close(serial_filestream);
}

如果我使用命令:

echo "p,1,1;\n" > /dev/ttyACM0

它没有问题,我收到了串行设备的预期数据。

但是,我在c ++程序中的主循环每分钟调用一次WriteSerial函数:

void Ping(SerialComms serialLine){
    serialLine.WriteSerial("p,1,1;\n");
    printf("pinged at: %s \n", ctime(&now));
}

第一次执行写入时,它不会给出错误,但它似乎不起作用,第二次写入会返回错误的文件描述符错误。此外,它也搞砸了从端口读取。这是我的程序输出:

WroteSerial: p,1,1;
, 7 
pinged at: Wed Dec 30 19:08:05 2015

Error writing to Serial: Bad file descriptor 
pinged at: Wed Dec 30 19:09:06 2015

我真的不确定从哪里开始所以任何建议都会受到赞赏。我很确定我错过了一些基本的东西,但我现在看不到它。

0 个答案:

没有答案