Raspberry Pi GPIOを使用したシリアル通信

Raspberry Pi

はじめに

本記事では、Raspberry PiのGPIOヘッダーに割り当てられているUARTピン(TXD0,RXD0)を使用して、センサーなどのIoTデバイスやルータなどの機器とシリアル通信を行う方法について記載します。
Raspberry Pi Foundationの公式ページで公開されている「UART configuration」に基づいて記載いたします。
(※)記載内容に誤り等ありましたら、ご連絡いただければ幸いです。

環境

  1. ボート
    Raspberry Pi 4 Model B
  2. OS
    Raspberry Pi OS Lite
    Release date: March 4th 2021

本記事では、「Raspberry Pi OS Lite」イメージを使用した環境で記載していますが、同一バージョンの「Raspberry Pi OS with desktop and recommended software」イメージや「Raspberry Pi OS with desktop」イメージを使用した場合でも同様です。

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で稼働するシステムと接続すると破損するので注意が必要です。

Bitly

Raspberry Pi Zero, 1, 2およびRaspberry Pi 3には、以下のような2つのUARTがあります。

名前タイプ
UART0PL011
UART1miniUART

Raspberry Pi 4には、上記2つのUARTの他に4つのPL011が追加され、合計6つのUARTがあります。追加された4つのPL011は、デフォルトで無効になっているため、使用する場合は有効化する必要があります。
次の表に、すべてのUARTの一覧を記載します。

名前タイプ
UART0PL011
UART1mini UART
UART2PL011
UART3PL011
UART4PL011
UART5PL011
UART 一覧

PL011(UART0、UART2~UART5)とmini UART(UART1)の違い

PL011とmini UARTの主な相違点について以下に記載します。

  1. 送受信用のFIFOバッファのサイズが小さくなっています。(8ビット)
  2. フロー制御機能がないため高いボーレートでは文字を失う傾向があります。
  3. クロックがVPUコアクロックにリンクされているため、VPUコアクロックの周波数が変化すると、mini UARTのボーレートが変化してしまいます。
    (※VPUコアクロックの周波数は、温度状況等により変化します。)
  4. break信号を検出できません。
  5. フレーミングエラーを検出できません。
  6. パリティビットが使用できません。
  7. 受信タイムアウト割り込みが使用できない。
  8. DCD, DSR, DTR, RI信号がありません。
  9. データ長が7ビット、8ビットしか使用できません。
  10. 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 Zeroprimarysecondary
Raspberry Pi Zero Wsecondary (Bluetoothに接続)primary
Raspberry Pi 1primarysecondary
Raspberry Pi 2primarysecondary
Raspberry Pi 3secondary (Bluetoothに接続)primary
Raspberry Pi 4secondary (Bluetoothに接続)primary
モデルごとのUARTの割り当て

注:mini UARTは、Primary UARTまたはSecondary UARTのどちらに指定されているかに関係なく、デフォルトで無効になっています。

次の表は、Raspberry Pi OSにおけるLinuxデバイスをまとめたものです。

Linuxデバイス説明
/dev/ttyS0mini UART
/dev/ttyAMA0UART0(1番目のPL011)
/dev/serial0Primary UART
/dev/serial1Secondary UART
各UARTのLinuxデバイスとの対応

注:/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コマンドを使用して行います。

  1. raspi-configを起動します。(pi@raspberrypi:~ $ sudo raspi-config)
  2. 「3 – インターフェイスオプション」を選択し、「Select」を選択します。
  3. 「P6 – シリアルポート」を選択し、「Select」を選択します。
  4. プロンプトに「シリアル経由でログインシェルにアクセスできるようにしますか?」と表示されるので、 「いいえ」を選択します。
  5. プロンプトに「シリアルポートハードウェアを有効にしますか?」と表示されるので、 「はい」を選択します。
  6. 「シリアルログインシェルが無効になっています」および「シリアルインターフェースが有効になっています」と表示されますので、「了解」を選択します。
  7. 初期の画面に戻りますので、「Finish」を選択します。
  8. 「今すぐ再起動しますか?」と表示されますので、「はい」を選択し、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

以上です。

コメント

  1. […] 詳細な方法は、公式ページ(英語)か、こちらのページ(日本語)が分かりやすいです。 […]

タイトルとURLをコピーしました