在自己的线程中从ttyUSB0读取

时间:2012-12-10 13:16:19

标签: c++ serial-port posix blocking ftdi

我在使用C ++从ttyUSB0读取数据时遇到问题。我有一个自己的线程从ttyUSB0以阻塞模式读取数据。当我只读取单个字符时,数据到达固定块(不是很好的机器人)。这可能是我的USB到UART转换器上的FTDI芯片的一些内部缓冲区。但是如果尝试读取的不仅仅是单个字符,我只会收到零块。 read或init命令没有错误。有没有人知道如何解决这个问题。

发送:dfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfsfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf

接收:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

这是我的代码。

void BoardCommunicator::execute()
{
    connection.openCon();
    uint8_t buffer[16] = {0};
    while(true)
    {
    //  unsigned char b = connection.readByte();
        if(connection.readBlock(buffer,16) == 0)
            std::cout << "EOF" << std::endl;
        else
            for(uint32_t i = 0; i < 16; i++)
                std::cout << (int)buffer[i] << " ";
        std::cout << std::endl;
    }
}

void SerialConnection::openCon()  throw (SerialPortOpenException&)
{
    conHandler = open(udevFileName , O_RDWR | O_NOCTTY);// | O_NDELAY | O_NONBLOCK);
    if (conHandler < 0) 
        throw SerialPortOpenException("Can not open given comport");

    cfsetispeed(&port_settings, B2000000);    // set baud rates
    port_settings.c_cflag = B2000000 | CS8 | CREAD | CLOCAL;
    port_settings.c_iflag = IGNPAR;
    port_settings.c_oflag = 0;
    port_settings.c_lflag = 0;
    if(tcsetattr(conHandler, TCSANOW, &port_settings) < 0)
        throw SerialPortOpenException("Was not able to aply settings to serail link.");// apply the settings to the port
}
//Does not work at all. Receives only zeros! Why? 
int SerialConnection::readBlock(uint8_t* buffer, uint32_t size)
{
    if(buffer == NULL)
        throw IllegalArgumentException("Can not read a block to null buffer");

    for(uint32_t index = 0; index < size; index++)
        buffer[index] = 0;
    int result;
    do{
        result = read(conHandler, &buffer, size);
    } while (errno == EINTR );
    if(result < 0)
        throw ReadBlockException("Can not read from serial link.");
        return result;
}
//Works only in blocking mode and data arrives in fixed sized blocks
uint8_t SerialConnection::readByte() const throw (ReadByteException&)
{
    int result = 0;
    uint8_t data = 0;
    do //Check if read waked up by any signal
    {
        result = read(conHandler, &data, 1);
    } while (errno == EINTR || errno == 11);
    std::cout << errno <<std::endl;
    if(result < 0)
        throw ReadByteException("Can not read from serial link.");
    return data;
}

如果有人对这些东西有一些经验,那会很好。 感谢

1 个答案:

答案 0 :(得分:1)

你有两个错误。

首先,这段代码:

    result = read(conHandler, &buffer, size);

您读入存储缓冲区地址的位置而不是缓冲区本身。

其次,你抛出read的结果,所以你不知道你读了多少字节。如果代码旨在读取完全 size字节,则需要执行以下操作:

    int total_read = 0;
    do
    {
        result = read(conHandle, buffer + total_read, size - total_read);
        if (result <= 0) return result;
        total_read += result;
    }
    while (total_read < result);