2012-12-15 48 views
0

我有一個從串口讀取和寫入的程序。我有讀取器線程讀取數據並將信息提供給共享內存。閱讀器線程應該休眠直到數據可用。所以我想讓read()系統調用阻塞調用線程。考慮到手冊頁,除非您提供O_NONBLOCKopen,否則read應始終阻止。但我有一個活動的線程,它在read不斷返回-1。同時更改VTIMEVMIN沒有什麼區別。這是口的打開方式:強制讀取系統調用塊

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 
    } 
} 

回答

2

幾件事情需要考慮。

首先,閱讀可以返回的原因有很多。任何類型的中斷都會導致讀解除阻塞並返回-1,這也可能是文件的問題。查看errno變量以獲取更多關於它返回-1的原因。可能的錯誤值的描述如下:read man page

第二,在解決了上述問題後,當數據可用時,讀取不能保證在一次讀取中爲您提供整個網絡數據包,因此您可能需要重新組合多次讀取。

+0

感謝您的回覆。我用'perror'測試,結果是'無效參數' –

+0

這意味着'fd'不是一個有效的文件描述符。 – Barmar

+0

...和errno是'EBUSY(16)' –