Raspberry Pi Picoのステップ実行できる開発環境づくり

Raspberry Pi 4とVSCodeを用いてRaspberry Pi Pico(RP2040)の開発環境(C言語)の構築の方法を解説します。最終的にはステップ実行・プロジェクトの新規作成までできるようになります。

  • 対象マイコン: Raspberry Pi Pico(RP2040)
  • 開発PC: Raspberry Pi 4
  • 開発OS: Raspberry Pi OS
  • IDE: Visual Studio Code (VSCode)
  • 開発言語: C言語

1. セットアップスクリプトのダウンロード・実行

ターミナル(LXTerminal)を開いてセットアップスクリプトをダウンロード・実行します。

このブログではホームフォルダ(/home/pi)でセットアップスクリプトを実施したことを前提に説明します。ターミナルを開いた時に、『pi@raspberrypi:~ $』という表示になっていなければ、『cd ~ 』コマンドにてホームフォルダ(/home/pi)に移動してから以下のコマンドを実施してください。

Terminal
# このブログではホームフォルダ(/home/pi)にて実施します。
pi@raspberrypi:~ $ cd ~

# wgetでセットアップスクリプトをダウンロード
pi@raspberrypi:~ $ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh

# スクリプトに実行権限を与える
pi@raspberrypi:~ $ chmod +x pico_setup.sh

# スクリプト実行
pi@raspberrypi:~ $ ./pico_setup.sh

# スクリプト実行後、再起動
pi@raspberrypi:~ $ sudo reboot

このスクリプトの実行で、開発環境のセットアップはほぼ完了です。 pico-sdkやサンプルコードがインストールされる他、コードエディタ・デバッガとしてVisual Studio Codeがインストールされます。



2. ボード上のLEDを点滅させてみる : 既存のUF2ファイルを使用

セットアップスクリプトにより、サンプルコードとそのビルド結果のバイナリファイル(.uf2)がpicoフォルダにダウンロードされています。

まずは既に存在しているLED点滅(blink)のバイナリファイルをRaspberry Pi Picoに書き込んで動作確認してみます。

ファイルマネージャー(もしくはターミナル)で『/home/pi/pico/pico-examples/build/blink』まで移動してください。そこに『blink.uf2』というファイルがあります。

ここでPicoボード上のBOOSELボタンを押しながら、Raspberry Pi 4 とUSBケーブルで接続します。

すると以下のようにリムーバブルメディアとして認識されます。

『OK』を押下してファイルマネージャで開き、『blink.uf2』をドラッグ&ドロップでPicoに書き込んでください。

すると、リムーバブルメディアは自動的に取り外され、Picoはプログラム実行状態になります。ボード上のLEDが点滅しているのが確認できると思います。



3. ボード上のLEDを点滅させてみる : ソース変更&ビルドしたUF2ファイルを使用

次に、自分でソースファイルを変更・ビルドして、LEDの点滅速度を変更してみます。

『/home/pi/pico/pico-examples/blink』をファイルマネージャで開き、そのフォルダ中の『blink.c』をダブルクリックしてエディタを開いてください。

18行目、20行目に『sleep_ms(250)』とありますので、この値を変更します。

/home/pi/pico/pico-examples/blink/blink.c
...

while (true) {
    gpio_put(LED_PIN, 1);
    sleep_ms(100);   // 250msの点灯時間を100msに変更
    gpio_put(LED_PIN, 0);
    sleep_ms(100);   // 250msの消灯時間を100msに変更
}

...

変更・保存後、ターミナルを開いて次のようにビルドします。

Terminal
# blinkのbuildフォルダへ移動
$ cd /home/pi/pico/pico-examples/build/blink

# ビルド
$ make -j4

ビルドが成功すると、『blink.uf2』が再度生成されます。(前から存在していた『blink.uf2』は上書きされて消えます) このuf2ファイルを、上記「2. ボード上のLEDを点滅させてみる①」の方法に従ってPicoに書き込んでみてください。 ボード上のLEDの点滅速度が変わったことが確認できると思います。



4. Visual Studio Code (VSCode) での開発環境構築

セットアップスクリプトにより既にインストールは完了していますので、メニューからVSCodeを開きます。

表示言語を日本語に変更できるようなので、一応日本語化してみます。必要なければインストールしなくても大丈夫です。英語のまま進める方は、以降の説明では適時読み替えてください。 もし『インストールして再起動』の表示が消えてしまった場合、右下の鈴(ベル)マークをクリックすると再表示できます。

日本語化が完了すると、次のような画面になります。『フォルダを開く』より『/home/pi/pico/pico-examples』フォルダを開いてください。

『このフォルダー内のファイルの作成者を信頼しますか?』と聞かれますので、『親フォルダー'pico'内のすべてのファイルの作成者を信頼します』にチェックを入れ、『はい、作成者を信頼します(フォルダーを信頼してすべての機能を有効にする)』をクリックします。

次に、右下に『Would you like to configure project 'pico-examples'? ソース:CMake Tools(拡張機能)』と表示されますので、『Yes』を押下します。 もしこの表示が消えてしまった場合は、VSCodeを再起動することで再度表示されます。

次に、右下に『Always configure projects upon opening?』と表示されますので、ここでは『Yes』を押下します。 もしこの表示が消えてしまった場合は、右下のベルマークをクリックすることで再表示できます。

次に、コンパイラを選択します。上部に『Select a Kit for pico-examples』と表示されますので、ここでは『GCC 7.3.1 arm-none-eabi』をクリックします。 もしこの表示がされていない、又は消えてしまった場合は、下の『No Kit Selected』をクリックすることで表示できます。

次に、『CMake Tools がこのフォルダーに対して IntelliSense を構成しようとしています。』と表示されますので、『許可する』をクリックします。 もしこの表示がされていない、又は消えてしまった場合は、ベルマークをクリックすることで再表示できます。

ここで、左側のエクスプローラーから、『blink』をクリックし、展開された中身の『bilnk.c』をクリックしてソースコードを開きます。 問題なければコード上に赤線等が引かれたりしていないはずです。 18行目と20行目の『sleep_ms』の値を1000(1秒)に変更して保存してください。

次に、一旦ビルドしてみます。左側の上から6番目のアイコン(CMake)をクリック後、blinkの右側のアイコンをクリックすることでビルドできます。

ここで『2. ボード上のLEDを点滅させてみる①』の手順に従って、Picoに書き込んでみます。1秒間隔でボード上のLEDが点滅する事が確認できると思います。



5. Visual Studio Code (VSCode) でステップ実行できるようにする

コードの行にブレークポイントを設定してそこで動作を止め、キー押下にて一行ずつコードを実行することができます。 動作が見えにくいマイコン開発では、これができるか否かで開発効率が大きく変わります。

ターミナルを開き次のコマンドを実行します。

Terminal
$ cd ~/pico/pico-examples

# .vscodeフォルダが既に存在する場合は不要
$ mkdir .vscode

$ cp ide/vscode/launch-raspberrypi-swd.json .vscode/launch.json

$ cp ide/vscode/settings.json .vscode/settings.json

次に、VSCodeの左側アイコンの『実行とデバッグ(Ctrl+Shift+D)』→『Pico Debug』ボタンの右の歯車ボタンを押下して、launch.json を開きます。

launch.json の 14行目辺りにある"configFiles"を次のように変更します。

launch.json
"configFiles": [
    "/home/pi/pico/openocd/tcl/interface/raspberrypi-swd.cfg",
    "/home/pi/pico/openocd/tcl/target/rp2040.cfg"
],

変更・保存が完了したら、Raspberry Pi 4 と Pico を次のように繋ぎます。

次に、VSCodeのblink.cの適当な箇所(ここでは14行目)の左側をクリックしてブレークポイントを設定後、『Pico Debug』の左側の実行ボタンを押下します。

成功すると次のような画面となります。上部の矢印ボタン(ステップオーバー[F10])を押下すると、一行ずつプログラムが実行できます。

もし、次の画面のように『Failed to launch GDB: Error erasing flash with vFlashErase packet (from target-download) 』といった表示が行われ、デバッグモードに入れない場合は、 『/home/pi/pico/openocd/tcl/interface/raspberrypi-swd.cfg』をエディタで開き、『adapter speed 1000』の部分を『adapter speed 100』等、数値を下げて保存後、再度試してみてください。

それでも上手くいかない場合は、以下を試してみてください。

  • launch.json の configFiles のパスが正しいフルパスとなっているか確認する。(初期状態だと恐らくパスが通っていません)
  • 配線を見直す、又は配線を短くする。
  • 『/home/pi/pico/openocd/tcl/interface/raspberrypi-swd.cfg』の『adapter speed 1000』の"1000"を"10"に変更してみる。(その後、問題なければ微調整してスピードを上げてみる)
  • PicoのUSBケーブルを一時的に外し、BOOTSELボタンを押しながらUSBを接続後、再度試してみる。
  • VNCを使用している場合は切断し、モニタ・キーボード・マウスを接続して直接操作してみる。
  • 外部電源付きのUSBハブを使用し、PicoのUSB接続をそちらで行う。


6. プロジェクトの新規作成

サンプルコードを変更して目的のプログラムを作成する事も出来ますが、プロジェクトを新規作成する方法を説明します。ターミナルを開いて次のコマンドを実行します。

Terminal
# ここでは自分の開発用プロジェクトフォルダとして『/home/pi/pico/myproj』フォルダを作成します。
$ mkdir /home/pi/pico/myproj

$ git clone https://github.com/raspberrypi/pico-project-generator.git

$ cd pico-project-generator

$ ./pico_project.py --gui

これで次のようなプロジェクトジェネレーターの画面が表示されます。

ここではPicoボード上のPicoボード上のLEDを点滅させる(GPIO出力)だけの "LedTest"というプロジェクトを作成してみます。

  • ①: プロジェクト名を入力します。
  • ②: プロジェクトを作成するフォルダを入力します。今回は初めに作成した『/home/pi/pico/myproj』フォルダにプロジェクトを作成します。
  • ③: 今回は『Console over UART』は使用しないので無効にします。
  • ④: VSCodeで開発するので、『Create VSCode project』を有効にします。
  • ⑤: SWDにてデバッグするので、『SWD』を選択します。
  • ⑥: OKボタンを押下して、プロジェクトを作成します。
  • ⑦: 自動作成完了後OKボタンを押下します。
  • ⑧: Quitボタンを押下してウィンドウを閉じます。

次に、VSCodeで生成された『LedTest』プロジェクトフォルダを開いてみます。

フォルダ選択後はしばらく待ちます。するとKit(コンパイラ)の選択ができるようになります。ここでは『GCC 7.3.1 arm-non-ebi』を選択します。

その後、次の画像のように左側の『実行とデバッグ』アイコンをクリック後、歯車ボタンをクリックして launch.json を開きます。

launch.json の 16行目辺りにある"configFiles"を次のように変更し、上書き保存します。

launch.json
"configFiles": [
    "/home/pi/pico/openocd/tcl/interface/raspberrypi-swd.cfg",
    "/home/pi/pico/openocd/tcl/target/rp2040.cfg"
],

次に、『Coretex Debug』の左側の実行ボタンを押下して実行します。(ここでは失敗しますが、ここで失敗を確認しないと次の手順が上手くいきません)

すると次の画像のように出力ウィンドウに『[main] No program will be executed』と表示され、デバッグの実行の失敗が確認できます。


次に、左側の『CMake』のアイコンを押下後、『すべてのプロジェクトの構成』ボタンをクリックし、下の出力ウィンドウの表示が落ち着いたら、ツリーのLedTestのアイコン(Target LedTest)を右クリックし『起動またはデバッグターゲットとして設定』をクリックします。


再度、左側の『実行とデバッグ』のアイコンを押下後、『Coretex Debug』の左側の実行ボタンを押下して実行してみます。


しばらく待つと、ステップ実行が可能になります。


もしここで上手くいかない場合は配線(配線方法)を見直した後、『/home/pi/pico/openocd/tcl/interface/raspberrypi-swd.cfg』の『adapter speed 1000』を『adapter speed 30』等に変更・保存して再度試してみてください。 (私の場合は配線が長すぎるためかよく失敗しますので、『adapter speed』 は "30" としています。)

また、上記の デバッグ実行→『[main] No program will be executed』の確認→『すべてのプロジェクトの構成』→『起動またはデバッグターゲットとして設定』の順番も大事です。この順番が異なると設定が上手くいかず『[main] No program will be executed』の表示のままとなってしまいます。


プロジェクトの新規作成の流れは以上です。

LedTest.cの中身を以下のように変更後、実行して想定通りボード上のLEDが点滅することを確認してみると良いと思います。

LedTest.c
#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    const uint LED_PIN = PICO_DEFAULT_LED_PIN;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(500);
        gpio_put(LED_PIN, 0);
        sleep_ms(500);
    }
}  


7. ソースファイルの追加

プロジェクトの作成にて作成したプロジェクトに別のソースファイルを追加してみます。 ここではRP2040内臓に実装されている温度センサーの値を取得するソースファイルを追加します。次に、その値に従ってLEDの点滅速度を変更してみます。

まずはエクスプローラーの上のファイル追加アイコンで、『OnChipTemp.c』、『OnChipTemp.h』を追加します。


『OnChipTemp.c』、『OnChipTemp.h』を次のように編集・保存します。

OnChipTemp.c
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"

void temp_adc_init()
{
    // AD変換器を初期化
    adc_init();

    // 1つのAD変換器にスイッチすることで、最大5入力分の値を得られる仕組み。
    // 0〜3番のスイッチはGPIO26〜29に対応。
    // 4番目のスイッチは内蔵温度センサーに対応している。
    adc_select_input(4);

    // RP2040内臓の温度センサーを起動
    adc_set_temp_sensor_enabled(true);
}

float get_temp()
{
    const float conversion_factor = 3.3f / (1 << 12);
    uint16_t adc_val = adc_read();
    float voltage = adc_val * conversion_factor;
    float temp = 27 - (voltage - 0.706) / 0.001721;
    return temp;
}      

OnChipTemp.h
void temp_adc_init();
float get_temp();

次に、『LedTest.c』を次にように編集します。

LedTest.c
#include <stdio.h>
#include "pico/stdlib.h"
#include "OnChipTemp.h"           // 追加

int main()
{
    temp_adc_init();               // 追加

    const uint LED_PIN = PICO_DEFAULT_LED_PIN;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);

    while (true) {
        float temp = get_temp();   // 追加
        int wait_ms = temp * 20;   // 追加

        gpio_put(LED_PIN, 1);
        sleep_ms(wait_ms);         // 変更
        gpio_put(LED_PIN, 0);
        sleep_ms(wait_ms);         // 変更
    }
}

次に、『CMakeLists.txt』の『add_executable』と『target_link_libraries』の行を編集します。

CMakeLists.txt
# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.13)

...

# OnChipTemp.c を追記
add_executable(LedTest LedTest.c OnChipTemp.c)

...

# hardware_adc を追記
target_link_libraries(LedTest pico_stdlib hardware_adc)

...

target_link_libraries に追記した『hardware_adc』ですが『hardware/adc.h』の参照に必要で、記述がなければビルドに失敗します。 この『hardware_adc』等の名称はサンプルプログラムのCMakeLists.txt(今回であれば『/home/pi/pico/pico-examples/adc/hello_adc/CMakeLists.txt』)の target_link_lisbraries の行を参照するのが簡単かと思います。

『CMakeLists.txt』の編集・保存が完了すると、『OnChipTemp.c』の『#include "hardware/adc.h"』に引かれていた赤い波線が自動的に消えると思います。

これで実行可能な状態となりましたので、デバッグを開始して正しく動作しているかどうか確認してみてください。


コメント

このブログの人気の投稿

v4l2-ctlで行うUSBカメラ設定方法まとめ

Raspberry Piでシリアル通信する方法(通信設定・通信確認)