1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

picotoolで設定だけを書き換える - Raspberry Pi PicoのFlash活用術

Last updated at Posted at 2025-03-25

picotool1 はもっぱらファームウェア書き込みツールとして利用されることが多い、Raspberry Pi Pico 公式ツールですが、ファームウェア書き込みだけでなくフラッシュメモリの任意の領域のデータを読み書きする機能を備えています。これを使えば「設定だけ後から書き換える」運用ができます。

設定を書き換えられると何がうれしいのか?

pico-examples2などもそうなのですが、ホビー向けのサンプルプログラムではWi-FiのSSIDやパスワードなどの設定をソースコードベタ書きでファームウェアに埋め込んでいる例が多いです。そのため、デバイスを別の場所で使う場面などでWi-Fiの設定を変更するには、ソースコードからビルドしなおす必要がありけっこう面倒です。ファームウェアとは別に設定情報だけ書き換えられるなら、デバイスの運用はずっとラクになります。

設定情報を書き込む手順

例えば、Picoのオンボードフラッシュメモリを以下のようなレイアウトで利用します。

アドレス 内容
0x10000000〜 ファームウェア
0x10100000〜 設定情報

1. 設定ファイル setting.txt を用意する

ホストPCで、設定ファイル setting.txt を作成します。

setting.txt
MySSID
MyPassword

プレーンテキストで記述し、行末の改行(\n)を忘れずに。

2. 設定ファイルをフラッシュメモリへ書き込む

picotool load -o 0x10100000 -t bin setting.txt

この例ではpicotool loadコマンドに-o オプションを付与し、フラッシュメモリの先頭(0x10000000)から1MBオフセットした位置(0x10100000)に設定情報を書き込みます。-tオプションで拡張子を無視しバイナリーファイルとしてロードします。
⚠️ アドレスがファームウェア領域と重複しないよう注意してください。 設定情報を書き込む位置は、ファームウェアのサイズに応じて調整してください。

設定情報をデバイスで読み込む(C: pico-sdk)

デバイスでは設定情報を以下のように読み込みます:

example.c
#include <pico/stdlib.h>
#include <stdio.h>


#define SETTING_LOCATION  _u(0x10100000)

typedef struct {
    char ssid[32 + 1];
    char password[63 + 1];
} wifi_setting_t;

// srcバッファの'\n'で終端された文字列をdestバッファにコピー
static uint8_t *load_string(char *dest, size_t maxlen, const uint8_t *src) {
    uint8_t *end = (uint8_t *)src;
    while (*end && *end != '\n')
        end++;

    size_t len = end - src;
    if (len >= maxlen)
        len = maxlen - 1;
    memcpy(dest, src, len);
    dest[len] = '\0';
    if (len > 0 && dest[len - 1] == '\r')
        dest[len - 1] = '\0';

    return *end ? end + 1 : end;
}

// Flashから設定情報を読み込む
void load_settings(wifi_setting_t *setting, uint32_t offset) {
    uint8_t *flash = (uint8_t *)offset;
    flash = load_string(setting->ssid, sizeof(setting->ssid), flash);
    load_string(setting->password, sizeof(setting->password), flash);
}

int main() {
    wifi_setting_t setting;

    printf("Load Wi-Fi setting from Flash\n");
    load_settings(&setting, SETTING_LOCATION);
    printf("Setting: SSID=%s, password=%s\n", setting.ssid, setting.password);

    return 0;
}

実行時に XIP_BASE (0x10000000)から1MB離れた位置のバッファを、load_settings関数で読み込むだけです。オンボードフラッシュメモリの参照に特別なAPIは必要ありません。

応用: 設定情報を構造体バイナリとしてパックする

より複雑な設定情報を構成したい場合は、構造体にパックしたバイナリを書き込む方法もあります。Pythonなどで setting.bin を作成:

create_setting_bin.py
import struct
ssid = "MySSID"
password = "MyPassword"
with open("setting.bin", "wb") as f:
    f.write(struct.pack("33s64s", ssid.encode(), password.encode()))

同様にpicotoolでフラッシュメモリに書き込めば、 wifi_setting_t * にキャストするだけで利用可能です。

補足: Pico2(RP2350)はパーテーションが利用できる

RP2350を搭載したPico2はパーテーションテーブルをサポートしています。一つのフラッシュメモリを「ファームウェア用パーテーション、設定データ用パーテーション」など複数の論理的領域に分割できるので、領域ごとの用途がより明確になります。RP2350環境で設定データをフラッシュメモリに埋め込む場合はパーテーションの利用も検討してみると良いでしょう。

まとめ:picotool はファームウェアだけじゃない

  • picotool の -o オプションでフラッシュメモリの任意アドレスにデータ書き込み可能
  • 設定を分離することで、運用が圧倒的に楽になる
  • 同一ファームウェアで複数構成・複数環境に対応できる

Raspberry Pi Pico を使った小規模な組み込み開発でも、こうした工夫ひとつで運用がずっと楽になります。この例では\n区切りのプレーンテキストで設定を記述しましたが、もう少し踏み込んでJSONや.INIといった構造化テキストを書き込んで、パースして利用する方式を取ることもできます。
picotool はファームウェア書き込みだけのツールではありません。「Pico用の汎用フラッシュメモリーライター」としての活用方法をぜひ試してみてください。

関連リンク

  1. raspberrypi/picotool

  2. raspberrypi/pico-examples

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?