uart termios APIのVTIME間隔を減らすためにカーネルをパッチする方法は?

uart termios APIのVTIME間隔を減らすためにカーネルをパッチする方法は?

文字間のギャップを減らすために、tty termios APIから100ms未満のVTIMEを取得するには、カーネルパッチを見つけるのに役立ちます。 VTIMEがタイムアウトするまで読み取りシステム呼び出しをブロックします。

n_tty_read() 関数はパッチエントリポイントです。 https://elixir.bootlin.com/linux/latest/source/drivers/tty/n_tty.c#L2131

パッチが必要なソースコード

誰でも私にアドバイスを与えることができますか?非正規モード(フレームプロトコルなし、ASCIIなし、割り込みなし)を使用する必要があります。すべてのメッセージ長が可変であるため、VMINパラメーターは空です。すべての文字をポーリングするソリューションは、複数のuartシステムに比べて高価であり、複数のプロセスコンテキスト切り替えを意味します。

用語抽出ガイド:VTIMEタイムアウト10分の1秒非正規読み取りの場合(時間)。https://man7.org/linux/man-pages/man3/termios.3.html

Linuxカーネルパッチが必要です。または、グローバルHZを小さい値に設定しますか?

Microsoft WindowsシリアルAPIは1msで設定できますが、Linuxは設定できません。したがって、Windows はネイティブシリアルポートの処理に適しています。 読み取り間隔のタイムアウト:https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddser/ns-ntddser-_serial_timeouts

非正規モードでは、読み取りバッファは4095文字のみを受け入れます。

レビューからの抜粋「非標準モードで...4095文字のみ許可されています。「私の考えにはここに問題があるようです。おそらくread_waitキューが目覚めない理由です。

https://elixir.bootlin.com/linux/latest/source/drivers/tty/n_tty.c#L1667

ベストアンサー1

tty termios APIから100ms未満のVTIMEを取得するには、カーネルパッチを見つけるのに役立ちます。

Linuxカーネルパッチが必要です...

これらのカーネルパッチはユーザー空間APIを変更するので賢明ではありません。 Linuxは一貫したAPIを維持しようとし、要求されたパッチによって既存のアプリケーションがクラッシュする可能性があります。

これらのカーネルパッチがAPIを変更しなくても、信頼性が低く、明示されていない目標を達成する可能性はありません。時間で区切られたメッセージを検出するために、VMINおよびVTIME設定にのみ依存する必要はありません。

UARTがFIFOを使用して着信データをバッファリングすると、ハードウェアバッファはソフトウェアが検出できる文字間隔をマスクします。同様に、UARTドライバがDMAを使用して受信したデータを保存すると、文字間タイミングがマスクされます。

termios は、UART デバイスドライバの上の少なくとも全体のレイヤーを処理します。 termios レイヤーは、UART とそのドライバーがバイトを処理/バッファした後、ライン上で同じタイミング情報を見ることはできません。


Microsoft WindowsシリアルAPIは1msで設定できますが、Linuxは設定できません。したがって、Windows はネイティブシリアルポートの処理に適しています。

Windowsがアプリケーションに適していると思われる場合は、Windowsを使用する必要があります。ただし、広告されたコンテンツが必ずしもあなたが得るものではないことに注意してください。 Windows APIはただ開示するタイムアウト仕様(ミリ秒)正確。だからといって、実際にこのようなものが得られるという意味ではありません。正確さ。たとえば、次の警告があります。

タイムアウト間隔はシステムクロックに基づいて測定されます。タイムアウト測定の精度は、システムクロックの粒度によって制限されます。。したがって、指定されたタイムアウト間隔より速い1つのシステムクロック周期と1つのシステムクロック周期の間でタイムアウトが発生する可能性があります。、システムクロックサイクル間の間隔の開始時間と終了時間が正確にどこに属するかによって異なります。後でタイムアウトが発生する可能性があります。他装置の割り込み処理によりシステムクロック割り込み処理が遅れる場合。指定されたタイムアウト間隔がシステムクロックティック間の期間に近いか短い場合タイムアウトは遅延なしですぐに発生する可能性があります。


私の考えの問題はここにあるようです。おそらくこれがread_waitキューが目覚めない理由です。

いいえ、あなたは間違った場所を見つけようとします。
私が以前に申し上げようとしていたように(参考としてこの投稿)、安定したソリューションにはアイドルUART受信機を検出するタイマーが必要です。ただし、UARTハードウェアがリスナータイムアウトを実装していても(私が検討した2つのLinuxドライバでは)、この機能は現在/アクティブDMA操作を中断するためにのみ使用されます。

受信機のタイムアウトは時間分離メッセージの終わりを検出する可能性があるため、UARTドライバが受信したデータを転送するときにこのイベント/情報をtermios層に転送する必要があります。これはVMIN > 0、元のモードの新しいバリエーションについてtermiosに必要な欠落情報ですVTIME > 0。この新しいバリエーションでは、UARTドライバはtermiosが文字間タイムアウトを確認するのではなく、受信したデータでタイムアウトイベントを表示する必要があります。
これは単なるカーネルパッチではありません。

おすすめ記事