Raspberry Pi財団が新たに開発したマイコン「RP2040(ArmCortexM0+デュアルコア@133MHz)」を搭載した「RaspberryPi pico」が発売されました。

なんと価格が500円(税抜き)程度で購入できます。

RaspberryPi picoの最大の特徴は、プログラム可能なI/O端子を備えていることでしょう。これは、メインのCPUに影響されない単独のステートマシン(命令数9の小さなCPUみたいな)でI/Oをプログラムでき、高速な動作と幅広い用途に対応できることのようです。

今回は、母艦としてRaspberryPi4を使用し、母艦に接続するOpenOCD用アダプタに1台と開発ターゲット用に1台とRaspberryPi pico2台を使用した構成で開発環境の構築を進めていきたいと思います。

RaspberryPi picoをRaspberryPiに接続すると、新しくホルダーが開きます。
その中の2つのファイル(INFO_UF2.TXT、INDEX.HTM)のうちINDEX.HTMを開きます。
Raspberry Pi RP2040のページが開くので、下の方にスクロールして、Documentationのところで必要な資料をダウンロードします。「Getting started with Raspberry Pi Pico」が開発環境の構築についての資料になります。

「Getting started with Raspberry Pi Pico」に記述されている内容と一緒になりますが、この内容をもとに実際にインストールしてみました。

まず、ユーザーホームのトップに移動します。

$ cd ~

wgetを使用して、pico_setup.shをダウンロードします。

$ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh

pico_setup.shに実行権限を与えます。

$ chmod +x pico_setup.sh

セットアップを実行します。
ちょっと時間がかかります。
実行により、pico-sdk、pico-examples、pico-extas、.bashrcへのパスの追加、実行サンプルのビルド(blink、hello_wold)、picotool、picoprode、OpenOCD、Visual Studio Codeなどがインストールされます。

$ ./pico_setup.sh

う〜〜んと、OpenOCDのところでコンパイルエラーが発生して止まってしまいました^^;

/usr/local/include/stlink.h:29:6: error: nested redefinition of ‘enum target_state’
 enum target_state {
      ^~~~~~~~~~~~
/usr/local/include/stlink.h:29:6: error: redeclaration of ‘enum target_state’
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:61:6: note: originally defined here
 enum target_state {
      ^~~~~~~~~~~~
In file included from /usr/local/include/usb.h:11,
                 from src/jtag/drivers/arm-jtag-ew.c:25:
/usr/local/include/stlink.h:30:5: error: redeclaration of enumerator ‘TARGET_UNKNOWN’
     TARGET_UNKNOWN = 0,
     ^~~~~~~~~~~~~~
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:62:2: note: previous definition of ‘TARGET_UNKNOWN’ was here
  TARGET_UNKNOWN = 0,
  ^~~~~~~~~~~~~~
In file included from /usr/local/include/usb.h:11,
                 from src/jtag/drivers/arm-jtag-ew.c:25:
/usr/local/include/stlink.h:31:5: error: redeclaration of enumerator ‘TARGET_RUNNING’
     TARGET_RUNNING = 1,
     ^~~~~~~~~~~~~~
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:63:2: note: previous definition of ‘TARGET_RUNNING’ was here
  TARGET_RUNNING = 1,
  ^~~~~~~~~~~~~~
In file included from /usr/local/include/usb.h:11,
                 from src/jtag/drivers/arm-jtag-ew.c:25:
/usr/local/include/stlink.h:32:5: error: redeclaration of enumerator ‘TARGET_HALTED’
     TARGET_HALTED = 2,
     ^~~~~~~~~~~~~
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:64:2: note: previous definition of ‘TARGET_HALTED’ was here
  TARGET_HALTED = 2,
  ^~~~~~~~~~~~~
In file included from /usr/local/include/usb.h:11,
                 from src/jtag/drivers/arm-jtag-ew.c:25:
/usr/local/include/stlink.h:33:5: error: redeclaration of enumerator ‘TARGET_RESET’
     TARGET_RESET = 3,
     ^~~~~~~~~~~~
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:65:2: note: previous definition of ‘TARGET_RESET’ was here
  TARGET_RESET = 3,
  ^~~~~~~~~~~~
In file included from /usr/local/include/usb.h:11,
                 from src/jtag/drivers/arm-jtag-ew.c:25:
/usr/local/include/stlink.h:34:5: error: redeclaration of enumerator ‘TARGET_DEBUG_RUNNING’
     TARGET_DEBUG_RUNNING = 4,
     ^~~~~~~~~~~~~~~~~~~~
In file included from ./src/target/armv7m_trace.h:21,
                 from ./src/jtag/interface.h:30,
                 from src/jtag/drivers/arm-jtag-ew.c:23:
./src/target/target.h:66:2: note: previous definition of ‘TARGET_DEBUG_RUNNING’ was here
  TARGET_DEBUG_RUNNING = 4,
  ^~~~~~~~~~~~~~~~~~~~
In file included from src/jtag/drivers/arm-jtag-ew.c:26:
src/jtag/drivers/usb_common.h:24:10: error: ‘struct usb_dev_handle’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
   struct usb_dev_handle **out);
          ^~~~~~~~~~~~~~
src/jtag/drivers/arm-jtag-ew.c: In function ‘armjtagew_usb_open’:
src/jtag/drivers/arm-jtag-ew.c:687:2: error: implicit declaration of function ‘usb_init’; did you mean ‘ugly_init’? [-Werror=implicit-function-declaration]
  usb_init();
  ^~~~~~~~
  ugly_init
src/jtag/drivers/arm-jtag-ew.c:692:32: error: passing argument 3 of ‘jtag_usb_open’ from incompatible pointer type [-Werror=incompatible-pointer-types]
  if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
                                ^~~~
In file included from src/jtag/drivers/arm-jtag-ew.c:26:
src/jtag/drivers/usb_common.h:24:27: note: expected ‘struct usb_dev_handle **’ but argument is of type ‘struct usb_dev_handle **’
   struct usb_dev_handle **out);
   ~~~~~~~~~~~~~~~~~~~~~~~~^~~
src/jtag/drivers/arm-jtag-ew.c:702:2: error: implicit declaration of function ‘usb_claim_interface’; did you mean ‘libusb_claim_interface’? [-Werror=implicit-function-declaration]
  usb_claim_interface(dev, 0);
  ^~~~~~~~~~~~~~~~~~~
  libusb_claim_interface
src/jtag/drivers/arm-jtag-ew.c: In function ‘armjtagew_usb_close’:
src/jtag/drivers/arm-jtag-ew.c:715:2: error: implicit declaration of function ‘usb_close’; did you mean ‘libusb_close’? [-Werror=implicit-function-declaration]
  usb_close(armjtagew->usb_handle);
  ^~~~~~~~~
  libusb_close
src/jtag/drivers/arm-jtag-ew.c: In function ‘armjtagew_usb_write’:
src/jtag/drivers/arm-jtag-ew.c:752:11: error: implicit declaration of function ‘usb_bulk_write’ [-Werror=implicit-function-declaration]
  result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT,
           ^~~~~~~~~~~~~~
src/jtag/drivers/arm-jtag-ew.c: In function ‘armjtagew_usb_read’:
src/jtag/drivers/arm-jtag-ew.c:766:15: error: implicit declaration of function ‘usb_bulk_read’ [-Werror=implicit-function-declaration]
  int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN,
               ^~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[2]: *** [Makefile:3910: src/jtag/drivers/libocdjtagdrivers_la-arm-jtag-ew.lo] エラー 1
make[2]: *** 未完了のジョブを待っています....
mv -f src/jtag/drivers/.deps/libocdjtagdrivers_la-ti_icdi_usb.Tpo src/jtag/drivers/.deps/libocdjtagdrivers_la-ti_icdi_usb.Plo
mv -f src/jtag/drivers/.deps/libocdjtagdrivers_la-vsllink.Tpo src/jtag/drivers/.deps/libocdjtagdrivers_la-vsllink.Plo
mv -f src/jtag/drivers/.deps/libocdjtagdrivers_la-stlink_usb.Tpo src/jtag/drivers/.deps/libocdjtagdrivers_la-stlink_usb.Plo
make[2]: ディレクトリ '/home/rika/pico/openocd' から出ます
make[1]: *** [Makefile:5212: all-recursive] エラー 1
make[1]: ディレクトリ '/home/rika/pico/openocd' から出ます
make: *** [Makefile:2135: all] エラー 2

USB関連のエラーのようです。ちょおとくぐってみると、USB関連のパッケージ(libusb-dev)を消すとうまく行くという記事が見つかりました。
早速、libusb-devを削除して見ました。

 $ sudo apt-get remove libusb-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージは「削除」されます:
  libftdi-dev libusb-dev
アップグレード: 0 個、新規インストール: 0 個、削除: 2 個、保留: 93 個。
この操作後に 2,210 kB のディスク容量が解放されます。
続行しますか? [Y/n] y
(データベースを読み込んでいます ... 現在 186628 個のファイルとディレクトリがインストールされています。)
libftdi-dev (0.20-4) を削除しています ...
libusb-dev (2:0.1.12-32) を削除しています ...
man-db (2.8.5-2) のトリガを処理しています ...

再度セットアップを実行してみます。
結果は、またもやエラー発生!

よくパッケージを見ると、libftdi.devとlibusb-devがセットになっているようで、libftdi-devをインストールするともれなくlibusb-devもインストールされているみたいです。

pico_setup.shの内容を確認すると、OPENOCD_DEPSの項目にlibftdi-devが記載されており、強制的にlibusb-devもインストールされることがわかりました。
今回では、ftdiは使用しないので、libftdi-devを削除してみて再度インストールしてみました。

pico_setup.shのOPENOCD_DEPSの項目の先頭に#を挿入しコメントし、もとのOPENOCD_DEPSのコピーからlibftdi-devを削除しました。

#OPENOCD_DEPS="gdb-multiarch automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev"
OPENOCD_DEPS="gdb-multiarch automake autoconf build-essential texinfo libtool libusb-1.0-0-dev"

すでに作成されているlibusb-devを削除、「picoフォルダー」をフォルダーごと削除、「.bashrc」の末尾に追加された環境設定項目を削除して、再度 セットアップを実行しました。

無事セットアップ終了しました。リブートします。

$ sudo reboot

開発ターゲット用のpicoにLED点滅の例題プログラム「Blink]をインストールしてみます。

すでに例題プログラムはコンパイルされているので、該当フォルダーに移動します。

$ cd ${PICO_SDK_PATH}/../pico-examples
$ cd build/blink

書き込みファイルは「blink.uf2」ですが、ここではコマンドラインで書き込みしたいと思います。

pico本体の「BOOTSEL」ボタンを押しながら、USBをRaspberryPiのUSB端子に接続します。

接続されたストレージデバイスを確認します。

$ dmesg | tail
略
[ 1425.543882] sd 1:0:0:0: [sdb] Attached SCSI removable disk

マウントストレージは sdbでした。

マウントポイントを作成します。

$ sudo mkdir -p /mnt/pico

マウントポイントへマウントします。

$ sudo mount /dev/sdb1 /mnt/pico

現在のマウントポイントの内容を確認します。

$ ls /mnt/pico
INDEX.HTM  INFO_UF2.TXT

blink.uf2を書き込みします。

$ sudo cp blink.uf2 /mnt/pico
$ sudo sync

LEDが点滅します。

マウントを解除します。

$ sudo umount /mnt/pico

次回はopenocdの設定と確認を行ってみたいと思います。

おすすめの記事