Raspberry Pi3Bのシリアルコンソール・シリアル通信について anchor.png

Raspberry Piに搭載されているSoCには2つのUART機能(UART0とminiUART)がある。

Pi1B,Pi2Bでは,UART0がGPIOヘッダーに使われている。
Raspberry Pi3B,ZeroWでは,WifiとBluetooth用にチップが搭載されたんだけど,搭載したチップとの通信にそれまでシリアル通信に使用されていたUART0を使うように設計されたため,GPIOヘッダーのpin8,10のUARTには,miniUARTを使用するように変更された。

その結果,Pi3BやZeroWではシリアル通信を利用する時にいくつか問題が発生する。

  • miniUARTがGPIOヘッダーの8pin,10pinに接続されている。
  • 従来のSoCのUART0(pin8,pin10)は,デフォルトでGPIOヘッダーでは接続されていない。(切り替え可能)
  • miniUARTで使用するデバイス名は,/dev/ttyS0を使用する。 従来使用されていたシリアルデバイス名の/dev/ttyAMA0は,WiFi/Bluetooth通信用のチップとの接続に使用されている。
  • Pi3B,ZeroWのminiUARTはボーレートがGPUのコアクロックに依存してしまうように設計されている。
  • Pi3B,ZeroWのGPUのコアクロックは,負荷等や低消費電力時などでダイナミックに変化してしまう。
  • この結果,/dev/ttyS0のボーレートもそれに合わせて変化してしまう。結果,シリアル通信が上手く行かなくなる。 SPIもTimerもこのコアクロックに依存している。

といった問題がある。

さらに,このminiUARTは以下のような機能制限があり,低速でも使用できるコンソール用途向けになってしまっている。

  • データ幅:7,8bitのみ
  • 1スタートビット,1ストップビットのみ
  • ブレーク信号が検出できない
  • パリティエラーが検出できない
  • フレーミングエラーが検出できない
  • 送受信FIFOサイズは8bit分しかない
  • 受信タイムアウト割り込みが無い
  • DCD,DSR,DTR,RI信号が無い

これらを踏まえて対策しないと,シリアルコンソールを使用した場合,ログインプロンプトが表示されてユーザー名を入れたあたりで,反応しなくなってしまうなどが起こる。

そこで,うまく利用出来る方法を設定して利用する必要がある。
やり方としては,1つ目は,GPUコアクロックを250MHzに固定してしまう方法。2つ目は,Bluetoothを無効にしてしまう方法がある。

Bluetoothを使わないなら無効にする方法が良いのかも。
どちらも利用したい場合は,GPUのコアクロックを固定にする方法を選択すべきとは思うが,この場合多少パフォーマンスが落ちる。

また,どちらの方法でも,GPIOヘッダーの8pin(TXD),10pin(RXD)のピンに,シリアルポート(miniUARTまたはUART0)が接続される。シリアルポートとしてはコネクタ経由で利用できるポートは1ポートのみになる。

デフォルト時のデバイス名のエリアスは,
Pi3Bの場合:

/dev/serial0 -> /dev/ttyS0
/dev/serial1 -> /dev/ttyAMA0

Pi1B,Pi2Bの場合:

/dev/serial0 -> /dev/ttyAMA0

になっている。

Pi3B,ZeroWで,dtoverlay=pi3-miniuart-btに設定した時のデバイス名のエリアスは,

/dev/serial0 -> /dev/ttyAMA0
/dev/serial1 -> /dev/ttyS0

になる。

Page Top

シリアルコンソールを使用する anchor.png

シリアルポートを,OSのインストール時の操作やリモートログイン用にシリアルコンソールとして出来るようにデフォルト設定されている。

これは,/boot/cmdline.txtで/dev/serial0をシリアルコンソールで使用するように設定されているから。
/boot/cmdline.txtの内容:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes root wait

ただ,デフォルトのままでは,上記の理由でPi3B,ZeroWでは正常に使用できない。*1

Page Top

Pi3B,ZeroWでシリアルポートを上手く使えるように設定する anchor.png

上手くシリアルポートが動作するよう,以下の様な設定を/boot/config.txt を修正して設定する。

  • Bluetoothを使用しながらシリアルポートも使用する(ちょっとPi3Bが遅くなる)
    core_freq = 250
    を追加する。これは,GPUコアクロックを250MHz固定にする方法。これによりシリアルポートのボーレートの変動が無くなって安定する。
    シリアルポートとしては,miniUARTがGPIOヘッダーのpin8,10に接続される。
    デバイス名は/dev/ttyS0になる。このデバイスのエリアスとして/dev/serial0が割り当てられる。
  • Bluetoothチップを無効にしてUART0をシリアルポートとして使用する場合
    dtoverlay=pi3-disable-bt
    を追加する。

    Pi1BやPi2Bと同様の接続となり,SoCのUART0がGPIOヘッダーのpin8,10に接続される。
    デバイス名は/dev/ttyAMA0になる。このデバイスのエリアスとして/dev/serial0が割り当てられる。

    また,以下の設定を行って,
    # systemctl disable hciuart
    Bluetoothとの接続を管理するデーモンを停止する。
  • miniUARTをBlutoothとの通信に使用しUART0をシリアルポートとして使用する
    dtoverlay=pi3-miniuart-bt
    core_freq = 250
    を追加する。SoCのUART0がGPIOヘッダーのpin8,10に接続される。(デフォルト接続と逆になる)
    デバイス名は,/dev/ttyAMA0になる。このデバイスのエリアスとして/dev/serial0が割り当てられる。
    miniUARTのデバイス名は,/dev/ttyS0になる。このデバイスのエリアス名は/dev/serial1が割り当てられる。

    また,/lib/systemd/system/hciuart.serviceを,
    After=dev-serial1.device -> After=dev-ttyS0.device
    に変更する。(変更しなくても大丈夫だと思う・・・)
Page Top

シリアル通信を有効にする anchor.png

シリアルポートをシリアルコンソールとして使用するのではなく,プログラムで他の機器とシリアル通信をするために使用する場合には,以下の様な設定を/boot/config.txt を修正して設定する。

  • シリアル通信を有効にする設定
    enable_uart=1
    を追加する。
    この設定を行うと,core_freq=250が無くてもcore_freq=250と同様にシステムクロックが固定されるみたい。
    おそらくこの設定は上記の,
    dtoverlay=pi3-miniuart-bt
    core_freq = 250
    と同じことだと思う。
  • シリアルコンソールを無効にする
    シリアルコンソールを無効にするために,/boot/cmdline.txt を修正する。
    console=serial0,115200
    を削除する。
  • シリアルコンソールのデーモンを停止
    さらに,シリアルコンソールのデーモンを停止して,無効にする。
    Pi3BやZeroWの場合(ttyS0),
    # systemctl stop serial-getty@ttyS0.service 
    # systemctl disable serial-getty@ttyS0.service
    Pi1BやPi2Bの場合(ttyAMA0),
    # systemctl stop serial-getty@ttyAMA0.service
    # systemctl disable serial-getty@ttyAMA0.service
    のようにする。

これで,シリアルコンソールの使用を停止・無効に出来て,シリアル通信に使用できるようになった。


*1 Pi1B,Pi2Bは問題ない。

コメント一覧

新しくコメントをつける

題名
ゲスト名
投稿本文
より詳細なコメント入力フォームへ
通りすがり   投稿日時 2019/6/19 7:58
めちゃくちゃわかりやすくてためになりました。
ありがとうございました

Front page   Freeze Diff Backup Copy Rename Reload   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom)
Counter: 3745, today: 2, yesterday: 0
Last-modified: 2020-12-26 (Sat) 15:07:43 (JST) (1484d) by yuji