2016-08-10 11 views
0

Cで2つのシリアルポートを接続/ブリッジしたいです。 2つのスレッドがポートを読み取り、もう一方のポートに書き込みます。Cで2つのシリアルポートを接続

void *rfid_to_uart_thread(void *) { 
char rfid_read_buffer[100]; 
int writeCounter; 
do { 
    writeCounter = read(rfidCom, rfid_read_buffer, sizeof(rfid_read_buffer)-1); 
    if (writeCounter > 0) { 
     write(uartCom, rfid_read_buffer, writeCounter); 
    } else 
     usleep(25); 



} while (!bKillBridgeThreads); 

return NULL;} 

問題があり、書き込みが遅すぎるようだ: は、ここでは一例です。私はしばしば反対側のStringの半分しか受け取らない。書き込みが非同期的で、バッファが次のループで再び上書きされ、最後の '書き込み'が上書きされるため、データが無効になるようです。 そうですか?

ポートがNON_BLOCKINGを開かれ、RW、ボーレートがあるとmanを見ると9600

+0

、あなたは2つのスレッド、スレッドの1つのポートと2つのCOMポートを持っています。スレッドはCOMポートまたは共通のポートに書き込みますか? – Raskayu

+0

指定したコードは、あるポート(rfidcom)から読み込み、他のポート(uartCom)に書き込もうとしているシングルスレッドです。だからスレッド内でコードは連続している。したがって、書き込みは非同期ではありません。 readは、rfidデバイスから読み込みが完了すると(100バイト以下)実行されます。バッファサイズが読み込みに与える影響は小さいのでしょうか? –

+0

申し訳ありませんが、質問が誤解を招く可能性があります。読んで受け取ったものだけを書くために「書く」のはいいです。 UART側では、すなわち、RFIDモジュールの出力を監視しているTeraTermを有しており、それはUARTに送信されなければならない。時々私はUART "2FEF0000"を介して受信し、次に "2FEF00001000 \ r"を取得します。だから、おそらく問題は書き込みがバッファリングされているすべてのことを書いていないようなものですか?バッファにすべての文字を強制的に書き込む方法はありますか? – Tobi

答えて

0

なければならない:

読み取り()数までを読むための試みファイル記述子fdからbufで始まるバッファへのバイト数。助成金は、他のタスクによって送信するすべてのバイトを返すようにしないreadつまり

、あなたは何ができるかsizeof(rfid_read_buffer)-1

にあなたにシングルバイトまでを与えることができますすることです:からの読み取り

  1. ループrfidComは、送信された文字の数と一致するまでです。
  2. メッセージの特定のターミネータを使用して、受信したメッセージを検証するためにチェックすることができます。
  3. メッセージの長さを埋め込んだヘッダーを含むプロトコルメッセージにcharをカプセル化することで、受信者は受信した文字をカウントし、 charが受信されます。たとえば、

void *rfid_to_uart_thread(void *) 
{ 
    char rfid_read_buffer[100] = {0}; 

    int writeCounter; 
    char RXchar; 
    ssize_t retVal; 
    bool send = false; 

    do 
    { 
     memset(rfid_read_buffer, 0x00, sizeof(rfid_read_buffer)); 
     send = true; 

     do 
     { 
      retVal = read(rfidCom, &RXchar, 1); 

      if (retVal > 0) 
      { 
       rfid_read_buffer[writeCounter] = RXchar; 

       writeCounter++; 
      } 
      else if (retVal < 0) 
      { 
       send = false; 
       RXchar = '\r' 
       break; 
      } 
      else 
      { 
       usleep(25); 
      } 
     } 
     while(RXchar != '\r'); 


     if (send) 
     { 
      write(uartCom, rfid_read_buffer, writeCounter); 
     } 
    } 
    while (!bKillBridgeThreads); 

    return NULL; 
} 
+0

@sawdust trueを参照してください。それは概念をより良く説明するための単なる例です。あなたは効率的なコードを答えとして投稿することは自由です;) – LPs

0

OK、私は私が考える私の問題への解決策を見つけました。

void *rfid_to_uart_thread(void *) { 
char rfid_read_buffer[10]; 
ssize_t writeCounter = -1; 

do { 
    writeCounter = read(rfidCom, &rfid_read_buffer, sizeof(rfid_read_buffer)-1); 
    if (writeCounter>0){ 
     rfid_read_buffer[writeCounter] = 0; 
     LOGE("RFID -> UART: %s", rfid_read_buffer); 
     write(uartCom, rfid_read_buffer, writeCounter); 
    }else{ 
     usleep(25); 
    } 
    tcdrain(uartCom); 
} while (!bKillBridgeThreads); 

return NULL;} 

私が使用しているAndroidのNDKは今termios.h でそれを提供されていないため、すべての値がUARTポートに送信し得るように見える、tcdrainのために定義し、私自身を作成し​​ました。

tcdrainが今のように定義されます。だから、

#define tcdrain(fd) ioctl(fd, TCSBRK, 1) 
+0

ioctlが壊れた文字を送信する方法が、送信バッファが空になるまで待つioctlになったことを本当に知りたいと思います。 – rjp

関連する問題