0

シリアルポートからの読み取りとシリアルポートへの書き込みを行うプログラムがあります。データを読み取り、共有メモリに情報を提供するリーダースレッドがあります。リーダースレッドは、データが利用可能になるまでスリープする必要があります。read()だから私は呼び出しスレッドをブロックするためにシステムコールを作りたいです。O_NONBLOCKに提供しない限り、manページを考慮するとopenread常にブロックする必要があります。しかし、私にはアクティブなスレッドがあり、その中に継続的にread戻ります。-1また、変更し、違いはVTIMEありVMINません。これは、ポートが開かれる方法です。

fd = open(portName.str().c_str()/*/dev/ttyS2*/, O_RDWR | O_NOCTTY);
    if (fd < 0) // if open is not successful
    {
        cerr << ERROR << "Unable to open `" << portName << "'." << endl;
        return false;
    }
    else
    {
        cout << INFO << "Port " << portName.str() << " successfully opened."
                << endl;
        cout << INFO << "Configuring port..." << endl;
        fcntl(fd, F_SETFL,0);
        struct termios port_settings; // structure to store the port settings in
        cfsetispeed(&port_settings, B38400); // set baud rate
        cfsetospeed(&port_settings, B38400); // set baud rate
        port_settings.c_cflag |= CLOCAL | CREAD;
        port_settings.c_cflag &= ~CRTSCTS; // disable H/W flow control
        port_settings.c_lflag &= ~( ISIG | // disable SIGxxxx signals
                IEXTEN | // disable extended functions
                ECHO | ECHOE); // disable all auto-echo functions
        port_settings.c_lflag &= ~ICANON ; // raw mode
        port_settings.c_oflag &= ~OPOST; // raw output
        port_settings.c_iflag &= ~(IXON | IXOFF | IXANY); // disable S/W flow control;
            // Following values do not change timout in runtime:
        port_settings.c_cc[VTIME] = 2; // wait 0.2 second to get data - 
        port_settings.c_cc[VMIN] = 0;

        port_settings.c_cflag = (port_settings.c_cflag &= ~CSIZE) | CS8; // set data byte size
        port_settings.c_cflag &= ~CSTOPB; // set stop bit 1
        port_settings.c_cflag &= ~PARENB; // set no parity
        port_settings.c_iflag |= IGNPAR; // ignore parity
        port_settings.c_iflag &= ~(INPCK | ISTRIP | PARMRK);

        // Set
        if (tcsetattr(fd, TCSANOW, &port_settings) < 0)
        {
            cerr << ERROR << "Unable to configure serial port." << endl;
            return false;
        }
        else
        {
            cout << INFO << "Port `" << portName.str()
                    << "' configuration was successful." << endl;
        }

そしてリーダースレッドで:

byte buffer[256];
while (true)
{
    int packetSize = read(fd, buffer, 256);
    if (packetSize > 0)
    { 
      // use data - this code is never run 
    }
    else 
    {
       // print error - we're always here. no matter how long timout is
    }
 }
4

1 に答える 1

2

ここで考慮すべきいくつかの事柄。

まず、readはいくつかの理由で戻る可能性があります。あらゆる種類の割り込みにより、読み取りのブロックが解除されて-1が返されます。また、ファイルに問題がある可能性があります。-1を返す理由の詳細については、errno変数を確認してください。考えられるerrno値の説明は、readmanページにあります。

次に、上記を解決した後、データが利用可能な場合、読み取りは1回の読み取りでネットワークパケット全体を提供することが保証されないため、複数の読み取りから再構築する必要がある場合があります。

于 2012-12-15T07:04:34.387 に答える