ラズパイピコでZephyrOS動かし、VS Codeでデバッグしてみよう
この投稿では、Zephyr RTOS用のアプリを作る方法と、ラズパイピコでデバッグする方法について説明します。こちらのビデオで、開発環境のセットアップ方法について説明していますので、必要に応じてそちらを先に見てください。
サンプルアプリの選択
やりたいことに近い、ベースとなるサンプルアプリを選びましょう。今回は、外部割り込みのサンプルが必要です。Zephyrのサンプルアプリフォルダーを確認してみましょう。
$ cd ~/zephyrproject/zephyr/samples
$ ls
application_development drivers posix
arch hello_world sensor
basic index.rst shields
bluetooth kernel subsys
boards modules synchronization
classic.rst net tfm_integration
compression philosophers userspace
$ cd basic
$ ls
basic.rst blinky_pwm fade_led rgb_led threads
blinky button minimal servo_motor
$ cd button
$ ls
CMakeLists.txt README.rst prj.conf sample.yaml src
ボタンサンプルのソースコードを確認してみましょう。ここに外部割り込み設定があります。
cat src/main.c
...
void main(void)
{
...
ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
...
gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb_data);
...
}
このサンプルアプリをベースにします。
スタンドアロンZephyrアプリの作成方法
アプリケーションは3種類あります。
- zephyrproject/zephyr/ フォルダーにあるアプリは、Zephyrリポジトリアプリケーションと呼ばれています。
- zephyrproject フォルダーにあるアプリは、Zephyrワークスペースアプリケーションと呼ばれています。
- zephyrproject フォルダーの外にあるアプリケーションは、Zephyr自立型アプリケーションと呼ばれています。
<home>/
├─── zephyrproject/
│ ├─── .west/
│ │ └─── config
│ ├─── zephyr/
│ │ ├── arch/
│ │ ├── boards/
│ │ ├── cmake/
│ │ ├── samples/
│ │ │ ├── hello_world/ -> Zephyrリポジトリアプリケーション
│ │ │ └── ...
│ │ ├── tests/
│ │ └── ...
│ ├── bootloader/
│ ├── modules/
│ ├── ...
│ └── applications/
│ └── app/ -> Zephyrワークスペースアプリケーション
│
└─── app/ -> Zephyr自立型アプリケーション
├── CMakeLists.txt
├── prj.conf
└── src/
└── main.c
Zephyr Project参考資料: アプリケーション開発
今回は自立型アプリケーションを作って行きます。ボタンサンプルフォルダーをコピーすることから始めましょう。プロジェクトフォルダー名やプロジェクトフォルダーパスにスペースがあるとコンパイルが通りませんので、スペースを使わないでください。
cd ~/
cp -R ~/zephyrproject/zephyr/samples/basic/button ~/Desktop/gpio_int_test
ボタンサンプルは変更なしでnucleoボード用にコンパイルできるので、最初にnucleoボード用にコンパイルしてみます。
$ cd ~/Desktop/gpio_int_test
$ west build -b nucleo_f411re
usage: west [-h] [-z ZEPHYR_BASE] [-v] [-V] <command> ...
west: error: argument <command>: invalid choice: 'build' (choose from 'init', 'update', 'list', 'manifest', 'diff', 'status', 'forall', 'help', 'config', 'topdir', 'selfupdate')
$
資料によると、いくつかの環境変数を設定する必要があります。これは、また後で直します。
Zephyr Project参考資料: 環境変数
一時的に、Zephyr環境スクリプトを実行します。これで、環境変数はターミナルが閉じるまで使えます。
$ source ~/zephyrproject/zephyr/zephyr-env.sh
$ west build -b nucleo_f411re
-- west build: generating a build system
Loading Zephyr default modules (Zephyr base).
-- Application: /Users/user/Desktop/gpio_int_test
-- Found Python3: /usr/local/opt/python@3.9/bin/python3.9 (found suitable exact version "3.9.13") found components: Interpreter
-- Cache files will be written to: /Users/user/Library/Caches/zephyr
-- Zephyr version: 3.0.99 (/Users/user/zephyrproject/zephyr)
-- Found west (found suitable version "0.13.1", minimum required is "0.7.1")
-- Board: nucleo_f411re
...
[156/156] Linking C executable zephyr/zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: 15108 B 512 KB 2.88%
SRAM: 4416 B 128 KB 3.37%
IDT_LIST: 0 GB 2 KB 0.00%
問題なくコンパイルが通りました。
VS Codeプロジェクトのセットアップ
VS CodeでスタンドアロンZephyrアプリをセットアップしましょう。コピーしたプロジェクトフォルダーをVS Codeで開きます。ビルドフォルダーを削除します。
Zephyr環境変数をプロジェクトに追加しましょう。これにより、環境変数がVS Codeターミナルに追加されます。
- 新しいフォルダーを作り、名前を .vscode にします。
- そして、中に新しいファイルを作り、名前を settings.json にします。
- ここに環境変数設定を入れます。
{ "terminal.integrated.env.osx": { "PATH": "$HOME/zephyrproject/zephyr/scripts", "ZEPHYR_BASE": "${env:HOME}/zephyrproject/zephyr", }, "terminal.integrated.env.linux": { "PATH": "$HOME/zephyrproject/zephyr/scripts:${env:PATH}", "ZEPHYR_BASE": "${env:HOME}/zephyrproject/zephyr", }, "terminal.integrated.env.windows": { "PATH": "${env:USERPROFILE}\\zephyrproject\\zephyr\\scripts;${env:PATH}", "ZEPHYR_BASE": "${env:USERPROFILE}\\zephyrproject\\zephyr", }, }
ワークスペース設定の詳細については、こちらを参照してください。
- 次に、プロジェクトを再度開き、コンパイルしてみます。
$ west build -b nucleo_f411re -- west build: generating a build system Loading Zephyr default modules (Zephyr base). -- Application: /Users/user/Desktop/gpio_int_test -- Found Python3: /usr/local/opt/python@3.9/bin/python3.9 (found suitable exact version "3.9.13") found components: Interpreter -- Cache files will be written to: /Users/user/Library/Caches/zephyr -- Zephyr version: 3.0.99 (/Users/user/zephyrproject/zephyr) -- Found west (found suitable version "0.13.1", minimum required is "0.7.1") -- Board: nucleo_f411re ... [156/156] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used FLASH: 15108 B 512 KB 2.88% SRAM: 4416 B 128 KB 3.37% IDT_LIST: 0 GB 2 KB 0.00%
問題なくコンパイルが通りました。
ボード名を設定しましょう。CMakeListsファイルを開き、cmake_minimum_required
の後にset(BOARD rpi_pico)
を足してください。
...
cmake_minimum_required(VERSION 3.20.0)
set(BOARD rpi_pico)
...
ボードオプションなしでコンパイルしてみましょう。
$ west build -p
...
/Users/user/Desktop/gpio_int_test/src/main.c:22:2: error: #error "Unsupported board: sw0 devicetree alias is not defined"
22 | #error "Unsupported board: sw0 devicetree alias is not defined"
| ^~~~~
[117/160] Building C object zephyr/drivers/gpio/CMakeFiles/drivers__gpio.dir/gpio_rpi_pico.c.obj
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake --build /Users/user/Desktop/gpio_int_test/build
ラズパイピコボードにスイッチがないため、コンパイルエラーが発生しました。
Switch0の追加
switch0を追加しましょう。このために、アプリオーバーレイファイルを使います。nucleoボードのデバイスオーバーレイファイルでswitch0の定義を確認してみましょう。
$ cat /Users/wizard/zephyrproject/zephyr/boards/arm/nucleo_f411re/nucleo_f411re.dts
...
/ {
gpio_keys {
compatible = "gpio-keys";
user_button: button {
label = "User";
gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
};
};
aliases {
led0 = &green_led_2;
sw0 = &user_button;
};
};
...
新しいファイルを作り、名前を app.overlay にします。必要なものをその中に入れましょう。
/ {
gpio_keys {
compatible = "gpio-keys";
user_button: button {
label = "User";
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
};
};
aliases {
sw0 = &user_button;
};
};
Zephyr Project参考資料: Device tree HOW TOs
私の回路で、スイッチはGPIO28に接続されています。回路図は後でお見せします。
コンパイルしてみましょう。
$ west build -p
WARNING: This looks like a fresh build and BOARD is unknown; so it probably won't work. To fix, use --board=<your-board>.
Note: to silence the above message, run 'west config build.board_warn false'
-- west build: generating a build system
...
[160/160] Linking C executable zephyr/zephyr.elf
Memory region Used Size Region Size %age Used
BOOT_FLASH: 256 B 256 B 100.00%
FLASH: 11940 B 2096896 B 0.57%
SRAM: 3760 B 264 KB 1.39%
IDT_LIST: 0 GB 2 KB 0.00%
Converting to uf2, output size: 24576, start address: 0x10000000
Wrote 24576 bytes to zephyr.uf2
$ gpio_int_test %
やったー!
バイナリファイルは build/zephyr フォルダーにあります。
westコマンドの詳細について、以下の資料を参考にしてください。
Zephyr Project参考資料: ビルド、フラッシュ、およびデバッグ
デバッグする方法
ラスパイピコ上のZephyrOS + アプリを使用したオンチップデバッグ
必要なもの
- ハードウェアデバッガインターフェイス(SWD)
- picoprobe ファームウェアが書き込まれたラスパイピコ
- オンチップデバッグ用のソフトウェア
- picoprobe用のOpenOCDビルド
- アームツールチェーン
- arm-none-eabi-gdb
- VS Code の Cortex-Debug 拡張機能
オンチップデバッグするには、いくつかのハードウェアとソフトウェアが必要です。 一つずつ準備していきましょう。
ハードウェアデバッガーインターフェイス
まずはハードウェアです。ハードウェアデバッガーインターフェイスとしてpicoprobeを使います。
picoprobe用にコンパイルされたバイナリをダウンロードし、ラズパイピコに書き込みましょう。このリンクを開き、
Debugging using another Raspberry Pi Pico
の下にある Download the UF2 file
からダウンロードしてください。
ラズパイピコのbootselボタンを押しながらパソコンに差し、ブートローダーモードにします。
$ cp ~/Downloads/picoprobe.uf2 /Volumes/RPI-RP2/
OpenOCDのビルド
現在、OpenOCDはpicoprobeを公式にサポートしていないので、picoprobe用のバージョンをビルドする必要があります。
macOS用
cd ~/
brew install libtool automake libusb wget pkg-config gcc texinfo
git clone https://github.com/raspberrypi/openocd.git --branch picoprobe --depth=1
cd openocd
export PATH="/usr/local/opt/texinfo/bin:$PATH"
./bootstrap
./configure --enable-picoprobe --disable-werror
make -j4
Linux用
cd ~/pico
sudo apt install automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev
git clone https://github.com/raspberrypi/openocd.git --branch picoprobe --depth=1 --no-single-branch
cd openocd
./bootstrap
./configure --enable-picoprobe
make -j4
sudo make i
これはOpenOCDのラズパイピコ固有のバージョンなので、「makeinstall」を実行する必要はありません。後でOpenOCDのパスを VS Code プロジェクトに設定します。
OpenOCDを確認してみましょう。
$ ~/openocd/src/openocd --version
Open On-Chip Debugger 0.11.0-g4f2ae61 (2022-06-08-15:59)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
ARMツールのインストール
macOS用
cd ~/
brew tap eblot/armeabi
brew install arm-none-eabi-gdb
arm-none-eabi-gdbを確認してみましょう。
$ arm-none-eabi-gdb --version
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
VS Codeの設定
- まず、Cortex-Debugをインストールします。
- settings.jsonファイルを開き、OpenOCDのバイナリパスを追加します。
{ "cortex-debug.openocdPath": "${env:HOME}/openocd/src/openocd", ...
- .vscodeフォルダーに新しいファイルを作り、名前を launch.json にします。そして、設定を追加します。
{ "version": "0.2.0", "configurations": [{ "name": "Pico Zephyr Debug", "device": "RP2040", "gdbPath": "arm-none-eabi-gdb", "cwd": "${workspaceRoot}", "executable": "build/zephyr/zephyr.elf", "request": "launch", "type": "cortex-debug", "servertype": "openocd", "configFiles": [ "/interface/picoprobe.cfg", "/target/rp2040.cfg" ], "searchDir": ["${env:HOME}/openocd/tcl"], "svdFile": "${env:HOME}/zephyrproject/modules/hal/rpi_pico/src/rp2040/hardware_regs/rp2040.svd", "runToEntryPoint": "main", "postRestartCommands": [ "break main", "continue" ] }] }
最終回路図
これはこれから使う回路の回路図です。左はハードウェアデバッガインターフェイス、右はボタンのあるターゲットボードです。
デバッグ開始
main.cを開き、行番号の左側をクリックします。それに応じてブレークポイントが追加されます。
デバッグする前にコンパイルすることを忘れないでください。次に、左側の「実行とデバッグ」アイコンをクリックします。「デバッグの開始」をクリックします。
やったー!
Zephyrコンソールの出力をシリアルターミナルで確認してみましょう。ボタンを押して、コンソールの出力を確認してみましょう。
素晴らしい!
スポンサーシップ
何もないところからプロジェクトを立ち上げるのは、とても時間がかかるものです。私がこの様なプロジェクトに取り組み続け、皆さんに新しいコンテンツを提供できるよう、支援をご検討いただければ幸いです。
- Patreonで支援する(月々)
- Ko-fiで支援する (一回)
- GitHubでスポンサーになる (一回/月々)
最後に
ラズパイピコ Zephyr RTOS VS Codeプロジェクトに、こちらのリンクからアクセスできます。
次のエピソードでは、ZephyrOSを使って実際のアプリケーションについて説明します。
つづく…