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の設定と確認を行ってみたいと思います。