Raspberry Pi Pico
2月5日に秋月電子通商に発注した Raspberry Pi Pico が、思ったより早く(2021-02-09)届きました。
今回の Raspberry Pi Pico は OS として Linux が動作するようなものではなく、マイクロコントローラという、どちらかというと組み込み向けの製品です。 私は 1個 550円 で購入しました。 送料が 500円 だったので、相対的に送料が高い感じです。 550円 でも、133MHz駆動のデュアルコアArm Cortex-M0+、RAM 264KB、フラッシュ 2MB、BOOT ROM 16KB とかなりの高機能です。
とりあえず祖先の Raspberry Pi 1 Model B(2012-09) と記念写真。
電源供給、プログタムの書き込み、データ転送のための USB (micro B) のソケットと、基板にピンヘッダ用のスルーホールが43個あるだけです。 さらに基板上にプログラム書き込み用のBOOTSELボタンとLEDが1つ付いています。
ネットワークもディスプレイも音声出力も何もありません。
Raspberry Pi がどんどん高性能化して、Linux が動作する普通のPCになってしまったので、コンピュータの基礎を学習するために、あえて OS のない環境を出してきたのでしょうか。
まったく何もプログラムが入っていないと動作しないので、16KB の ROM には「bootrom」という BIOS に相当するようなプログラムが入っていて、電源オンからの動作がある程度決まっています。 bootrom の内容はhttps://github.com/raspberrypi/pico-bootrom に公開されています。
アセンブラとCのソースで1万行ほどありますが、2000万行を超える Linux と比較すると、小さいものです。 個人でも頑張れば動作を追っかけられる範囲でしょう。
Raspberry Pi Pico の使い方
Raspberry Pi Pico の使い方は簡単で、プログラムをUSB経由でコピーするだけです。
実行するプログラムは USB Flashing Format (UF2) という形式(拡張子が uf2)のファイルです。 サンプルプログラムをダウンロードするか、自分でプログラムを作成してビルドします。
- Raspberry Pi Pico の基板上にある BOOTSELボタンを押しながら、USBケーブルをPCに接続します。
- USBドライブとして認識されるので、uf2形式のファイルをコピーします。
- 自動的にUSBドライブが切断され、Raspberry Pi Pico上で書き込んだプログラムの実行が始まります。
Raspberry Pi Pico に関する情報源
Raspberry Pi Pico は 2021年1月21日に発表された新しい製品ですが、すでに膨大な量の情報が取得できます。 全部英語ですが、そのうち日本語の情報も増えてくると思います。
- Getting started with Raspberry Pi Pico: C/C++ development (72p)
- Raspberry Pi Pico C/C++ SDK (271p)
- API-level Doxygen documentation for the Raspberry Pi Pico C/C++ SDK
- Raspberry Pi Pico Python SDK (45p)
- Raspberry Pi Pico product brief (6p)
- Raspberry Pi Pico datasheet (29p)
- Raspberry Pi RP2040 datasheet (637p)
- Hardware design with RP2040 (30p)
また ARM Cortex-M0+ の CPU に関する ARMv6-M のマニュアルである「Armv6-M Architecture Reference Manual」 は https://developer.arm.com/documentation/ddi0419/latest/ からダウンロードできます。 これも374ページあります。
Raspberry Pi Pico のCPU
Raspberry Pi Pico のCPUは、RP2040 という名称の 2コアの Arm Cortex-M0+ というプロセッサです。 チップ内に 264KB の SRAM を持っていて、最大 133MHz で動作します。
Arm Cortex-M0+ は、Crotex-A シリーズのような普通の32ビット や 64ビット のARMプロセッサ(1命令が32ビット)とは異なり、1命令が16ビットの Thumb 命令セットで動作します。プログラムが小さくなる効果があるらしいです。 私自身は Thumb 命令セットを使ったアセンブリプログラミングをしたことがないので、そのうち始めようかと思っています。
メモリマップ
先頭の16KBにブート用のROMが置かれます。その後ろに実行用のプログラムが置かれる2MBのフラッシュメモリの領域があって、フラッシュメモリ上で直接プログラムが実行されます。フラッシュメモリの領域はプログラムから書き換えはできません。 データは読み書き、実行が可能なスタティックRAM領域に置かれます。
pico-sdk を使ってビルドすると、リンカスクリプトが自動的に以下の配置となるように設定してくれるので、アドレスを意識する必要はありません。
ROM(16KB) | 0x00000000 |
: | |
0x00003FFF | |
Flash(2MB) | 0x100000000 |
: | |
0x1001FFFFF | |
SRAM(256KB) | 0x20000000 |
: | |
0x2003FFFF | |
SCRATCH_X(4KB) | 0x20040000 |
: | |
0x20040FFF | |
SCRATCH_Y(4KB) | 0x20041000 |
: | |
0x20041FFF |
ピンヘッダのハンダ付け
ハンダゴテ が必要で、初めての人には一番難易度が高い部分かもしれません。 少し練習して、ハンダゴテの先でピンとハンダを先に加熱して、最後に基板のスルーホールにハンダが流れるようにすればできると思います。私は小学生の時からやってました。 今はかなりの老眼で、数年ぶりでしたが大丈夫でした。
ピンヘッダ を使うと ブレッドボード に固定して、ジャンパーワイヤ で回路を仮組みできます。 また、
Pimoroni の Pico Display Pack 等を接続するためにも必要となります。
Raspberry Pi 4B に開発環境を構築
開発環境は、Raspberry Pi上で構築するのが最も簡単ということで、最初は素直に従うことにします。 Raspberry Pi のホームディレクトリで以下のコマンドを実行します。
wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh chmod +x pico_setup.sh ./pico_setup.sh
pico_setup.sh が行うのは以下のような作業です。
- まず pico というディレクトリを作成します
- 必要なLinux のパッケージをインストールします。
- pico-sdk、pico-examples、pico-extras、pico-playground をリポジトリからダウンロードします。
- ~/.bashrc で PICO_SDK_PATH、PICO_EXAMPLES_PATH、PICO_EXTRAS_PATH、PICO_PLAYGROUND_PATH を定義します。
- pico-examples/build/blink と pico-examples/build/hello_world でblinkとhello_world のサンプルをビルドします。
- picotoolをダウンロードしてビルドし、/usr/local/bin にコピーします。
- picoprobeをダウンロードしてビルドします。
- デバッグサポート用の OpenOCD をダウンロードしてビルドします。
- Visual StudioCodeをダウンロードしてインストールします。
- 必要なVisualStudio Code拡張機能をインストールします。
- Raspberry Pi Picoで使用するために Raspberry Pi の UARTを設定します。
x86_64(amd64) の Ubuntu 20.10 が動作しているデスクトップマシンでは、以下のコマンドでインストール可能でした。
$ SKIP_VSCODE=1 ./pico_setup.sh
Raspberry Pi 用の Visual Studio Code のインストールを行わないように「SKIP_VSCODE=1」を指定しています。 「sudo: raspi-config: コマンドが見つかりません」というエラーが表示されますが、問題ありません。
pico ディレクトリの構成
pico というディレクトリは以下のような構成となりました。 「Lチカ」と「Hello world」のサンプルは pico-examples/build 以下にビルドされています。
jun@raspberrypi ~/pico $ du . --max-depth 2 24 ./pico-playground/audio 32 ./pico-playground/sleep 28 ./pico-playground/standalone 2084 ./pico-playground/.git 20 ./pico-playground/reset 3828 ./pico-playground/scanvideo 28 ./pico-playground/net 272 ./pico-playground/apps 24 ./pico-playground/stdio 6368 ./pico-playground 18708 ./openocd/jimtcl 1432 ./openocd/contrib 3236 ./openocd/testing 109832 ./openocd/src 1244 ./openocd/doc 232 ./openocd/tools 1428 ./openocd/autom4te.cache 12 ./openocd/.github 11400 ./openocd/.git 3532 ./openocd/tcl 154548 ./openocd 20 ./pico-examples/ide 43432 ./pico-examples/build 652 ./pico-examples/spi 680 ./pico-examples/i2c 32 ./pico-examples/hello_world 44 ./pico-examples/multicore 1292 ./pico-examples/pio 52 ./pico-examples/dma 12 ./pico-examples/blink 44 ./pico-examples/rtc 204 ./pico-examples/usb 44 ./pico-examples/pwm 20 ./pico-examples/watchdog 44 ./pico-examples/timer 64 ./pico-examples/adc 28 ./pico-examples/interp 32 ./pico-examples/picoboard 1124 ./pico-examples/gpio 12 ./pico-examples/divider 76 ./pico-examples/flash 2452 ./pico-examples/.git 20 ./pico-examples/reset 44 ./pico-examples/clocks 28 ./pico-examples/cmake 56 ./pico-examples/system 32 ./pico-examples/uart 50576 ./pico-examples 8 ./pico-sdk/external 6724 ./pico-sdk/src 172 ./pico-sdk/test 432 ./pico-sdk/tools 49852 ./pico-sdk/lib 28540 ./pico-sdk/.git 64 ./pico-sdk/cmake 228 ./pico-sdk/docs 86056 ./pico-sdk 9508 ./picoprobe/build 68 ./picoprobe/src 592 ./picoprobe/.git 10180 ./picoprobe 8 ./pico-extras/external 928 ./pico-extras/src 36 ./pico-extras/test 9464 ./pico-extras/lib 12736 ./pico-extras/.git 23204 ./pico-extras 4860 ./picotool/build 24 ./picotool/clipp 36 ./picotool/picoboot_connection 464 ./picotool/.git 12 ./picotool/cmake 5536 ./picotool 398652 .
USBシリアル通信アダプタの接続
ビルドに使った Raspberry Pi は少し離れた場所にあるので、今回は先月(2021-01-14)届いて Ubuntu 20.10 が動作しているデスクトップマシン (Ryzen9 5900X, RTX3070, 32GB, SSD1TB) に、玄箱PROで使っていた FT232RX というFT232RLを使ったUSBシリアル通信アダプタの基板を使いました。
FT232RL が内蔵されたより新しいコンパクトなものは USB-TTLシリアルケーブル や、もっと小型の USB-TTLシリアルアダプター もあるようです。
基板などの固定には、最近 耐震ジェルというか粘着マット を愛用していて、キーボードや色々なデバイスの仮止めやデスクトップマシンの防振にも重宝しています。 ホコリなどで少々汚れても洗剤で洗えば粘着力が復活する点も良いです。
ケーブルの接続は、シリアルアダプタ側の送信(TX)を Raspberry Pi Pico の受信(RX)に接続して(緑)、シリアルアダプタ側の受信(RX)を Raspberry Pi Pico の送信(RX)に接続します(黃)。
FT232RL | Pico | ||||
---|---|---|---|---|---|
GND | 青 | 黃 | GP0 | UART0 TX | |
DTR | - | 緑 | GP1 | UART0 RX | |
TXD | 緑 | 青 | GND | - | |
RXD | 黃 | - | GP2 | - | |
DCD | - | - | GP3 | - |
Raspberry Pi Pico で実行
Linux の dmesg コマンドで、USBシリアル通信アダプタを認識していることを確認します。
sudo dmesg
[ 213.427292] usb 3-3: new full-speed USB device number 5 using xhci_hcd
[ 213.601586] usb 3-3: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
[ 213.601587] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 213.601588] usb 3-3: Product: FT232R USB UART
[ 213.601588] usb 3-3: Manufacturer: FTDI
[ 213.601588] usb 3-3: SerialNumber: A1000oKG
[ 213.616065] usbcore: registered new interface driver usbserial_generic
[ 213.616071] usbserial: USB Serial support registered for generic
[ 213.617966] usbcore: registered new interface driver ftdi_sio
[ 213.617970] usbserial: USB Serial support registered for FTDI USB Serial Device
[ 213.618005] ftdi_sio 3-3:1.0: FTDI USB Serial Device converter detected
[ 213.618021] usb 3-3: Detected FT232RL
[ 213.624661] usb 3-3: FTDI USB Serial Device converter now attached to ttyUSB0
hello_serial.uf2
pico/pico-examples/hello_world/serial をビルドすると、以下のように多くのファイルが生成されます。 Raspberry Pi Pico で実行するのは hello_serial.uf2 です。 hello_serial.dis は逆アセンブルされたリストです。 CMakeFiles/hello_serial.dir/link.txt は最終的にリンクに使ったコマンドと思われます。 リンカ(ld) に大量のオプションを渡しているのが分かります。
jun@raspberrypi ~/pico/pico-examples/build/hello_world/serial $ ls -lt
total 1124
-rw-r--r-- 1 jun jun 50688 Feb 10 01:18 hello_serial.uf2
-rw-r--r-- 1 jun jun 384039 Feb 10 01:18 hello_serial.dis
-rwxr-xr-x 1 jun jun 25120 Feb 10 01:18 hello_serial.bin
-rw-r--r-- 1 jun jun 70727 Feb 10 01:18 hello_serial.hex
-rwxr-xr-x 1 jun jun 396136 Feb 10 01:18 hello_serial.elf
-rw-r--r-- 1 jun jun 223313 Feb 10 01:18 hello_serial.elf.map
drwxr-xr-x 3 jun jun 4096 Feb 10 01:17 CMakeFiles
-rw-r--r-- 1 jun jun 81567 Feb 10 01:17 Makefile
-rw-r--r-- 1 jun jun 1002 Feb 10 01:17 cmake_install.cmake
~/pico/pico-examples/build/hello_world/serial にある hello_serial.uf2 を Raspberry Pi Pico に書き込みます。 BOOTSELボタンを押しながら、USBケーブルを接続して電源を入れたときに現れるドライブにコピーするだけです。 自動的に hello_serial.uf2 が実行されます。
母艦の Linux で以下のようなコマンドを実行すると Raspberry Pi Pico が「Hello, world!」を出力している様子が確認できます。cu コマンドがインストールされていない場合は「sudo apt install cu」でインストールできます。
$ sudo chmod 777 /dev/ttyACM0 $ cu --line /dev/ttyACM0 --speed 115200 Connected. Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!
cu を終了するためには「~.」を入力します。
hello_usb.uf2
hello_usb.uf2 を使うと、USBケーブルをシリアル通信に使用する事ができます。 この場合はシリアル通信アダプタは不要です。
~/pico/pico-examples/build/hello_world/usb $ ls -lt
total 1596
-rw-r--r-- 1 jun jun 73728 Feb 10 01:18 hello_usb.uf2
-rw-r--r-- 1 jun jun 579500 Feb 10 01:18 hello_usb.dis
-rwxr-xr-x 1 jun jun 36660 Feb 10 01:18 hello_usb.bin
-rw-r--r-- 1 jun jun 103167 Feb 10 01:18 hello_usb.hex
-rw-r--r-- 1 jun jun 285133 Feb 10 01:18 hello_usb.elf.map
-rwxr-xr-x 1 jun jun 508796 Feb 10 01:18 hello_usb.elf
drwxr-xr-x 3 jun jun 4096 Feb 10 01:17 CMakeFiles
-rw-r--r-- 1 jun jun 115822 Feb 10 01:17 Makefile
-rw-r--r-- 1 jun jun 999 Feb 10 01:17 cmake_install.cmake
$ sudo chmod 777 /dev/ttyUSB0 $ cu --line /dev/ttyUSB0 --speed 115200 Connected. Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!
Cで作成されたサンプルソースのビルドが、Raspberry Pi4B を使うと簡単にできることが分かりましたが、うらで cmake が大量の作業をしている事がわかります。 Raspberry Pi Pico の征服は遠い道のようです。