2011-01-12 8 views
7

PXA270 RISC PC/104のRS232通信で長時間の遅延(1.5ms〜9.5ms)が発生しています。私は長い遅延を最小限に抑えたいのですが、私は組込みデバイスとC++の初心者ですので、何か不足していると思います。PXA270でのRS232通信の遅延が大きい

上記の遅延は、PXAボードがRS232(115200ボー)を介して外部デバイスからパケットを受信し、ACKカスタムパケットを外部デバイスに送り返すまでの遅延です。 オシロスコープでPXAボードの遅延を測定しました.1つはRxに、もう1つはTxにあります。

PXAボードでは、Arcom Embedded Linux(AEL)が実行されています。私はそれがリアルタイムOSではないことを知っていますが、私はまだ考えています。平均遅延が4.5msであると考えています高すぎます受信パケットを抽出し、CRC16であることを確認し、ACKパケット(CRC付き)シリアル回線を元に戻します。 私は故意にCPUを重い負荷(いくつかの並列gzip操作)に置いていましたが、遅延時間はまったく増えませんでした。 受信パケットの最大サイズは30バイトです。

C++アプリケーション(別の以前の同僚が書いています)は、パケットの受信とその肯定応答を処理しています。 1つのスレッドが送信中で、もう1つがパケットを受信して​​います。

私は、PXAボード上のRTCが非常に悪い解像度を持ち、AELがタイミングを内部RTC解像度に合わせることができないと考えました。しかし、RTCの周波数は32.768kHzです。解像度は十分ですが、依然として高い遅延を説明していません。 Btw、私はOSは、タイミングのためのRTCではなく、内部PXAクロック(十分な解像度を持っている)を使用していると思う。

したがって、問題はC++アプリケーションまたはRS232インターフェイスのドライバ/ OS設定にある必要があります。

次の制御フラグは、Serial Programming Guide for POSIX Operating SystemsによるC++アプリケーションでのRS232通信に使用されています

// Open RS232 on COM1 
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY); 
// Force read call to block if no data available 
int f = fcntl(mPhysicalComPort, F_GETFL, 0); 
f &= ~O_NONBLOCK; 
fcntl(mPhysicalComPort, F_SETFL, f); 
// Get the current options for the port... 
tcgetattr(mPhysicalComPort, &options); 
// ... and set them to the desired values 
cfsetispeed(&options, baudRate); 
cfsetospeed(&options, baudRate); 
// no parity (8N1) 
options.c_cflag &= ~PARENB; 
options.c_cflag &= ~CSTOPB; 
options.c_cflag &= ~CSIZE; 
options.c_cflag |= CS8; 
// disable hardware flow control 
options.c_cflag &= ~CRTSCTS; 
// raw input 
options.c_lflag = 0; 
// disable software flow control 
options.c_iflag = 0; 
// raw output 
options.c_oflag = 0; 
// Set byte times 
options.c_cc[VMIN] = 1; 
options.c_cc[VTIME] = 0; 
// Set the new options for the port 
tcsetattr(mPhysicalComPort, TCSAFLUSH, &options); 
// Flush to put settings to work 
tcflush(mPhysicalComPort, TCIOFLUSH); 

私は、私は非常に単純な何かが欠けていると思います。私は、アプリケーションのプロセスがより優先度の高い状態で実行されている場合、問題は解決しないと考えています。 RS232ドライバにレイテンシを最小限に抑えるために優先順位の高い要求を処理するよう指示するものがなければなりません。

誰にもアイデアはありますか?ご協力いただきありがとうございます。

+0

を\ nが入力されているか、バッファがいっぱいですか?あなたのタイミングを推測することができる、シリアルドライバの上にいくつかの端末関連のものがあります。 – Rudi

+0

すべての文字に対して遅延が発生しません。パケット全体(〜30バイト)が受信されると、ACKパケットが返されるまで発生します。 – saxos

+1

1.あなたが待っていて、ポートから読むコードを教えてください。 2.Uptimeの出力を表示する(多分あなたのシステムは過負荷ですか?)3. LinuxにFast Context Switch Extension(lwn.net/images/conf/rtlws11/papers/proc/p01.pdf)がありますか? PXA270はコンテキストスイッチの遅延を0.5ms以下に抑えることができます。 – atzz

答えて

8

ご意見ありがとうございました。

遅延を約0.4msまで減らすことができました。コマンドsetserial(8)は、AELマニュアルで参照されています。そして、ビンゴ、私は以下の説明でありlow_latency旗を見つけた:

は大きい CPU使用率を犠牲にし シリアルデバイスの受信遅延を最小にします。 ( 文字がオーバーヘッドを最小限に抑えるためにライン しつけに渡される前に、通常5-10msの待ち時間の 平均がございます。)この はデフォルトではオフですが、特定の リアルタイム・アプリケーションは、この が役に立つかもしれません。

私はsetserial /dev/ttyS1 low_latencyを実行し、遅延は〜0に減少しました。4msの:-)

しかし、私は(このコマンドは、すべてのディストリビューションに含まれていないデフォルトである)setserialのでグローバルにこのフラグを設定せずに、C++アプリケーションでこの動作を実装したかったです。

私はsetserialのからlow_latencyフラグと同じ効果を持っていた、次のコード行、コメントを追加しました:あなたは、すべてのcharのこれらの遅延を持っていますか、またはがある場合、あなたの入力が来るん

#include <sys/ioctl.h> 
#include <linux/serial.h> 
// Open RS232 on COM1 
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY); 
struct serial_struct serial; 
ioctl(mPhysicalComPort, TIOCGSERIAL, &serial); 
serial.flags |= ASYNC_LOW_LATENCY; // (0x2000) 
ioctl(mPhysicalComPort, TIOCSSERIAL, &serial); 
+0

高いCPU使用率によりレイテンシが低下します:これは、OSが何らかの方法でシリアルポートをポーリングする必要があることを意味しますか? – stijn

+0

私は正確な内部を知らない。 low_latencyフラグを指定すると、データがソフト割り込みよりもはるかに高い優先順位を持つハード割り込みコンテキストでttyレイヤにプッシュされるというものを読んだことがあります。私はすべてのCPU使用率の増加に気づいていない(私のシナリオの場合)。 – saxos

関連する問題