私はちょうどシリアルポートについての日から苦労しているプロジェクトを始めました。私はすべてのシリアルルーチンを扱い、 "readLine()"と "writeLine()"関数を使ってインターフェイスを与える静的ライブラリを書いた。 スレーブがデータを取得した後にアンワーカーしなかった場合を除いて、すべてが書き込みと読み取りで完璧に機能します(データは私に送り返され、私はそれを読み取ります)。シリアルポートでの読み込みは、ちょうど私が書いたものを返します
私はfdをO_NDELAYで開き、読み込みシステムコールをfcntlで非ブロックとして設定します。
ここでは、そのすぐ隣にある2つのスレッドループがあります。
void *Serial_Port::readLoop(void *param)
{
Serial_Port *sp = static_cast<Serial_Port*>(param);
std::string *line = NULL;
char buffer[128];
while (1)
{
line = new std::string();
while ((line->find("\r\n")) == std::string::npos)
{
usleep(100);
bzero(buffer, 128);
pthread_mutex_lock(sp->getRLock());
if (read(sp->getDescriptor(), buffer, 127) > 0)
*line += buffer;
pthread_mutex_unlock(sp->getRLock());
}
pthread_mutex_lock(sp->getRLock());
sp->getRStack()->push(line->substr(0, line->find("\r\n")));
pthread_mutex_unlock(sp->getRLock());
delete (line);
}
return (param);
}
void *Serial_Port::writeLoop(void *param)
{
Serial_Port *sp = static_cast<Serial_Port*>(param);
std::string *line;
while (1)
{
line = NULL;
pthread_mutex_lock(sp->getWLock());
if (!sp->getWStack()->empty())
{
line = new std::string(sp->getWStack()->front());
sp->getWStack()->pop();
}
pthread_mutex_unlock(sp->getWLock());
if (line != NULL)
{
pthread_mutex_lock(sp->getWLock());
write(sp->getDescriptor(), line->c_str(), line->length());
// fsync(sp->getDescriptor());
pthread_mutex_unlock(sp->getWLock());
}
usleep(100);
}
return (param);
}
私はファイルディスクリプタをフラッシュしようとしましたが、その後にデータを受け取ることができません。重複した不要なデータを取り除くにはどうすればよいですか?
ありがとうございました。
ローカルエコーを無効にしましたか? * "読み込みシステムコールを非ブロックとして設定する" *おそらく悪い考えです。なぜなら、CPUサイクルの遅延とポーリングをもっと無駄にしているように思えるからです。ターミナルから行を読み込むには、http://stackoverflow.com/questions/36586137/stop-on-newline-when-using-read/36588517#36588517 – sawdust
を参照してください。読み込みを非ブロックモードにする必要がありました。何も読まない限りミューテックスをリリースしてください。私は他の代替手段については考えていません – stalker2106