UART通信におけるハードウェアフロー制御のすすめ
UART(Universal Asynchronous Receiver/Transmitter)は、組み込み機器をはじめとした多くの電子機器で用いられるシンプルなシリアル通信手段です。
しかし、その手軽さゆえに 「データの取りこぼし」や「バッファオーバーフロー」といった通信トラブル に悩まされた経験がある方も多いのではないでしょうか?
こうした問題を未然に防ぐ有効な手段のひとつが、ハードウェアフロー制御(Hardware Flow Control) です。
なぜUART通信にフロー制御が必要なのか?
UARTは、送信側と受信側が非同期に動作する通信方式です。つまり、送信側がどんどんデータを送っても、受信側の処理が追いつかない場合があります。このとき、受信バッファがあふれる等の受信機がデータ受け入れ不可の時に送信機が新しいデータを送信してしまうと、データの破損やロストが発生します。
以下のようなケースで問題が起こりやすくなります
- 高速なデータ送信(例:1Mbps以上)
- ソフトウェア処理に遅延があるMCU
- BluetoothやUSB-シリアル変換ICなど、内部バッファが制限されているデバイスとの通信
- 相手機器が一時的に処理を中断する可能性がある場面(スリープ遷移、割込み多発など)
そこで、UARTのデータライン(RX,TX)に加えて、送受信側それぞれの送信許可信号を取り扱うRTS(Request To Send)とCTS(Clear To Send)ピンを加えた通信がハードウェアフロー制御付きのUART通信になります。
RTSとCTSの接続と振る舞い
ノード同士のRTS/CTSの接続について、丁度よい図がSTMicroelectronics社の公開資料に掲載されていたので下図に示します。
STMicroelectronics "STM32WB – USART" 11ページより
https://www.stmcu.jp/wp/wp-content/uploads/files/presentation-ja/STM32WB/33_STM32WB-Peripheral-USART-interface-(USART)_J.pdf
この回路において、各RTS/CTSの方向・機能は以下の表に示すとおりです。
信号線 | 方向 | 機能 |
---|---|---|
RTS | 出力 | 自機の「受信可能」状態を相手に通知 |
CTS | 入力 | 相手の「受信可能」状態を自機が確認 |
通信にあたっては、受信機側のRX回路は、新しいデータを受け入れ可能な状態のときにRTSピンをLowにし、受け入れ不可の場合にはHighにすることで、受信の可否を送信機のCTSピンへ通知します。送信機側のTX回路は、CTSピンの状態を監視することでデータ送信の可否を判断し、CTSピンがLow(=受信機のRTSがLow)のときにデータを送信します。この処理は通常、1バイト単位で行われ、送信側はCTSピンがHigh(=受信機が受信不可)であることを検知すると、CTSピンが再びLowになるまで送信を待機します。
この一連の流れによってUARTのデータ転送を安全かつ確実に行うことができるのです。
図の通りRTS/CTSは、送受信それぞれのTX/RX回路に対して独立して動作するため、片方のラインのみを使用することも可能です。たとえば、USART1のTX回路およびUSART2のRX回路間でRTS/CTSを接続し、片方向のみでハードウェアフロー制御を行うといった使い方ができます。この場合、USART1のRX回路およびUSART2のTX回路間ではハードウェアフロー制御は行われません。
また、UARTペリフェラルにRTS/CTSピンが搭載されていない場合でも、GPIOピンを使用してRTS/CTSの機能をソフトウェアで模倣することは可能です。しかし、この方法ではソフトウェアの割り込み処理やタイミングの遅延により、正常に動作しない可能性がありので、RTS/CTS機能をハードウェア的に備えたUARTペリフェラルを使用することを推奨します。
ハードウェアフロー制御を採用すべき事例
UART通信を行うにあたって、ハードウェアフロー制御を積極的に採用すべき事例と、フロー制御を行わない場合のリスクを以下に列挙します。参考にしてみてください。
1. PCと組み込み機器間の高速通信
PCは非常に高速にデータを送信できる一方、組み込み機器側は受信処理が追いつかないことがあります。特に1Mbps以上の通信では、割込みやDMA処理の遅延が致命的になります。フロー制御による再送処理がない場合、互いに逸失したデータが存在することすら気付けないというかなり致命的な事故を起こします。
2. 無線通信モジュールとのUART通信(例:Xbee、RN42)
無線通信は無線特有の遅延や不安定さがあり、フロー制御による通信可能の確認を怠るとモジュール内部のバッファが簡単にあふれることがあります。バッファが溢れた場合、モジュールがデータを黙って破棄する可能性があり、通信の信頼性が著しく低下します。
また、無線が不通となった際に、送信側が気づかずにデータを送信し続けてしまい多量のデータを逸失してしまう等の惨状を引き起こす場合があります。
3. 受信処理に時間を要するセンサーとの接続
センサーからの連続データ出力に対して、MCU側が他の処理で応答できない時間帯が生じることがあります(逆もまた然り)。
このタイムラグの間に受信バッファがあふれ、データが破損。センサーによっては再取得が不可能となるなどの惨劇が発生します。
4. 複数のUARTデバイスを切り替えて使用する構成
複数のUARTデバイスをソフトウェアで切り替えながら使用する構成では、1つのデバイスに集中できないため、一時的な受信停止が避けられません。非アクティブ状態の間にデータが送られると、受信バッファのオーバーフローやデータ欠落、データラインの汚染によるやデバイス間通信の競合が発生する可能性があります。
まとめ
高品質・安全なUART通信の確保にはハードウェアフロー制御による通信がオススメです。
無線モジュールなどのUART通信設計をする際には、是非ハードウェアフロー制御の採用をご検討ください。
おまけ(具体的な設定例)
STM32CubeIDEでのハードウェアフロー制御の設定
Xbee(XB24C)でのハードウェアフロー制御の設定