工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Pico搭載ブートスイッチ:電源投入前にOSを選択

電源を入れる前にスイッチを切り替えるだけで、起動するOSを事前に選択可能。OS選択のために待つ必要がなくなります。

ストーリー

Hackaday.ioでプロジェクトを物色中、Stephen Holdawayによるこのプロジェクトに出会いました。このプロジェクトでは、デュアルブートユーザーが直面する煩わしいタスク、すなわちWindowsに切り替えたいときに毎回GRUBメニューでOSを選択するために座って待つという問題を解決しています。彼はハードウェアスイッチを追加し、コンピューターの電源投入時に毎回どのOSをブートするかを決定できるようにしました。

彼はSTM32マイクロコントローラーをUSBマスストレージデバイスとして構成することでこれを実現しました。研究から実装までの全過程をHackaday投稿(クリック)で文書化しています。実装の理解を深めるために、そちらの投稿もご覧ください。

このプロジェクトでは、その変更をRaspberry Pi Picoに移植した方法を紹介します。私のバージョンはこのGitHubリポジトリ(クリック)で公開しています。

コンセプト

GNU GRUBは、オペレーティングシステムがロードされる前に実行されるプログラムです。このメニューでどのOSをロードするか選択できます。GRUBが提供するモジュールは非常に限られており、USB接続のマイクロコントローラーからデータを読み取ることはできません。しかし、ストレージディスクからデータを読み取ることは可能です。

そこで、マイクロコントローラーをマスストレージデバイスとして列挙させることで、GRUBを騙してマイクロコントローラーからデータを読み取らせます。

つまり、Raspberry Pi PicoをtinyUSBライブラリ経由でマスストレージデバイスとして列挙させ、switch.cfgファイルを持たせます。Picoはこのファイルにスイッチ位置、すなわち1でON、0でOFFを書き込みます。

GRUBにスクリプトを追加し、その機能でswitch.cfgファイルを読み取り、defaultを0(Ubuntu)/ 2(Windows)に設定します。

GRUBがロードされると、カスタムスクリプトが実行され、UUID識別子でデバイスを検索し、存在すればswitch.cfgファイルを読み取ります。スイッチ位置を取得後、抽出データに基づいてデフォルトOS選択を設定します。

まとめると、

Picoをマスストレージデバイスとして構成

tinyUSBのcdc_msc例を使用してこれを実現しました。この例ではPicoをマスストレージデバイスとして構成し、FAT12ファイルシステムを作成し、README.txtファイルを列挙します。

README.txtをswitch.cfgに変更し、ファイルに「set os_hw_switch=0\n」という行を追加。

#define SWITCH_CFG_CONTENTS \
"set os_hw_switch=0\n"
...
//------------- Block3: Readme Content -------------//
SWITCH_CFG_CONTENTS

これでPicoがマスストレージデバイスとして構成されました。UF2ファイルをPicoにコピーすると、ストレージデバイスとして列挙されます。GRUBスクリプトで必要となるデバイスのUUID IDは UUID=”0000-1234″ です。

$ sudo blkid
...
/dev/sda: SEC_TYPE="msdos" LABEL_FATBOOT="TinyUSB MSC" LABEL="TinyUSB MSC" UUID="0000-1234" BLOCK_SIZE="512" TYPE="vfat"

回路

スイッチ位置の読み取りとファイルへの書き込み

スイッチ位置を読み取り、switch.cfgファイルの内容をそれに応じて変更する必要があります:

GPIO_PIN 28をスイッチピンとして使用し、プルダウンに設定。

read_switch_valueはスイッチ位置を返します。すなわち‘1’はオン(プルアップ)、‘0’はオフ(プルダウン)。

//-------------------------main.c---------------------
#define SWITCH_PIN 28

// read switch value
uint8_t read_switch_value()
{
    return gpio_get(SWITCH_PIN) ? '1' : '0';
}

int main(void)
{
    gpio_init(SWITCH_PIN);

    // ピンをINPUTに設定
    gpio_set_dir(SWITCH_PIN, false);

    // ピンをPULL_DOWNに設定
    gpio_set_pulls(SWITCH_PIN, false, true);

switch.cfgにスイッチ位置を書き込むため、readGRUBConfig()を使用し、内部でread_switch_valueを呼び出し、出力バッファにスイッチ位置を設定します。

第3ブロックlbaが3に設定されるときに読み取りが発生することを発見し、その呼び出しをインターセプトしてreadGrubConfigを呼び出し、ファイルの内容がコピーされるバッファを渡します。

//-------------------------msc_disk.c---------------------
static char grubConfigStr[] = "set os_hw_switch=0\n";
static void readGrubConfig(uint8_t* output)
{
    // 現在のスイッチ値で設定文字列を更新
    grubConfigStr[sizeof(grubConfigStr)-3] = read_switch_value();
    memcpy(output, &grubConfigStr, sizeof(grubConfigStr));
}

// READ10コマンド受信時のコールバック。
// ディスクのデータをバッファにコピー(最大bufsize)し、コピーしたバイト数を返す。
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
    (void) lun;
    // ファイル読み取り時
    if(lba == 3){
        readGrubConfig(buffer);
        return bufsize;
    }
    ...
    ...
}

Picoコードのコンパイル

Pico stdlibをコードに追加して、gpioピンアクセスを取得。

//-------------------------main.c-----------------------------------
#include 
#include 
#include 
#include "bsp/board.h"
#include "tusb.h"
...
#include "pico/stdlib.h"

プロジェクトをビルド:

$ mkdir build
$ cd build
$ cmake ..
$ make

GRUBを設定してファイル内容を読み取る

これらの変更はUbuntu 20.10で行いました。

$ sudo vim /etc/grub.d/40_custom

....
# ハードコードされたファイルシステムIDでハードウェアスイッチデバイスを検索
search --no-floppy --fs-uuid --set hdswitch 0000-1234

# 見つかった場合、動的設定ファイルを読み取り、各位置に適切なエントリーを選択
if [ "${hdswitch}" ] ; then
    source ($hdswitch)/switch.cfg

    if [ "${os_hw_switch}" == 0 ] ; then
        # Linuxを起動
        set default="0"
    elif [ "${os_hw_switch}" == 1 ] ; then
        # Windowsを起動
        set default="2"
    else
        # フォールバック
        set default="${GRUB_DEFAULT}"
    fi

else
    set default="${GRUB_DEFAULT}"
fi

まず、ファイルシステムを検索します。GRUBにはこのためのsearchサブコマンドがあります。

デバイスが見つかった場合、最初に見つかったデバイスが環境変数の値として設定されます。

–set hdswitch hdswitch は環境変数で、見つかった場合はディスク名が設定されます。

次に、hdswitch変数が設定されている場合にswitch.cfgファイルをsourceし、別の環境変数 os_hw_switch をスイッチ位置(0または1)で作成します。

os_hw_switch の値を読み取り、defaultを0または2に設定。0はGRUBメニューでUbuntuが0番目、Windowsが2番目にあるためです。

最後に、hdswitchが設定されていなければ、defaultを GRUB_DEFAULT に設定。

GRUBを更新:

$ sudo update-grub

出典: Hardware Boot Select Switch Using Pico

製造プロセス

  1. 現代エピレーションデバイス総合ガイド:設計、歴史、未来
  2. Raspberry Pi 2とADS-WS1で屋外気象観測ステーションを構築
  3. AT89S52マイコンとLM35センサーによる温度ベース機器制御システム
  4. Raspberry Pi 3とPubNubでリモート気象監視
  5. TI SensorTagをNode-RED経由でBlynkと統合 – Raspberry Pi Zero編
  6. Raspberry PiでPIRモーションセンサーとLEDを制御
  7. Bridge Shield でスマートロボットを構築:Raspberry Pi と Arduino の統合
  8. Pythonで作るWi-Fi制御Raspberry Piロボット - ステップバイステップガイド
  9. IoTデバイス向け組み込みハードウェアハッキング:ツール、技術、ビジネスへの影響
  10. C# switch 文をマスターする:構文、例、ベストプラクティス
  11. C# usingステートメント完全ガイド:名前空間インポート、エイリアス、静的ディレクティブ