はじめに
Raspberry PiのGPIOヘッダーに割り当てられているUARTピン(TXD0,RXD0)を使用して、センサーなどのIoTデバイスやルータなどの外部機器とシリアル通信を行う方法について記載します。
Raspberry Pi Foundationの公式ページ(https://www.raspberrypi.org/)にもとづいて記載しています。
(※)記載内容に誤り等ありましたら、ご連絡いただければ幸いです。
環境
- ボート
Raspberry Pi 4 Model B - OS
Raspberry Pi OS (32-bit) Lite
Minimal image based on Debian Buster
Version: August 2020
Release date: 2020-08-20
Kernel version: 5.4
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l GNU/Linux
pi@raspberrypi:~ $
Raspberry PiのUARTについて
Raspberry Piで使用されているSoCには、PL011とminiUARTの2種類のUARTがあり、すべてのUARTは、3.3Vで駆動します。このため、5Vで駆動するシステムと接続する場合は、RS232Cレベル変換IC等を使用して、電圧レベルを変換して接続します。誤って5Vで稼働するシステムと接続すると破損するので注意が必要です。
Raspberry Pi 4には、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周辺機器のドキュメント(https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf)を参照してください。
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番ピンに対応します。)
Secondary UARTは、通常、GPIOコネクタには存在していません。デフォルトでは、Secondary UARTは Bluetoothモジュールに接続されています。
デフォルトでは、UART0のみが有効になっています。
次の表は、最初の2つのUART(UART0とmini UART)の割り当てをまとめたものです。
モデル | UART0 | mini UART |
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 |
注:Primary UARTとSecondary UARTのどちらが指定されている場合でも、デフォルトでは、mini UARTは、無効になっています。
次の表は、Raspberry Pi OSにおけるLinuxデバイスをまとめたものです。
Linuxデバイス | 説明 |
/dev/ttyS0 | mini UART |
/dev/ttyAMA0 | UART0(1番目のPL011) |
/dev/serial0 | Primary UART |
/dev/serial1 | Secondary UART |
使用した環境では、デフォルトではLinuxデバイスは以下のようになっていました。
上記の表のとおり、mini UART(/dev/ttyS0)は無効化されて存在しておらず、Primary UART(/dev/serial0)も存在しませんでした。また、Secondary UART(/dev/serial1)は、UART0(/dev/ttyAMA0)が使用されていました。
pi@raspberrypi:~ $ ls -l /dev
(略)
lrwxrwxrwx 1 root root 7 Sep 6 06:23 serial1 -> ttyAMA0
(略)
crw-rw---- 1 root dialout 204, 64 Sep 6 06:23 ttyAMA0
(略)
pi@raspberrypi:~ $
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.
Raspberry Piでは、あるUARTがGPIO 14(TXD)およびGPIO 15(RXD)に接続されている。ー このUARTがPrimary UARTです。
デフォルトでは、このUARTは、Linuxコンソールが存在する可能性があるUARTにもなっています。
使用した環境のデフォルトでは、Linuxコンソールで使用するシリアルデバイスは、以下のようにserial0(Primary UART)となっています。しかし、Linuxデバイスには、mni UART(/dev/ttyS0)は存在せず、Primary UART(/dev/serial0)も存在していませんので、Linuxコンソールは、使用できない状態でした。
代わりに、Bluetoothモジュールとの接続に使用されているUART0(/dev/ttyAMA0)が接続されているようです。
pi@raspberrypi:~ $ cat /boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=7d63f42a-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
pi@raspberrypi:~ $
GPIOヘッダーのUARTピンでUART0を使用する方法
上述のRaspberry Pi UARTのデフォルトの状態を踏まえ、GPIOヘッダーのUARTピンでUART0を使用して、シリアル通信を行う方法について記載します。
- Linuxシリアルコンソールの無効化(raspi-configを使用する場合)
デフォルトでは、Primary UART(/dev/serial0)は、Linuxコンソールに割り当てられています。
Primary UARTを他のシステムとのシリアル通信など他の目的で使用する場合は、Raspberry Pi OSを再構成し、Primary UARTをLinuxシリアルコンソールで使用しないようにする必要があります。再構成するには、次のようにraspi-configコマンド、あるいはDevice Tree Overlayを使用して行います。- raspi-configを起動します。(sudo raspi-config)
- 「オプション5 – インターフェイスオプション」を選択します。
- 「オプションP6 – シリアル」を選択します。
- プロンプトに「シリアル経由でログインシェルにアクセスできるようにしますか?」と表示されるので、 「いいえ」と答えます。
- プロンプトに「シリアルポートハードウェアを有効にしますか?」と表示されるので、 「はい」と答えます。
- raspi-configを終了し、Raspberry Piを再起動して変更を有効にします。
以下のように、「console=serial0,115200」の記載が削除され、Primary UART(/dev/serial0)がLinuxコンソールとして使用されなくなります。
pi@raspberrypi:~ $ cat /boot/cmdline.txt
console=tty1 root=PARTUUID=7d63f42a-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
pi@raspberrypi:~ $
- Bluetoothモジュールの切り替え
デフォルトでは、Bluetoothモジュールとの接続にSecandary UART(/dev/serial1)であるUART0(/dev/ttyAMA0)が使用されているため、切り替えを行う必要があります。
様々なUARTに関するDevice Tree Overlayがkernel GitHub tree(https://github.com/raspberrypi/linux)で定義されており、この中に、Bluetoothモジュールに関する有用な「disable-bt」と「miniuart-bt」があります。
このDevice Tree Overlayのいずれかを使用して、デフォルトでBluetoothモジュールとの接続で使用されているUART0をシリアル通信で使用できるように切り替えを行います。
- disable-btを使用する場合
Bluetoothデバイスを無効にし、UART0(1番目のPL011)をPrimary UARTにします。
加えて、「sudo systemctl disable hciuart」コマンドを使用して、モデムを初期化するシステムサービスを無効にして、モデムに接続しないようにする必要があります。
「/boot/config.txt」ファイルを編集し、「dtoverlay=disable-bt」を末尾に追記します。
その後、設定を反映するため、再起動を行います。
pi@raspberrypi:~ $ sudo vi /boot/config.txt
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 Sep 6 07:48 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Sep 6 07:48 serial1 -> ttyS0
(略)
crw--w---- 1 root tty 204, 64 Sep 6 07:49 ttyAMA0
(略)
crw-rw---- 1 root dialout 4, 64 Sep 6 07:48 ttyS0
(略)
pi@raspberrypi:~ $
- miniuart-btを使用する場合
Bluetooth機能を切り替えて、Bluetoothモジュールとの接続をUART0からmini UARTを使用するように切り替えを行い、UART0(1番目のPL011)をPrimary UARTにします。
Bluetoothの機能を使用する場合は、この切り替えによりBluetoothデバイスとの接続にmini UARTが使用されるため、可能な最大ボーレートが低下する場合があることに注意してください。
また、miniUARTのクロックがVPUコアクロックとリンクしているので、force_turbo = 1またはcore_freq = 250を使用して、VPUコアクロックを固定周波数に設定する必要があります。
(※「PL011(UART0、UART2~UART5)とmini UART(UART1)の違い」を参照)
「/boot/config.txt」ファイルを編集し、「dtoverlay=miniuart-bt」および「core_freq=250」を末尾に追記します。
その後、設定を反映するため、再起動を行います。
pi@raspberrypi:~ $ sudo vi /boot/config.txt
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 Sep 6 08:25 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Sep 6 08:25 serial1 -> ttyS0
(略)
crw--w---- 1 root tty 204, 64 Sep 6 08:25 ttyAMA0
(略)
crw-rw---- 1 root dialout 4, 64 Sep 6 08:25 ttyS0
(略)
pi@raspberrypi:~ $
UART1~UART5の有効化
Raspberry Pi 4で追加された4つのUARTを有効化するには、uart2、uart3、uart4、およびuart5のDevice Tree Overlayを使用して行います。
デバイスツリーオーバーレイの詳細については、/boot/overlays/READMEを参照してください。
説明と使用方法については、「dtoverlay -h overlay-name」を実行してください。
デバイスツリーオーバーレイの使用方法の詳細については、このページ(https://www.raspberrypi.org/documentation/configuration/device-tree.md)を参照してください。
手短に言えば、「config.txt」ファイルに行を追加して、デバイスツリーオーバーレイを適用します。
ファイル名の「-overlay.dts」部分が削除されていることに注意してください。
例えば、以下のように記述します。
dtoverlay=disable-bt
以上です。