見出し

ラズパイピコでZephyrOS動かし、VS Codeでデバッグしてみよう

   2022年06月16日     20分で読めます

Zephyr RTOS+ラズパイピコでデバッグ

この投稿では、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種類あります。

  1. zephyrproject/zephyr/ フォルダーにあるアプリは、Zephyrリポジトリアプリケーションと呼ばれています。
  2. zephyrproject フォルダーにあるアプリは、Zephyrワークスペースアプリケーションと呼ばれています。
  3. 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ターミナルに追加されます。

  1. 新しいフォルダーを作り、名前を .vscode にします。
  2. そして、中に新しいファイルを作り、名前を settings.json にします。
  3. ここに環境変数設定を入れます。
    {
     "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",
     },
    }
    

    ワークスペース設定の詳細については、こちらを参照してください。

  4. 次に、プロジェクトを再度開き、コンパイルしてみます。
    $ 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

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の設定

  1. まず、Cortex-Debugをインストールします。
  2. settings.jsonファイルを開き、OpenOCDのバイナリパスを追加します。
    {
     "cortex-debug.openocdPath": "${env:HOME}/openocd/src/openocd",
     ...
    
  3. .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"
     ]
      }]
    }
    

最終回路図

これはこれから使う回路の回路図です。左はハードウェアデバッガインターフェイス、右はボタンのあるターゲットボードです。

Schematic diagram

デバッグ開始

main.cを開き、行番号の左側をクリックします。それに応じてブレークポイントが追加されます。

ブレークポイント

デバッグする前にコンパイルすることを忘れないでください。次に、左側の「実行とデバッグ」アイコンをクリックします。「デバッグの開始」をクリックします。

デバッグ

やったー!

Zephyrコンソールの出力をシリアルターミナルで確認してみましょう。ボタンを押して、コンソールの出力を確認してみましょう。

デバッグとコンソールの出力

素晴らしい!

スポンサーシップ

何もないところからプロジェクトを立ち上げるのは、とても時間がかかるものです。私がこの様なプロジェクトに取り組み続け、皆さんに新しいコンテンツを提供できるよう、支援をご検討いただければ幸いです。

最後に

ラズパイピコ Zephyr RTOS VS Codeプロジェクトに、こちらのリンクからアクセスできます。

次のエピソードでは、ZephyrOSを使って実際のアプリケーションについて説明します。

つづく…