2009-11-18 2 views
6

を失敗:シリアルポートからの読み出しは、私は次のCプログラムを持っている

#include <fcntl.h> 
#include <termios.h> 
#include <stdio.h> 

int main() 
{ 
    int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); 
    if(fd < 0) 
    { 
     perror("Could not open device"); 
    } 
    printf("Device opened\n"); 

    struct termios options; 
    tcgetattr(fd, &options); 
    cfmakeraw(&options); 
    cfsetispeed(&options, B19200); 
    cfsetospeed(&options, B19200); 
    tcsetattr(fd, TCSANOW, &options); 

    char txpacket[] = {0x23, 0x06, 0x00, 0x00, 0xdd, 0xf9}; 
    ssize_t written = write(fd, txpacket, sizeof(txpacket)); 
    printf("Written %d bytes\n", written); 

    printf("Starting to wait for target to respond\n"); 
    while(1) 
    { 
     fd_set readset; 
     FD_ZERO(&readset); 
     FD_SET(fd, &readset); 
     int nCount = select(fd + 1, &readset, NULL, NULL, NULL); 
     if(nCount > 0) 
     { 
      if(FD_ISSET(fd, &readset)) 
      { 
       int i; 
       char buffer[128]; 
       ssize_t bytesread = read(fd, buffer, sizeof(buffer)); 
       printf("Received %d bytes\n", bytesread); 
       for(i = 0; i < bytesread; i++) 
       { 
        printf(" %02x", buffer[i]); 
       } 
      } 
     } 
    } 
} 

このプログラムは、シリアルデバイス/ dev/ttyS0のを開いて、そこにデータのシーケンスを書き込み、応答のためのリスニングを開始します。私は次の出力を得ます:

Device opened 
Written 6 bytes 
Starting to wait for target to respond 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
... 

そしてアプリケーションは100%CPUを消費します。ターゲットハードウェアが実際にそれを送信しても、私はデータを受け取ることができません。

どうしたのですか?

答えて

7

read()戻り値0はファイルの終わりの状態を示します。そのことをチェックし、ループが発生した場合はそれを抜け出す必要があります。

シリアルポートのファイルの終わりは、ハングアップを検出したことを示しています。つまり、DCD回線が切断されたことを示しています。

options.c_cflagCLOCALフラグを設定して、デバイスが正しく設定していない場合は、モデム制御回線を無視することができます。

+0

ありがとう!それは確かに問題を引き起こしていたものでした。 – anorm

+0

くそー、CLOCALのことは見ませんでした! – shodanex

+0

同じ問題があった、チップのおかげで。 cfmakerawがその2つの明白なフラグを見ていないことを理解していない。 – RishiD

1

O_NONBLOCKフラグを付けずに試してください。データが利用可能である場合 数より少ないと、直ちに戻り を読み取り、

c_cc[VMIN]c_cc[VTIME]の設定値が0の場合、rawモードでは、シリアルポートは、この(男cfmakerawに応じて)のように振る舞います利用可能なバイトの数、または要求されたバイト数の です。何のデータ が利用できない場合は、0を返します

を読むそれでは、あなたは試してみてくださいすることです:

options->c_cc[VMIN]=1; 
+0

奇妙なコーナーケースで本当に良いメモ。 – Joe

関連する問題