📚

Pico ボード単体で通信プロトコル解析もできる! 本当はスゴい la コマンドの話

に公開

pico-jxgLABO は、USB ケーブル一本でマイコンボード RaspberryPi Pico の様々な機能を試すことができる実験プラットフォームです。

この記事では、pico-jxgLABO のロジックアナライザコマンド la の機能を紹介します。la コマンドはコンソールベースのツールで、GUI アプリ PulseView と連携するときはバックエンドで黙々と動作するだけの存在です。でも、このコマンド単体でも波形表示ができますし、I2C や SPI、UART などの通信プロトコル解析もできるんです。本記事を通じて、la コマンドの便利さを知っていただけれると嬉しいです。

PulseView との連携については以下の記事を参照ください。

▶️ pico-jxgLABO × PulseView: プローブ接続いらずで気軽に使えるロジックアナライザを体験しよう!

pico-jxgLABO の書き込み

Pico ボードへの pico-jxgLABO の書き込みと基本的な使い方はこちら。特別なハードウェアは必要なく、Pico や Pico 2 ボードを USB ケーブルで PC に接続するだけで始められます。

この記事で説明する実験を行うには、バージョン 0.2.0 以降の pico-jxgLABO が Pico ボードに書き込まれている必要があります。ターミナルソフトで about-me コマンドを実行すると pico-jxgLABO のバージョンを確認できます。

L:/>about-me
Program Information
 name:              pico-jxgLABO
 version:           0.2.0
     :
     :

la コマンドの機能

la コマンドの機能は大きく分けて二つあり、一つはデータサンプリング、もう一つは波形表示および解析です。データサンプリングで信号データをバッファメモリにとりこみ、そのバッファメモリを参照して波形表示や通信プロトコル解析を行うという流れになります。

一度データサンプリングを行えば、バッファメモリの内容は次のデータサンプリング操作まで保存されるので、波形表示や解析を何度でも実行できます。

データサンプリング

データサンプリングの開始と停止

la コマンドの -p (または --pins) オプションで測定する GPIO ピンを指定し、enable サブコマンドを実行することでサンプリングを開始します。

L:/>la -p 2,3,4 enable

GPIO ピンはピン番号をカンマで区切って指定します。ハイフンを使って範囲指定をすることもできます。以下の表に例を示します。

GPIO ピン指定 内容
-p 0 GPIO0 を指定します
-p 2,3,8,9 GPIO2,3,8,9 を指定します
-p 8-15 GPIO8 から GPIO15 までを指定します
-p 2-4,8-13 GPIO2 から GPIO4、GPIO8 から GPIO13 までを指定します

このオプションで指定した GPIO ピンの情報は、print サブコマンドや PulseView での波形表示にも反映されます。

la コマンドは、データ格納用のバッファメモリを確保した後、PIO (Programmable Input/Output) と DMA (Direct Memory Access) に対してサンプリング処理を指示してすぐに終了します。実際の処理はこれら PIO と DMA が行うので、CPU 負荷はほぼゼロです。バッファメモリがいっぱいになると、自動的にサンプリングを停止します。

la コマンドで disable サブコマンドを実行するとデータサンプリングを停止して PIO、DMA およびバッファメモリのリソースを解放します。通常は disable サブコマンドを明示的に実行する必要はありません。

L:/>la disable

enable サブコマンドを再度実行すると、リソースを初期化してデータサンプリングを開始します。このとき、GPIO ピンや他のサンプリングパラメータ前回の設定が引き継がれるので、変更がなければ enable だけ実行すれば大丈夫です。

L:/>la enable

PulseView との連携

PulseView で Start ボタンを押すと、Pico ボード内で la enable コマンド相当の処理を実行します。測定する GPIO ピンの設定や他のサンプリングにかかわるオプションは、これよりも前に la コマンドで設定しておく必要があります。

サンプリングが始まると、pico-jxgLABO はバッファメモリの状態をポーリングし、サンプリングデータがあると PulseView に送信します。Stop ボタンを押すと、このサンプリングデータの送信を停止します。データ転送が終了してもバッファメモリの内容はそのままなので、la コマンドの print サブコマンドで波形データを表示したり、プロトコル解析を行ったりできます。

サンプリングモードについて

pico-jxgLABO のロジックアナライザは、transitional モードでサンプリング処理を行います。transitional モードでは信号が変化したときだけデータをサンプリングするので、バッファメモリを効率的に使用できます。また、信号の変化が速い(周波数が高い)場合でも、遅い(周波数が低い)場合でも、同じサンプリングレートでサンプリングできます。

内部信号と外部信号の選択

--target オプションでサンプリング対象を指定できます。internal (デフォルト) を指定すると Pico 内部の信号を、external を指定すると GPIO ピンに入力された外部信号をサンプリングします。

  • --target:internal Pico 内部の信号をサンプリングします
  • --target:external GPIO ピンに入力された外部信号をサンプリングします

--target オプションはすべての GPIO ピンを一括で設定しますが、以下のオプションを使うことで GPIO ピン毎に設定を変更することができます。

  • --internal:PINS 内部信号のサンプリングをする GPIO ピンを指定します
  • --external:PINS 外部信号のサンプリングをする GPIO ピンを指定します
  • --inherited:PINS --target オプションの設定を引き継ぐ GPIO ピンを指定します

測定対象が外部信号の場合、la を実行したときの状態表示で GPIO ピン番号の前にバッククォート (`) が付きます。以下に例を示します。

L:/>la -p 2,3 --target:internal
disabled ---- 12.5MHz (samplers:1) pins:2,3 events:0/0 (heap-ratio:0.7)
L:/>la -p 2,3 --target:external
disabled ---- 12.5MHz (samplers:1) pins:`2,`3 events:0/0 (heap-ratio:0.7)

サンプリングレートの指定

pico-jxgLABO は PIO のステートマシンを使ってサンプリング処理を行います。このサンプリング処理を行うステートマシンのことを、ここではサンプラーと呼びます。

サンプラーが一つのデータのサンプリングをするのに必要なクロック数は 12 クロックです。つまり、クロック周波数 150MHz の Pico2 の場合、150MHz ÷ 12 = 12.5MHz のサンプリングが可能です。Pico (クロック周波数 125MHz) の場合は、125MHz ÷ 12 = 10.4MHz のサンプリングが可能になります。

ひとつの PIO ブロックには 4 個のステートマシン (サンプラー) が搭載されています。これらを開始時刻をずらして並行動作させることで、サンプリングレートを上げることができます。動作させるサンプラーの数はオプション --samplers で指定します。以下にサンプラーの数に対するサンプリングレートの例を示します。

オプション Pico2 Pico
--samplers:1 12.5MHz 10.4MHz
--samplers:2 25.0MHz 20.8MHz
--samplers:3 37.5MHz 31.2MHz
--samplers:4 50.0MHz 41.7MHz

サンプラーの数を増やすとサンプリングレートが上がりますが、サンプリングできるイベントの数が減ります。

使用する PIO の指定

Pico2 は PIO0, PIO1, PIO2 の 3 ブロック、Pico は PIO0 と PIO1 の 2 ブロックを搭載しています。デフォルトでは、PIO2 (Pico2) または PIO1 (Pico) をロジックアナライザ用に使用しますが、--pio オプションで使用する PIO ブロックを指定できます。以下に例を示します。

  • --pio:0 PIO0 を使用します
  • --pio:1 PIO1 を使用します
  • --pio:2 PIO2 を使用します

バッファメモリのサイズ指定

--heap-ratio:N オプション (N は 0 < N < 1 の範囲の数値) を指定すると全体のヒープ領域の中からバッファメモリとして使用する領域の割合を指定できます。デフォルトは 0.7 で、ヒープ領域の 70% をバッファメモリとして使用します。laenable サブコマンドを実行したときにメモリ確保エラーが出る場合は、この数値を小さくしてください。

波形表示

la コマンドの print サブコマンドで、サンプリングした波形データをテキストベースで表示することができます。ここでは例として I2C インターフェースの信号をキャプチャします。

まず、GPIO2 (I2C SDA) と GPIO3 (I2C SCL) を測定対象にしてキャプチャを開始します。

L:/>la -p 2,3 enable
enabled pio:2 12.5MHz (samplers:1) pins:2,3 events:1/88620 (heap-ratio:0.7)

次に、i2c1 コマンドを使って I2C プロトコルの信号を出力します。オプション -p で使用する SDA, SCL ピンを指定します。scan サブコマンドは、アドレス 0 から 127 に対して Read リクエストを送信し、応答があったアドレスを表示します。

L:/>i2c1 -p 2,3 scan
Bus Scan on I2C1
   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

これで I2C の信号が生成されました。キャプチャがされているか、la コマンドを実行してロジックアナライザの状態を確認します。

L:/>la
enabled pio:2 12.5MHz (samplers:1) pins:2,3 events:3459/88620 (heap-ratio:0.7)

イベントの数が増えて、信号のキャプチャがされていることがわかります。la print コマンドを使って、キャプチャした信号を表示します。

L:/>la print

以下はターミナルソフトの画面をキャプチャして 90 度回転させたものです。

waveform-i2c-org

表示分解能 (1 行あたりに表示する時間間隔) は、デフォルトで 1000usec (1msec) です。上の例だとエッジの間隔が 5usec 程度ですから、それよりも短くしないと正しい表示ができません。そこで、オプション --reso を使って、表示分解能を 4usec に設定して波形表示をします。

L:/>la print --reso:4

waveform-i2c

la print は、デフォルトではバッファメモリ中の最初の 80 イベントを表示します。--part オプションを使うと表示するイベントの範囲を指定できます。

  • --part:head: 最初の部分のイベントを表示します (デフォルト)
  • --part:tail: 最後の部分のイベントを表示します
  • --part:all: すべてのイベントを表示します

headtail を指定したときに表示するイベント数を変更するには、オプション --events:N (N はイベント数) を指定します。

--part:all オプションを使うと、すべてのイベントを表示できます。表示を中断するには Ctrl-C キーを押します。

L:/>la print --part:all
 Time [usec] P2  P3
             │   │
             :   :
        0.00 └─┐ │
        1.28   │ └─┐
               :   :
      776.00 ┌─┘   │
             │     │
      780.40 │   ┌─┘
             │   │
      786.72 │   └─┐
             │     │
             :
             :

リダイレクトを使うことで表示内容をファイルに保存できます。例えば、i2c.log というファイルに保存するには以下のようにします。

L:/>la print --part:all > i2c.log

波形の表示には Unicode のマルチバイト文字を使用していますが、環境によっては文字化けすることがあります。その場合は、オプション --style:ascii2 などを指定すると ASCII 文字だけで表示できます。

L:/>la print --style:ascii2 --reso:4

waveform-i2c-ascii

--style オプションには、文字種や波形の大きさが異なる以下のスタイルを指定できます。デフォルトは unicode2 です。

  • unicode1, unicode2, unicode3, unicode4 ... Unicode マルチバイト文字を使用
  • ascii1, ascii2, ascii3, ascii4 ... ASCII 文字を使用

通信プロトコル解析

サブコマンド dec を使うと、I2C や SPI、UART などの通信プロトコル解析ができます。dec サブコマンドの書式は dec:DECODER {SUB-COMMANDS...} です。DECODERi2c, spi, uart などのプロトコルデコーダ名を指定します。ブレースで囲まれた SUB-COMMANDS にはデコーダ毎に異なるサブコマンドを指定します。

I2C プロトコル解析

I2C プロトコルをデコードするには、dec サブコマンドのプロトコル名に i2c を指定し、以下のサブコマンドを指定します。

  • sda:PIN: SDA ピンを指定
  • scl:PIN: SCL ピンを指定

i2c1 scan コマンド使ってアドレス 0 から 127 に対して Read リクエストを送信したときの信号をキャプチャし、la dec:i2c コマンドでデコードしてみます。

L:/>la -p 2,3 enable
L:/>i2c1 -p 2,3 scan
L:/>la dec:i2c {sda:2 scl:3} print --reso:4

waveform-i2c-dec

SPI プロトコル解析

SPI プロトコルをデコードするには、dec サブコマンドのプロトコル名に spi を指定し、以下のサブコマンドを指定します。

  • mode:MODE: SPI モードを指定 (0-3)
  • mosi:PIN: MOSI ピンを指定
  • miso:PIN: MISO ピンを指定
  • sck:PIN: SCK ピンを指定

mosimiso はどちらか一方または両方を必ず指定します。

spi0 write コマンド使って SPI の MOSI に 0 から 255 までのデータを送信したときの信号をキャプチャし、la dec:spi コマンドでデコードしてみます。

L:/>la -p 2,3 enable
L:/>spi0 -p 2,3 write:0-255
L:/>la dec:spi {mode:0 sck:2 mosi:3} print --reso:0.4

waveform-spi-dec

UART プロトコル解析

UART プロトコルをデコードするには、dec サブコマンドのプロトコル名に uart を指定し、以下のサブコマンドを指定します。

  • tx:PIN: TX ピンを指定
  • rx:PIN: RX ピンを指定
  • baudrate:RATE: ボーレートを指定。デフォルトは 115200
  • frame:NPS: フレームフォーマットを指定。N はデータビット長 (5, 6, 7, 8, 9)、P はパリティ (N:none, E:even, O:odd)、 S はストップビット長 (1, 2)。デフォルトは 8n1 (8bit, none, 1bit stop)

baudrateframe は省略可能です。txrx はどちらか一方または両方を必ず指定します。

uart1 write コマンド使って UART の TX に 0 から 255 までのデータを送信したときの信号をキャプチャし、la dec:uart コマンドでデコードしてみます。

L:/>la -p 4 enable
L:/>uart1 -p 4 write:0-255
L:/>la dec:uart {tx:4} print --reso:4

waveform-uart-dec

まとめ

本記事では la コマンドの詳細と、プロトコル解析の方法について説明しました。テキストベースなので、ターミナルソフトの操作だけで手軽にロジックアナライザの機能を利用できます。GUI ベースの PulseView などのツールと使い分けることで、より効果的に波形解析を行うことができるでしょう。

GitHubで編集を提案

Discussion