🕌

RaspberryPi PICOのSDKで自作プロジェクトを作る

2024/12/10に公開

前回までの話

https://zenn.dev/nonnoise/articles/8c8997c2757cc0

前回までに、SDKがセッティング出来ていて、exampleがコンパイル出来ている状態での話になります。

プロジェクトを作っていく

早速プロジェクトを作っていきます。

フォルダを作成

mkdir test

フォルダ名は特に好きな場所に好きな名前で大丈夫です

プログラムソース (仮にtest.c)を作成

先ほど作ったフォルダ(test)にプログラムソースを作成します。

こちらも名前は自由ですが、一旦test.cと言う名前で作成します。

#include "pico/stdlib.h"
#define LED_DELAY_MS 250
int main() {
    gpio_init(PICO_DEFAULT_LED_PIN);
    gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(PICO_DEFAULT_LED_PIN, 1);
        sleep_ms(LED_DELAY_MS);
        gpio_put(PICO_DEFAULT_LED_PIN, 0);
        sleep_ms(LED_DELAY_MS);
    }
}

仮に、上記のようなソースをtest.cに書きます。

こちらは、PICO用のLチカソースです。PICO Wでは、LEDはモジュールの先にありますので、少しソースが変わります。PICO Wについては最後の方にまとめてあります。

CMakeLists.txt を作成

※List"s" です。毎回最後のsを忘れるので

CMakeは、この 「CMakeLists.txt」 を自動的に読みに行く仕組みです。

CMakeLists.txtは、以下の内容を記載します。

cmake_minimum_required(VERSION 3.12)  # 必要なCMakeの最小バージョンを指定
# SDKをインクルード(プロジェクト設定の前に必ず記述する必要がある)
include(pico_sdk_import.cmake)
#include(pico_extras_import_optional.cmake)  # 必要に応じて追加のライブラリをインクルード
project(pico_examples C CXX ASM)  # プロジェクト名を指定し、使用する言語を指定(C、C++、アセンブリ)
set(CMAKE_C_STANDARD 11)  # C言語の標準をC11に設定
set(CMAKE_CXX_STANDARD 17)  # C++言語の標準をC++17に設定

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})  # プロジェクトのソースディレクトリを指定
# USBからのデバッグ出力を有効にするために、接続待機時間のタイムアウトを設定
# (USBのセットアップ中にデバッグ出力が失われないようにする)
if (NOT DEFINED PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS)
    set(PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS 3000)  # デフォルトで3000ms(3秒)
endif()

# Pico SDKの初期化
pico_sdk_init()


# test.cを使って実行可能ファイル「test」を作成
add_executable(test test.c)
# 必要なライブラリをリンク(Pico標準ライブラリと、WiFiなしのアーキテクチャ)
target_link_libraries(test pico_stdlib )
# 実行可能ファイルのために、map、bin、hex、uf2ファイルなどの追加出力を生成
pico_add_extra_outputs(test)

# USB機能(tinyusb_device)がサポートされている場合
if (TARGET tinyusb_device)
    # USB出力を有効にし、UART出力を無効に設定
    pico_enable_stdio_usb(test 1)  # USBでのデバッグ出力を有効化
    pico_enable_stdio_uart(test 0)  # UARTでのデバッグ出力を無効化
endif()

# Pico Wボードがサポートされている場合(WiFi機能がある場合)
if (PICO_CYW43_SUPPORTED)  # PICO_BOARD=pico_w が設定されているときに有効
    if (NOT TARGET pico_cyw43_arch)  # WiFiアーキテクチャが利用できない場合
        message("Pico Wの例はサポートされていないためスキップします")
    else()
        target_link_libraries(test pico_cyw43_arch_none)    
        # WiFiのSSIDが環境変数に定義されていれば、それを使用
        if (DEFINED ENV{WIFI_SSID} AND (NOT WIFI_SSID))
            set(WIFI_SSID $ENV{WIFI_SSID})  # 環境変数からSSIDを設定
            message("環境変数からWIFI_SSIDを使用 ('${WIFI_SSID}')")
        endif()

        # WiFiのパスワードが環境変数に定義されていれば、それを使用
        if (DEFINED ENV{WIFI_PASSWORD} AND (NOT WIFI_PASSWORD))
            set(WIFI_PASSWORD $ENV{WIFI_PASSWORD})  # 環境変数からパスワードを設定
            message("環境変数からWIFI_PASSWORDを使用")
        endif()

        # WiFi設定をキャッシュに保存(この設定は他の部分でも使用可能)
        set(WIFI_SSID "${WIFI_SSID}" CACHE INTERNAL "WiFi SSID for examples")
        set(WIFI_PASSWORD "${WIFI_PASSWORD}" CACHE INTERNAL "WiFi password for examples")
    endif()
endif()

こちらのCMakeLists.txtは、PICOとPICO Wに対応しており、またUSBシリアルとして動くように設定してあります。

PICOのSDKでは、必要なライブラリはCMakeLists.txtに記載してリンクしていく方法になっています。

CMakeLists.txtでは色んな技や色んな設定がありますので、以下のサイトもご覧になるのも良いかと思います。

https://retrotecture.jp/picolab/0080_cmake01.html

一旦はこれで。

おぉ!CMakeの記述にコメント付けてとChatGPTにお願いしたらいい感じのコメントが。コメント書いてもらうのは良いかもね(実ソースはお勧めしない)

buildディレクトリを作成

mkdir build
cd build

これで、コンパイルの準備が出来ました。

CMake を実行

buildフォルダに移動した状態で

cp ~/pico/pico-sdk/external/pico_sdk_import.cmake ..
cp ~/pico/pico-examples/pico_extras_import_optional.cmake ..

これで、インポートするcmakeファイルをコピーしてきます。

cmake .. 

を実行すると、buildフォルダに色々と展開されます。

20241210 悲しいことに、エラーが出てしまってます。後々CMakeLists.txtを編集して直す予定です

20241211無事に解決しました

無事に終わったら、次はmakeを実行してバイナリ化します

make を実行

make

無事にコンパイルが通ると、uf2 がフォルダーにあると思いますので、そちらをPICOのUSBメモリに保存するっといった流れです。

おまけ PICO-W用プログラムソース (仮にtest_w.c)を作成

PICO-Wでは、LEDはRP2040から操作できず、無線モジュールにあるGPIO0からアクセスします。
その為、無線モジュール用ドライバを読みだす必要があります。

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#define LED_DELAY_MS 250
int main() {
    cyw43_arch_init();
    while (true) {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(LED_DELAY_MS);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(LED_DELAY_MS);
    }
}

おまけ PICO-W用CMakeLists.txt

基本的には上のCMakeと変わりなく、上のCMakeには既に無線モジュール系も含まれています。

    add_executable(test_w
    test_w.c )
    target_link_libraries(test_w pico_stdlib pico_cyw43_arch_none)
    pico_enable_stdio_usb(test_w 1)
    pico_enable_stdio_uart(test_w 0)
    pico_add_extra_outputs(test_w)

変更するとするなら、test.cだった箇所をtest_wに変更するといった地味な部分でしょうか。

おまけ PICO-W用 CMake を実行

PICO-Wでは、ボードを選択する引数が必要になります。よく忘れます。

cmake .. -DPICO_BOARD=pico_w

おまけ PICO-W用 make を実行

流石にmakeはPICOもPICO-Wも変わりあしません。

make

※よくネット記事に make -j4 とありますが、 -j4 は、コンパイルを行うPC側で4コア分使って分散コンパイルを行うというコマンドです。通常のmakeが遅い!思った際は、4コア分のj4を使ってみるのも良いかと思います。

終わりに

20241210 悲しいことに、エラーが出てしまってます。後々CMakeLists.txtを編集して直す予定です
20241211無事に解決しました

CMakeは色んなフォルダーをくっ付けたり展開したりができますので、理解してくると面白いものですが、まだまだ慣れてない為、エラーが多く出てきますね。

今後も頑張っていきたいと思います。

■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
ArtifactNoise合同会社では技術コンサルタントを行っております。
ご興味があれば是非ご連絡くださいませ。
北神雄太 kitagami(at)artifactnoise.com
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■

Discussion