はじめに
本記事では、Raspberry PiのGPIOヘッダーに割り当てられているUARTピン(TXD0,RXD0)を使用して、センサーなどのIoTデバイスやルータなどの機器とシリアル通信を行う方法について記載します。
Raspberry Pi Foundationの公式ページで公開されている「UART configuration」に基づいて記載いたします。
(※)記載内容に誤り等ありましたら、ご連絡いただければ幸いです。
環境
- ボート
Raspberry Pi 4 Model B - OS
Raspberry Pi OS Lite
Release date: March 4th 2021
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.17-v7l+ #1403 SMP Mon Feb 22 11:33:35 GMT 2021 armv7l GNU/Linux
pi@raspberrypi:~ $
Raspberry PiのUARTについて
Raspberry Pi 4で使用されているSoCには、PL011とmini UARTの2種類のUARTがあります。PL011は、16550と互換性があるUARTです。これに対してmini UARTは、最小限の限られた機能しかありません。
すべてのUARTは、3.3Vで駆動します。このため、5Vで駆動するシステムと接続する場合は、RS232Cレベル変換IC等を使用して、電圧レベルを変換して接続します。誤って、5Vで稼働するシステムと接続すると破損するので注意が必要です。
Raspberry Pi Zero, 1, 2およびRaspberry Pi 3には、以下のような2つのUARTがあります。
名前 | タイプ |
UART0 | PL011 |
UART1 | miniUART |
Raspberry Pi 4には、上記2つのUARTの他に4つのPL011が追加され、合計6つのUARTがあります。追加された4つのPL011は、デフォルトで無効になっているため、使用する場合は有効化する必要があります。
次の表に、すべてのUARTの一覧を記載します。
名前 | タイプ |
UART0 | PL011 |
UART1 | mini UART |
UART2 | PL011 |
UART3 | PL011 |
UART4 | PL011 |
UART5 | PL011 |
PL011(UART0、UART2~UART5)とmini UART(UART1)の違い
PL011とmini UARTの主な相違点について以下に記載します。
- 送受信用のFIFOバッファのサイズが小さくなっています。(8ビット)
- フロー制御機能がないため高いボーレートでは文字を失う傾向があります。
- クロックがVPUコアクロックにリンクされているため、VPUコアクロックの周波数が変化すると、mini UARTのボーレートが変化してしまいます。
(※VPUコアクロックの周波数は、温度状況等により変化します。) - break信号を検出できません。
- フレーミングエラーを検出できません。
- パリティビットが使用できません。
- 受信タイムアウト割り込みが使用できない。
- DCD, DSR, DTR, RI信号がありません。
- データ長が7ビット、8ビットしか使用できません。
- 1スタートビット、1ストップビットしか使用できません。
mini UARTの詳細については、SoC周辺機器のドキュメントを参照してください。
Primary UART及びSecondary UART
Raspberry Piでは、1つのUARTがGPIO 14(TXD:送信)およびGPIO 15(RXD:受信)に接続されており、このUARTが、Primary UARTになっています。デフォルトでは、このUARTは、Linuxコンソールに接続されているUARTになっている場合があります。
(注:GPIO 14は、GPIOヘッダーの8番ピンに、GPIO 15はGPIOヘッダーの10番ピンに対応します。)
Raspberry Pi Fundationの公式ページの「UART configuration」ドキュメントに、以下のように記載されています。
On the Raspberry Pi, one UART is selected to be present on GPIO 14 (transmit) and 15 (receive) – this is the primary UART. By default, this will also be the UART on which a Linux console may be present. Note that GPIO 14 is pin 8 on the GPIO header, while GPIO 15 is pin 10.
Raspberry Piでは、GPIO 14(送信)と15(受信)に存在する(接続されている)1つのUARTが選択されています。ー このUARTがPrimary UARTです。デフォルトでは、これはLinuxコンソールが存在する可能性のあるUARTにもなります。
GPIO 14はGPIOヘッダーのピン8であり、GPIO15はピン10であることに注意してください。
Secondary UARTは、通常、GPIOコネクタには存在していません(接続されていません)。デフォルトでは、Secondary UARTは、無線LAN/Bluetoothコントローラが搭載されているモデルでは、このコントローラのBluetoothモジュール側に接続されています。デフォルトでは、UART0のみが有効になっています。
次の表は、最初の2つのUART(UART0とUART1)の割り当ての概要です。
モデル | 1番目のPL011(UART0) | 2番目のmini UART(UART1) |
Raspberry Pi Zero | primary | secondary |
Raspberry Pi Zero W | secondary (Bluetoothに接続) | primary |
Raspberry Pi 1 | primary | secondary |
Raspberry Pi 2 | primary | secondary |
Raspberry Pi 3 | secondary (Bluetoothに接続) | primary |
Raspberry Pi 4 | secondary (Bluetoothに接続) | primary |
注:mini UARTは、Primary UARTまたはSecondary UARTのどちらに指定されているかに関係なく、デフォルトで無効になっています。
次の表は、Raspberry Pi OSにおけるLinuxデバイスをまとめたものです。
Linuxデバイス | 説明 |
/dev/ttyS0 | mini UART |
/dev/ttyAMA0 | UART0(1番目のPL011) |
/dev/serial0 | Primary UART |
/dev/serial1 | Secondary UART |
注:/dev/serial0および/dev/serial1は、/dev/ttyS0または/dev/ttyAMA0のいずれかを指すシンボリックリンクになっています。
使用した環境では、デフォルトのLinuxデバイス状態は、以下のようになっていました。
上記のとおり、mini UART(/dev/ttyS0)は、無効化されていて存在しておらず、このため、mini UART(/dev/ttyS0)のシンボリックリンクであるPrimary UART(/dev/serial0)も存在しませんでした。Bluetoothモジュールとの接続に使用されるSecondary UART(/dev/serial1)は、UART0(/dev/ttyAMA0)のシンボリックリンクになっており、UART0(/dev/ttyAMA0)がBluetoothモジュールとの接続に使用されていました。
pi@raspberrypi:~ $ ls -l /dev
~(略)~
lrwxrwxrwx 1 root root 7 Apr 14 05:04 serial1 -> ttyAMA0
~(略)~
crw-rw---- 1 root dialout 204, 64 Apr 14 05:04 ttyAMA0
~(略)~
pi@raspberrypi:~ $
使用した環境のデフォルトでは、Linuxコンソールで使用するシリアルデバイスは、以下のようにserial0(Primary UART)となっています。しかし、Linuxデバイスには、serial0(Primary UART)は存在していませんので、結果として、Linuxコンソールは、使用できない状態でした。
pi@raspberrypi:~ $ cat /boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=6a990620-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
pi@raspberrypi:~ $
GPIOヘッダーのUARTピンでUART0を使用する方法
上記のRaspberry Piのデフォルト状態を踏まえ、UART0(/dev/ttyAMA0)でGPIOヘッダー8番ピン(TXD0)およびGPIOヘッダー10番ピン(RXD0)を使用して、シリアル通信を行う方法について記載します。
Linuxシリアルコンソールの無効化
デフォルトでは、Primary UART(/dev/serial0)は、Linuxコンソールに割り当てられています。このため、外部のIoTデバイスやルータ等の機器とのシリアル通信など、他の目的でPrimary UARTを使用する場合は、Raspberry Pi OSを再構成し、Primary UART(/dev/serial0)をLinuxシリアルコンソールで使用しないようにする必要があります。再構成するには、次のようにraspi-configコマンドを使用して行います。
- raspi-configを起動します。(pi@raspberrypi:~ $ sudo raspi-config)
- 「3 – インターフェイスオプション」を選択し、「Select」を選択します。
- 「P6 – シリアルポート」を選択し、「Select」を選択します。
- プロンプトに「シリアル経由でログインシェルにアクセスできるようにしますか?」と表示されるので、 「いいえ」を選択します。
- プロンプトに「シリアルポートハードウェアを有効にしますか?」と表示されるので、 「はい」を選択します。
- 「シリアルログインシェルが無効になっています」および「シリアルインターフェースが有効になっています」と表示されますので、「了解」を選択します。
- 初期の画面に戻りますので、「Finish」を選択します。
- 「今すぐ再起動しますか?」と表示されますので、「はい」を選択し、Raspberry Piを再起動して変更を有効にします。
以下のように、「console=serial0,115200 console=tty1」の記載が削除され、Primary UART(/dev/serial0)が、Linuxコンソールとして使用されなくなります。
【変更前】
pi@raspberrypi:~ $ cat /boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=6a990620-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
pi@raspberrypi:~ $
【変更後】
pi@raspberrypi:~ $ cat /boot/cmdline.txt
console=tty1 root=PARTUUID=6a990620-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
pi@raspberrypi:~ $
Bluetoothモジュールの接続切り替え
上記の表のとおり、デフォルトでは、Secondary UART(/dev/serial1)は、UART0(/dev/ttyAMA0)のシンボリックリンクになっていて、Bluetoorhモジュールとの接続に使用されています。このため、Bluetoorhモジュールと接続されているUARTの切り替えを行う必要があります。この接続の切り替えは、Device Tree Overlayを使用して行います。
様々なUARTに関するDevice Tree Overlayが「kernel GitHub tree」で定義されており、この中に、Bluetoothモジュールに関係する有用な「disable-bt」と「miniuart-bt」があります。
このDevice Tree Overlayのいずれかを使用して、デフォルトでBluetoothモジュールとの接続に使用されているUART0(/dev/ttyAMA0)をシリアル通信で使用できるように切り替えを行います。
disable-btを使用する場合
disable-btは、Bluetoothデバイスを無効にし、1番目のPL011(UART0)をPrimary UART(/dev/serial0)にします。disable-btを使用することにより、Primary UART(/dev/serial0)として、UART0(/dev/ttyAMA0)を使用できるようになります。また、UARTを使用して接続されたBluetoothモデムを初期化するシステムサービスを無効にして、システムサービスがUARTに接続しないようにする必要があります。
「/boot/config.txt」ファイルを編集し、「dtoverlay=disable-bt」を末尾に追記します。
その後、設定を反映するため、再起動を行います。
pi@raspberrypi:~ $ sudo vi /boot/config.txt
~(略)~
# Disable Bluetooth <-- 必要に応じてコメントを追記
dtoverlay=disable-bt <-- 追記
pi@raspberrypi:~ $
再起動後のLinuxデバイスは、以下のようになります。
Primary UART(/dev/serial0)は、UART0(/dev/ttyAMA0)のシンボリックリンクとなり、Secondary UART(/dev/serial1)は、mini UART(/dev/ttyS0)のシンボリックリンクになります。
pi@raspberrypi:~ $ ls -l /dev
~(略)~
lrwxrwxrwx 1 root root 7 4月 14 06:35 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 4月 14 06:35 serial1 -> ttyS0
~(略)~
crw-rw---- 1 root dialout 204, 64 4月 14 06:35 ttyAMA0
crw-rw---- 1 root dialout 4, 64 4月 14 06:35 ttyS0
~(略)~
pi@raspberrypi:~ $
次に、以下のコマンドを実行し、Bluetoothモデムを初期化するシステムサービスを無効にします。
pi@raspberrypi:~ $ sudo systemctl disable hciuart
pi@raspberrypi:~ $
miniuart-btを使用する場合
miniuart-btは、Bluetooth機能を切り替えて、Bluetoothモジュールとの接続にmini UART(/dev/ttyS0)を使用し、1番目のPL011(UART0)をPrimary UART(/dev/serial0)にします。
この切り替えにより、Bluetoothデバイスとの接続に、mini UART(/dev/ttyS0)が使用されるため、使用可能な最大ボーレートが低下する可能性があることに注意してください。
(※「PL011(UART0、UART2~UART5)とmini UART(UART1)の違い」を参照)
また、force_turbo=1または、core_freq=250のいずれかを使用して、VPUコアクロックを固定周波数に設定する必要があります。
「/boot/config.txt」ファイルを編集し、「dtoverlay=miniuart-bt」および「core_freq=250」を末尾に追記します。
その後、設定を反映するため、再起動を行います。
pi@raspberrypi:~ $ sudo vi /boot/config.txt
~(略)~
# Use miniUART to connect to Bluetooth module <-- コメントを必要に応じて追記
dtoverlay=miniuart-bt <-- 追記
core_freq=250 <-- 追記
pi@raspberrypi:~ $
再起動後のLinuxデバイスの状態は、以下のようになります。
Primary UART(/dev/serial0)は、UART0(/dev/ttyAMA0)のシンボリックリンクになり、Secondary UART(/dev/serial1)は、mini UART(/dev/ttyS0)のシンボリックリンクになります。
pi@raspberrypi:~ $ ls -l /dev
lrwxrwxrwx 1 root root 7 4月 14 06:59 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 4月 14 06:59 serial1 -> ttyS0
~(略)~
crw-rw---- 1 root dialout 204, 64 4月 14 06:59 ttyAMA0
crw-rw---- 1 root dialout 4, 64 4月 14 06:59 ttyS0
~(略)~
pi@raspberrypi:~ $
UART1~UART5の有効化
Raspberry Pi 4で追加された4つのUARTを有効化するには、uart2、uart3、uart4、およびuart5のDevice Tree Overlayを使用して行います。
Device Tree Overlayの詳細については、「/boot/overlays/README」を参照してください。
説明と使用方法については、「dtoverlay -h overlay-name」を実行してください。
Device Tree Overlayの使用方法の詳細については、Raspberry Pi Foundationの公式ページの「Device Trees, overlays, and parameters」ドキュメントを参照してください。
手短に言えば、「config.txt」ファイルに行を追加して、Device Tree Overlayを適用します。
Device Tree Overlayを記述する際は、ファイル名の「-overlay.dts」部分を削除して記載します。
例えば、以下のように記述します。
dtoverlay=disable-bt
以上です。
コメント
[…] 詳細な方法は、公式ページ(英語)か、こちらのページ(日本語)が分かりやすいです。 […]