0
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?

訳:MicroPythonOS Documentation

0
Posted at

一部の章は未翻訳です。順次翻訳範囲を拡大します。

MicroPythonOS ドキュメント

ホーム

MicroPythonOSの公式ドキュメントへようこそ。MicroPythonOSは、MicroPythonで完全に構築された軽量かつ多機能なオペレーティングシステムです。ESP32などのマイクロコントローラやデスクトップシステム向けに設計されたMicroPythonOSは、アプリのエコシステム、App Store、OTA(Over-The-Air)アップデートを備えた、Androidにインスパイアされたモダンなインターフェースを提供します。

MicroPythonOSの動作を確認するには、公式サイトのスクリーンショットと画面動画をご覧ください。

MicroPythonOSについて

MicroPythonOSは、IoTデバイス、スマートウェアラブル、教育ツールなどを開発する開発者やイノベーター向けに設計されています。主な機能は以下のとおりです。

  • ネイティブMicroPython:迅速な開発のために、アプリとドライバをMicroPythonで記述します。
  • クロスプラットフォーム対応:ESP32マイクロコントローラー、Linuxデスクトップ、そして将来的にはmacOSやRaspberry Piでも動作します。
  • モダンUI:ジェスチャー操作に対応したAndroidライクなタッチスクリーンインターフェース。
  • アプリエコシステム:組み込みアプリとアプリストアにより、簡単に拡張可能。
  • OTAアップデート:システムとアプリのアップデートがシームレスに行われます。

このドキュメントには、開始に必要なすべての情報、アーキテクチャの理解、システムの構築、およびアプリケーションの開発に関する情報が記載されています。

対象読者

  • 開発者向け:MicroPythonOSのインストール、ビルド、および新しいアプリや機能による拡張方法を学びましょう。
  • 管理者の方へ:システムの機能、対応ハードウェア、プロトタイプ作成や量産にすぐに使える機能をご確認ください。

貢献する

MicroPythonOSへの貢献にご参加ください。

概要

MicroPythonOSは、ESP32などのマイクロコントローラやデスクトップ環境向けに設計された、MicroPythonで完全に記述された軽量オペレーティングシステムです。Androidに触発され、すべてがアプリとなる「薄型」OSモデルを採用しているため、開発者はアプリケーションを簡単に構築・展開できます。

主な機能

  • クロスプラットフォーム:ESP32、Linuxデスクトップ、そして将来的にはmacOSとRaspberry Piで動作します。
    タッチスクリーンUI:Androidにインスパイアされた、モダンなジェスチャーベースのインターフェース。
  • App Store:アプリをスムーズにダウンロードしてインストールできます。
  • OTAアップデート:システムとアプリを簡単に最新の状態に保ちます。
  • ハードウェアサポート:タッチスクリーン、IMU、カメラなど。
  • 軽量:リソースが限られたデバイス向けに最適化されており、起動時間が高速です。

利点

  • MicroPython Foundation:使い慣れたPythonベースの言語で開発を簡素化します。
  • クロスプラットフォーム互換性:マイクロコントローラーからデスクトップまで、あらゆる場所に展開可能。
  • リソース効率:メモリ容量と消費電力の少ないデバイス向けに設計されています。
  • 最新のインターフェース:タッチスクリーンとジェスチャー操作に対応し、直感的な操作を実現します。
  • 拡張性:App Store経由で新しいアプリや機能を簡単に追加できます。

ユースケース

MicroPythonOSは、幅広いアプリケーションを支えています。

  • スマートホームコントローラーなどのIoTデバイス。
  • インタラクティブなディスプレイを備えた教育ツール。
  • ビットコイン・ライトニングを利用した分散型決済システム。
  • 携帯型タッチスクリーンデバイスとスマートウェアラブル。
  • IMUとカメラを搭載したロボット。
  • DIYプロジェクトのための迅速なプロトタイピング。

スクリーンショット

MicroPythonOSの動作を確認するには、公式サイトのスクリーンショットと画面動画をご覧ください。

はじめる

概要

MicroPythonOS をすぐに使い始めましょう。このセクションでは、デバイスやデスクトップに OS をデプロイするためのインストール方法とサポートされているハードウェアについて説明します。

  • 実行する:MicroPythonOSをインストールして実行するためのステップバイステップガイド。
  • 対応ハードウェア:互換性のあるデバイスおよびプラットフォーム。

実行

実行する

MicroPythonOSは、対応するマイクロコントローラ(例:ESP32)およびデスクトップシステム(Linux、Raspberry Pi、macOS、Windowsなど)上で動作します。

プリビルド済みソフトウェアをインストールするには、続きをお読みください!

内部の低レベルな部分を変更するには、OS開発のセクションを参照してください。

ESP32上で動作

install.micropythonos.com にある WebSerial インストーラーを使用するだけです。

ファイルを使用せずに開発ビルドをインストールするなど、高度な使用方法については、「ESP32 へのインストール」を参照してください。

デスクトップで実行する

  1. internal_filesystem/フォルダがあることを確認してください
    ソースコードからビルドした場合、既にそれを含むローカルクローンが存在するはずです。
    事前にビルドされたバイナリを使用する場合は、リリースぺージまたはメインブランチから付属の「ソースコード」zipファイルをダウンロードして解凍してください。

  2. ソフトウェアが揃っていることを確認してください
    最も簡単な方法は、リリース ページから事前にビルドされたバイナリ(MicroPythonOS_arm64_macOS_0.9.0.binMicroPythonOS_x64_linux_0.9.0.elfなど)をダウンロードすることです。
    ダウンロード後、以下のように適切な場所に保存してください。

    mkdir -p lvgl_micropython/build # do this from the top level folder MicroPythonOS from step 1
    cp /Users/yourname/MicroPythonOS_amd64_macOS_0.7.1.bin lvgl_micropython/build/lvgl_micropy_macOS # for macOS
    cp /home/yourname/MicroPythonOS_amd64_linux_0.7.1.elf lvgl_micropython/build/lvgl_micropy_unix # for Linux or WSL2 on Windows 11
    

    あるいは、事前にビルドされたバイナリをダウンロードする代わりに、ソースからビルドすることもできます。その場合、ビルドされたバイナリは lvgl_micropython/build/lvgl_micropy_XXX に格納されます(XXX は Unix または macOS を表します)。

  3. ソフトウェアを起動します。
    これで実行準備が整いました:

    ./scripts/run_desktop.sh
    

macOSに関するメモ

/opt/homebrew/opt/libffi/lib/libffi.8.dylib が見つからないというエラーが表示された場合は、brew install libffi で修正してください。

コードが署名されていないというエラーが表示された場合は、次のようにして許可してください。

デスクトップでの変更

internal_filesystem/ 内のファイルを変更すると、ファイルを再読み込みしたりアプリを再起動したりすると、デスクトップにその変更がすぐに反映されることに気づくでしょう。

./scripts/run_desktop.sh を実行すると、OS は内部ファイルシステムから直接 MicroPythonOS スクリプトを実行します。これはつまり:

  • Pythonファイルへの変更はすべて即座に反映されます - ビルドやインストールは不要
  • 即時テスト - ファイルを編集し、アプリを再起動すると、変更内容が表示されます
  • 迅速な反復サイクル - 開発とテストの推奨方法

自分で試してみてください:

  1. internal_filesystem/builtin/apps/com.micropythonos.about/assets/about.py を編集します。
  2. ./scripts/run_desktop.sh を実行します。
  3. About アプリを開きます。
  4. 変更がすぐに反映されます。

ESP32での変更方法

変更内容をデスクトップ上でテストして正しく動作することを確認した後、またはデスクトップ上でテストできない作業を行う場合は、物理ハードウェアにデプロイできます。

ESP32にインストールする最も簡単な方法は、もちろんWebインストーラーを使用することです。

しかし、そこに掲載されていないバージョンをインストールする必要がある場合、または自分でビルドした場合は、ESP32デバイスに手動でインストールできます。

  1. ファームウェアを入手する

    • リリースバイナリをダウンロードします(例:MicroPythonOS_esp32_0.5.0.bin
    • または、 macOSまたはLinux上で独自のビルドを作成することもできます。
  2. ESP32をブートローダーモードにする
    MicroPythonOSが既に起動している場合は、[設定]→[ブートローダーに再起動]→[ブートローダー]→[保存]の順に進んでください。
    そうでない場合は、ボードの電源を入れる際に「BOOT」(場合によっては「START」と表示されている)ボタンを物理的に押し続けてください。詳細については、Webインストーラーを参照してください。

  3. ファームウェアをフラッシュする
    ~/.espressif/python_env/idf5.2_py3.9_env/bin/python -m esptool --chip esp32s3 write_flash 0 firmware_file.bin
    古いファイルやアプリが残らないように、フラッシュメモリ全体を消去したい場合は、--erase-allオプションを追加してください。
    また、自分でコンパイルした最新のファームウェアをフラッシュしようとする便利なスクリプト ./scripts/flash_over_usb.sh もあります。

  4. MicroPython REPLシェルにアクセスします
    リセット後、シリアル回線上でREPLシェルが利用可能になるはずです。
    シリアルクライアントであればどれでも構いませんが、lvgl_micropythonに同梱されているmpremote.pyツールを使うと便利です。
    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py

  5. ファイルシステムにデータを書き込む(開発時のみ)
    開発段階では、コンパイル時に組み込まれる「固定」ライブラリやアプリケーションを上書きし、編集可能なソースファイルに置き換えたいと思うでしょう。
    これにより、Pythonスクリプトがビルド時ではなく実行時にコンパイルされるため、MicroPythonOSの起動速度が大幅に低下します。しかし、MicroPythonOSとテスト対象のコードがロードされると、速度は正常に戻ります。
    これを自動で行ってくれる便利なスクリプトがあります。
    使用法:

    ./scripts/install.sh
    
    ./scripts/install.sh com.micropythonos.about # to install one single app
    

    macOS では、install.sh スクリプトには次のものが必要です: brew install cask serial
    少数のファイルを頻繁に更新する必要がある場合は、手動で更新することもできます。例:

    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py cp internal_filesystem/lib/mpos/device_info.py :/lib/mpos
    

注記

次のステップ

  • システムを使い始めるには、内蔵アプリを探索してみてください。

対応ハードウェア

MicroPythonOSは、マイクロコントローラからデスクトップPCまで、さまざまなプラットフォームで動作します。

ESP32マイクロコントローラー

ESP32-S3マイクロコントローラ

デスクトップコンピュータ

  • Linux:ディスプレイ処理にSDLを使用することでサポートされています。
  • macOS:サポートされています。
  • Windows:Linuxデスクトップ版がWindows 11上のWSL2で問題なく動作するとのユーザー報告がある。

Raspberry Pi

  • Raspbianやその他のLinuxベースのOS:動作するはずです!

アプリ

概要

MicroPythonOSはアプリ中心のモデルに基づいて構築されており、コア機能のための組み込みアプリと、追加アプリ用のアプリストアが用意されています。

組み込みアプリ

MicroPythonOSには、システムを起動するために必要なアプリが含まれており、/builtin/appsに配置されています。

  • ランチャー:アプリを起動し、ホーム画面を提供します。
  • WiFi:WiFi接続を設定します。
  • App Store:新しいアプリをダウンロードしてインストールします。
  • OSUpdate:無線(OTA)システムアップデートを管理します。
  • 設定:MicroPythonOSの設定

スクリーンショット


ランチャー

WiFi

App Store

OSアップデート

その他のアプリについては、App Storeをご覧ください。

App Store

MicroPythonOSアプリストアでは、ユーザーが新しいアプリをダウンロードしてインストールし、システム機能を拡張することができます。

アプリの検出は現在、 apps.micropythonos.comからアプリリストをダウンロードすることで行われています。

サンプルアプリ

  • ハローワールド:基本的な機能を示すサンプルアプリ。
  • カメラ:画像を撮影し、QRコードをスキャンします。
  • 画像ビューア:に保存されている画像を表示します/data/images/。
  • IMU:慣性計測ユニット(加速度計とも呼ばれる)からのデータを視覚化します。

スクリーンショット


App Storeのカメラアプリ

ハローワールドのインストール

カメラQRコードスキャナー

アプリ開発

アプリはMicroPythonで記述され、/apps/.にインストールされます。アプリのディレクトリ構造については、「ファイルシステムレイアウト」を参照してください。

アプリの作成

アプリはMicroPythonで記述され、/apps/.にインストールされます。アプリのディレクトリ構造については、「ファイルシステムレイアウト」を参照してください。

ここでは、シンプルなHelloWorldアプリの作成方法とインストール方法について説明します。

より高度な例はソースコードリポジトリで入手できます。

構造

以下のファイルとフォルダ構造を作成してください。

com.micropythonos.helloworld/
├── assets/
│   └── hello.py
├── META-INF/
│   └── MANIFEST.JSON
└── res/
    └── mipmap-mdpi/
        └── icon_64x64.png

アプリコード

hello.py に以下を記述します。

import lvgl as lv
from mpos import Activity

class Hello(Activity):

    def onCreate(self):
        screen = lv.obj()
        label = lv.label(screen)
        label.set_text('Hello World!')
        label.center()
        self.setContentView(screen)

上記のコードは、新しい画面を作成し、ラベルを追加し、ラベルのテキストを設定し、ラベルを中央に配置し、画面をアクティブ化します。

マニフェスト

MANIFEST.JSON に以下を記述します。

{
"name": "HelloWorld",
"publisher": "MicroPythonOS",
"short_description": "Minimal app",
"long_description": "Demonstrates the simplest app.",
"fullname": "com.micropythonos.helloworld",
"version": "0.0.2",
"category": "development",
"activities": [
    {
      "entrypoint": "assets/hello.py",
      "classname": "Hello",
      "intent_filters": [
        {
          "action": "main",
          "category": "launcher"
        }
      ]
    }
  ]
}

アイコン

アイコンはシンプルな64x64ピクセルのPNG画像で、GIMPなどのツールを使って作成できます。

圧縮レベルを9に設定し、背景色、解像度、作成時間、コメント、Exifデータ、XMPデータ、サムネイル、カラープロファイルなどのメタデータを保存しないことで、ファイルサイズをできるだけ小さく保つことをお勧めします。

サイズはおそらく3KBから10KBの間になるでしょう。

アプリのインストール

アプリは、最上位フォルダcom.micropythonos.helloworld/(およびその内容)を/apps/フォルダにコピーすることでインストールできます。

デスクトップ版

おそらく、デスクトップ上で MicroPythonOS を実行するために使用しているinternal_filesystemのクローンは既に作成済みでしょう。

最上位フォルダcom.micropythonos.helloworld/(とその内容)を internal_filesystem/apps/ にコピーまたは移動するだけで準備完了です。

ESP32版

ESP32では、mpremote.pyなどのMicroPythonツールを使用して、MicroPython REPL経由でデバイスとの間でファイルやフォルダをコピーできます。

MicroPythonOSリポジトリの./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.pyにも含まれています。

次に、デバイスをケーブルで接続し、以下の手順でアプリをインストールしてください。

/path/to/mpremote.py mkdir :/apps
/path/to/mpremote.py fs cp -r com.micropythonos.helloworld/ :/apps/

便利な「すべてインストール」または「アプリを1つだけインストール」するスクリプトについては、scripts/install.sh を参照してください。

お好みであれば、グラフィカルユーザーインターフェースを備えたMicroPythonファイルマネージャーも存在するかもしれません。

アプリを起動する

アプリが /apps/ フォルダにインストールされている場合、ランチャーを更新すると表示されるはずです。

MicroPython REPLに以下を入力して手動で起動することもできます。

from mpos import AppManager
AppManager.start_app('com.micropythonos.helloworld')

さらに読む

最初のアプリが動作するようになったので、UIにはMicroPython用の標準的なLVGL呼び出しを、そしてMicroPythonOSフレームワークを使用してアプリの構築を開始できます。

しかし、その前に、アプリのライフサイクルを確認して、なぜonCreate()を追加したのか、そして他にどのようなライフサイクル関数が利用できるのかを理解しておくと良いでしょう。

アプリのライフサイクル

MicroPythonOSは、Androidにヒントを得たアクティビティライフサイクルモデルを採用しています。このライフサイクルを理解することは、ユーザーが画面間を移動したり、アプリを切り替えたり、ランチャーに戻ったりする際に正しく動作するアプリを構築するために不可欠です。

概要

MicroPythonOSのすべてのアプリはアクティビティを中心に構築されています。アクティビティは、ユーザーインターフェースを備えた単一の画面を表します。システムはアクティビティのスタックを管理し、アクティビティが作成、開始、一時停止、再開、停止、破棄される際に、特定のライフサイクルメソッドを呼び出します。

┌─────────────────────────────────────────────────────────────┐
│                    Activity Lifecycle                        │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│    ┌──────────┐                                              │
│    │ onCreate │  ← Activity instantiated, build UI here      │
│    └────┬─────┘                                              │
│         │                                                    │
│         ▼                                                    │
│    ┌──────────┐                                              │
│    │ onStart  │  ← Screen about to become visible            │
│    └────┬─────┘                                              │
│         │                                                    │
│         ▼                                                    │
│    ┌──────────┐                                              │
│    │ onResume │  ← Activity in foreground, user can interact │
│    └────┬─────┘                                              │
│         │                                                    │
│         │ ◄──────────────────────────────────────────┐       │
│         │                                            │       │
│         ▼                                            │       │
│    ┌──────────┐                                      │       │
│    │ onPause  │  ← Another activity coming to front  │       │
│    └────┬─────┘                                      │       │
│         │                                            │       │
│         ▼                                            │       │
│    ┌──────────┐                                      │       │
│    │ onStop   │  ← Activity no longer visible        │       │
│    └────┬─────┘                                      │       │
│         │                                            │       │
│         ├─────────────────────────────────────────────┘       │
│         │  (user navigates back)                             │
│         │                                                    │
│         ▼                                                    │
│    ┌───────────┐                                             │
│    │ onDestroy │  ← Activity being removed from stack        │
│    └───────────┘                                             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

ライフサイクル手法

onCreate()

アクティビティが最初に作成されたときに呼び出されます。ここで以下の処理を行う必要があります。

  • UI(LVGLウィジェット)を作成する
  • インスタンス変数を初期化する
  • コンテンツビューを設定するにはsetContentView()
from mpos import Activity
import lvgl as lv

class MyActivity(Activity):
    def onCreate(self):
        # Create the screen
        screen = lv.obj()

        # Add UI elements
        label = lv.label(screen)
        label.set_text("Hello World!")
        label.center()

        # Activate the screen
        self.setContentView(screen)

重要:画面を表示するには、onCreate() の最後に必ず setContentView() を呼び出してください。

onStart(screen)

アクティビティが表示される直前に呼び出されます。screenパラメータは、作成したLVGLスクリーンオブジェクトです。

以下を利用してください:

  • 展示に必要な資料を準備する
  • 画面が表示されたときに再生されるアニメーションの開始
def onStart(self, screen):
    print("Activity is starting...")

onResume(screen)

アクティビティがフォアグラウンドに入り、インタラクティブになったときに呼び出されます。これは次のように呼ばれます。

  • onStart()の後、アクティビティが最初に表示されたとき
  • 別のアクティビティからこのアクティビティに戻ってきたとき(例:ユーザーが戻るボタンを押した場合)

以下を利用してください:

  • コールバック(ネットワーク、センサーなど)の登録
  • バックグラウンドタスクを開始しています
  • 変更された可能性のあるデータを更新しています
def onResume(self, screen):
    super().onResume(screen)  # Sets _has_foreground = True

    # Register for network changes
    self.connectivity_manager = ConnectivityManager.get()
    self.connectivity_manager.register_callback(self.on_network_change)

    # Refresh data
    self.refresh_app_list()

重要:フォアグラウンドの状態を正しく追跡するには、super().onResume(screen) を呼び出してください。

onPause(screen)

アクティビティがフォーカスを失いそうになったとき(別のアクティビティがフォアグラウンドに現れたとき)に呼び出されます。

以下を利用してください:

  • コールバックの登録解除
  • 進行中の作業を一時停止します
  • 一時状態を保存
def onPause(self, screen):
    # Unregister callbacks
    if self.connectivity_manager:
        self.connectivity_manager.unregister_callback(self.on_network_change)

    super().onPause(screen)  # Sets _has_foreground = False

重要:フォアグラウンドの状態を正しく追跡するには、super().onPause(screen) を呼び出してください。

onStop(screen)

アクティビティが表示されなくなったとき(別のアクティビティによって完全に覆われたとき)に呼び出されます。

以下を利用してください:

  • 非表示になっている間に不要なリソースを解放する
  • 重い処理を中止する
def onStop(self, screen):
    # Stop any expensive background work
    self.cancel_pending_downloads()

onDestroy(screen)

アクティビティがアクティビティスタックから削除されるとき(ユーザーがこのアクティビティを過ぎて戻ったとき)に呼び出されます。

以下を利用してください:

  • 最後のクリーンナップ
  • すべてのリソースを解放します
def onDestroy(self, screen):
    # Clean up resources
    self.cleanup_temp_files()

アクティビティスタック

MicroPythonOSはアクティビティのスタックを保持しています。新しいアクティビティを開始すると、それがスタックにプッシュされます。ユーザーが前の画面に戻ると、最上位のアクティビティがポップされて破棄されます。

Activity Stack:
┌─────────────────┐
│  SettingsDetail │  ← Top (visible, has focus)
├─────────────────┤
│    Settings     │  ← Paused, stopped
├─────────────────┤
│    Launcher     │  ← Paused, stopped
└─────────────────┘

ナビゲーションフロー

  1. 新しいアクティビティを開始:現在のアクティビティは onPause()onStop() を受け取り、新しいアクティビティは onCreate()onStart()onResume() を受け取ります。

  2. 戻る:現在のアクティビティはonPause()onStop()onDestroy()を受け取り、前のアクティビティはonResume()を受け取る

開始アクティビティ

基本ナビゲーション

startActivity() を使用して別のアクティビティに移動:

from mpos import Intent

class MyActivity(Activity):
    def on_settings_click(self):
        intent = Intent(activity_class=SettingsActivity)
        self.startActivity(intent)

インテントを使ったデータの受け渡し

Intent extrasを使用してアクティビティ間でデータを受け渡す:

# Sending activity
def on_item_click(self, item_id):
    intent = Intent(activity_class=DetailActivity)
    intent.putExtra("item_id", item_id)
    intent.putExtra("title", "Item Details")
    self.startActivity(intent)

# Receiving activity
class DetailActivity(Activity):
    def onCreate(self):
        intent = self.getIntent()
        item_id = intent.extras.get("item_id")
        title = intent.extras.get("title")
        # Use the data...

活動から成果を得る

結果が必要な場合は、startActivityForResult() を使用:

class PhotoPickerActivity(Activity):
    def on_gallery_click(self):
        intent = Intent(activity_class=GalleryActivity)
        self.startActivityForResult(intent, self.on_photo_selected)

    def on_photo_selected(self, result):
        if result["result_code"] == "OK":
            photo_path = result["data"].get("photo_path")
            self.display_photo(photo_path)

# In GalleryActivity
class GalleryActivity(Activity):
    def on_photo_tap(self, photo_path):
        self.setResult("OK", {"photo_path": photo_path})
        self.finish()

アクティビティの終了

finish() を呼び出すと、現在のアクティビティが閉じられ、前のアクティビティに戻る:

def on_done_click(self):
    # Optionally set a result first
    self.setResult("OK", {"selected_item": self.selected})
    self.finish()

フォアグラウンド状態

アクティビティは、フォアグラウンドにあるかどうかを追跡します。これは次のような場合に役立ちます。

  • ユーザーが別のページに移動したときに操作をキャンセルする
  • アクティビティが表示されていないときは、UIの更新を回避する

フォアグラウンドの状態を確認

def on_data_loaded(self, data):
    # Only update UI if we're still in the foreground
    if self.has_foreground():
        self.update_list(data)

条件付き実行

if_foreground() を使用すると、フォアグラウンド時のみコードを実行:

def on_download_complete(self, data):
    self.if_foreground(self.show_download_result, data)

スレッドセーフなUIアップデート

asyncio task/coroからUIを更新する場合、asyncioはLVGLと同じスレッドで実行されるため、特別な処理は必要ありません。これがマルチタスクを実現する最も簡単な方法です。

しかし、場合によっては、例えば次のようにして作成されたまったく新しいスレッドでアクションを実行したい場合があります。

    _thread.stack_size(TaskManager.good_stack_size())
    _thread.start_new_thread(self.background_task, (an_argument, another_one))

次に、別のスレッドから LVGL UI を更新するには、update_ui_threadsafe_if_foreground() を使用します。

def background_task(self):
    # Running in a separate thread
    result = self.fetch_data()

    # Safely update UI on main thread, only if in foreground
    self.update_ui_threadsafe_if_foreground(
        self.display_result, 
        result
    )

これにより、lv.async_call() を使用して、関数 self.display_result(result) が LVGL スレッドから実行されるようにスケジュールされます。また、has_foreground() を使用して、アクティビティがまだフォアグラウンドで実行されているかどうかも確認します。

これが機能するためには、前述のように、関数onResume()onPause()関数は、暗黙的に(オーバーライドしない場合)または明示的に(オーバーライドする場合)super()を実行する必要があります。

完全な例

適切なライフサイクル管理を示す完全な例を以下に示します。

import lvgl as lv
from mpos import Activity, ConnectivityManager, TaskManager

class NetworkAwareActivity(Activity):

    def __init__(self):
        super().__init__()
        self.connectivity_manager = None
        self.data = None

    def onCreate(self):
        # Create UI
        self.screen = lv.obj()

        self.status_label = lv.label(self.screen)
        self.status_label.set_text("Loading...")
        self.status_label.center()

        self.refresh_button = lv.button(self.screen)
        self.refresh_button.align(lv.ALIGN.BOTTOM_MID, 0, -20)
        self.refresh_button.add_event_cb(
            lambda e: self.refresh_data(),
            lv.EVENT.CLICKED, None
        )
        btn_label = lv.label(self.refresh_button)
        btn_label.set_text("Refresh")

        self.setContentView(self.screen)

    def onResume(self, screen):
        super().onResume(screen)

        # Register for network changes
        self.connectivity_manager = ConnectivityManager.get()
        self.connectivity_manager.register_callback(self.on_network_change)

        # Initial data load
        if self.connectivity_manager.is_online():
            self.refresh_data()
        else:
            self.status_label.set_text("Waiting for network...")

    def onPause(self, screen):
        # Unregister callbacks
        if self.connectivity_manager:
            self.connectivity_manager.unregister_callback(self.on_network_change)

        super().onPause(screen)

    def on_network_change(self, online):
        if online and self.has_foreground():
            self.refresh_data()
        elif not online:
            self.status_label.set_text("Network disconnected")

    def refresh_data(self):
        self.status_label.set_text("Loading...")
        TaskManager.create_task(self.fetch_data_async())

    async def fetch_data_async(self):
        try:
            # Simulate network request
            await TaskManager.sleep(1)
            self.data = {"items": ["Item 1", "Item 2", "Item 3"]}

            # Update UI only if still in foreground
            if self.has_foreground():
                self.status_label.set_text(f"Loaded {len(self.data['items'])} items")
        except Exception as e:
            if self.has_foreground():
                self.status_label.set_text(f"Error: {e}")

ベストプラクティス

やるべきこと

__init__ メソッドで必ず super().__init__() を呼び出す
✅ フォアグラウンドの状態を追跡するには、super().onResume(screen)super().onPause(screen) を呼び出す
onResume() でコールバックを登録し、onPause() で登録を解除する
✅ 非同期操作でUIを更新する前にhas_foreground()をチェックする
onCreate()の最後にsetContentView()を使用する
onDestroy()でリソースをクリーンアップする

してはいけないこと

onCreate() で重い処理をしないでください。UI がブロックされる
❌ コールバックの登録解除を忘れないでください。メモリリークの原因になる
update_ui_threadsafe_if_foreground() がない場合、バックグラウンド スレッドから UI を更新しないこと
❌ 非同期操作後もアクティビティが表示されているとは限らないので注意する
onDestroy()後にLVGLオブジェクトへの参照を保存しないこと

Androidとのライフサイクル比較

MicroPythonOS アンドロイド 注記
onCreate() onCreate() 同じ目的
onStart(screen) onStart() MicroPythonOS は screen を渡します
onResume(screen) onResume() MicroPythonOS は screen を渡します
onPause(screen) onPause() MicroPythonOS は screen を渡します
onStop(screen) onStop() MicroPythonOS は screen を渡します
onDestroy(screen) onDestroy() MicroPythonOS は screen を渡します
finish() finish() 同じ目的
startActivity(intent) startActivity(intent) 同じ目的
startActivityForResult() startActivityForResult() MicroPythonOSにおいてはコールバックベース
setResult() setResult() 同じ目的
getIntent() getIntent() 同じ目的

関連項目

バンドルされたアプリ

アプリを.mpkファイルにバンドルするには、最上位com.micropythonos.helloworld/フォルダを含めずに、圧縮されていない「zip」ファイルを作成するだけです。

.mpk ファイルを決定論的にするには、以下の方法をお勧めします:

  • ファイルのタイムスタンプを固定値に設定する
  • ファイルをソートして順序を固定する
  • 余分なファイル属性とディレクトリを除外する

例えば:

cd com.micropythonos.helloworld/
find . -type f -exec touch -t 202501010000.00 {} \; # set fixed timestamp to have a deterministic zip file
find . -type f | sort | TZ=CET zip -X -r -0 /tmp/com.micropythonos.helloworld_0.0.2.mpk -@ # sort, -Xclude extra attributes, -recurse into directories and -0 compression

App Storeバンドル

https://apps.MicroPythonOS.com にあるアプリは、厳選され、手動でレビューされ、検証済みのコレクションであり、多くの場合、MicroPythonOS コアチームによって作成および維持されています。
これらは、scripts/bundleapps.sh を使用して app_index.json に手動でバンドルされ、アプリリポジトリにプッシュされます。

フレームワーク

AppearanceManager

AppManager

AudioManager

BatteryManager

BuildInfo

ConnectivityManager

DeviceInfo

DisplayMetrics

DownloadManager

InputManager

LightsManager

Preferences

SensorManager

SettingActivity

SettingsActivity

TaskManager

TimeZone

WebServer

WidgetAnimator

WifiService

アーキテクチャ

概要

MicroPythonOSは、Androidに触発された、軽量でアプリ中心のオペレーティングシステムとして設計されています。完全にMicroPythonで記述されており、アプリ開発に必要な機能を備えた最小限のコアを提供することで、アプリケーションの開発と展開を容易にします。

アーキテクチャ

  • アプリ(App Store、ランチャー、OSアップデート、設定、WiFi)
  • フレームワーク:MicroPython(AppManager、AudioManager、SensorManager)およびC言語(QRDecoder)
  • ドライバ:Micropython(ディスプレイ、タッチ入力)およびC(カメラ)
  • カーネル:FreeRTOSおよびLinux(低レベルバスドライバ)

設計原則

  • 軽量OS:コアOSはハードウェアの初期化、マルチタスク処理、UIを担当し、ほとんどの機能はアプリに任せる。
  • すべてがアプリ化されている:Wi-Fiの設定やアップデートといったシステム機能は、アプリとして実装されている。
  • 開発者に優しい:MicroPythonは、PythonベースのAPIを使用してアプリ開発を簡素化します。

主要構成要素

  • ブートプロセス:ハードウェアを初期化し、ファイルシステムをマウントします。
  • ユーザーインターフェース:ジェスチャー操作に対応したAndroidライクなタッチスクリーンUI。
  • アプリエコシステム:組み込みアプリと拡張性のためのアプリストア。
  • OTAアップデート:システムとアプリのアップデートがシームレスに行われます。

ディレクトリ構造については、「ファイルシステムレイアウト」を参照してください。

フレームワーク

インテント

ブートシーケンス

MicroPythonOSは、システムの初期化と管理を行う複数のコアコンポーネントで構成されています。

  • lvgl_micropython/lib/micropython/ports/esp32/modules/_boot.py : 内部ストレージパーティションを / にマウントしようとし、失敗した場合はフォーマットします。
  • internal_filesystem/main.py : /lib/mpos/main.py をインポートすることで、実行を /lib/mpos/main.py に委譲します。
  • /lib/mpos/main.py:
    • ハードウェアボードを検出します
    • ファイルシステムドライバを初期化します
    • freezefsを/builtin/にマウントします。
    • com.micropythonos.settings を読み込みます
    • ユーザーインターフェースを初期化します。
    • WiFi自動接続スレッドを開始します
    • launcherアイコンを表示するアプリを起動します
    • asyncio REPL を起動します
    • 現在の起動を成功とマークします(ロールバックをキャンセルします)
    • タスクマネージャーを起動します

アプリとデータがどこに保存されるかについては、「ファイルシステムレイアウト」を参照してください。

ファイルシステムレイアウト

MicroPythonOSは、構造化されたファイルシステムを使用して、アプリケーション、データ、およびリソースを整理します。

  • apps/:ダウンロードおよびインストール済みのアプリが格納されるディレクトリ。
    • com.micropythonos.helloworld/ : HelloWorld アプリのインストールディレクトリ。アプリの作成を参照してください。
  • builtin/ : OSに組み込まれた読み取り専用ファイルシステムで、起動時にmain.pyによってマウントされる。
    • apps/ :組み込みアプリを参照してください。
    • res/mipmap-mdpi/default_icon_64x64.png : アイコンが設定されていないアプリのデフォルトアイコン。
  • lib/ : ライブラリとフレームワーク
    • mpos/ : MicroPythonOSライブラリとフレームワーク
      • ui/ : MicroPythonOSユーザーインターフェースライブラリとフレームワーク
  • data/ : アプリデータの保存場所。
    • com.micropythonos.helloworld/ : アプリケーション固有のストレージ (例: config.json)
    • com.micropythonos.settings/ : 内蔵設定アプリで使用されるストレージ
    • com.micropythonos.wifi/ : 内蔵WiFiアプリが使用するストレージ
    • images/ : 画像用の汎用ストレージ(カメラアプリなどで使用)。

この構造により、システムリソース、アプリケーション、およびユーザーデータが明確に分離されます。

OS開発

概要

ほとんどのユーザーは、MicroPythonOSを実行して、それ用のアプリケーションを開発するだけで十分でしょう。

しかし、内部的な部分をいじりたい場合は、メニューの「OS開発」の項目からいずれかを選択してください。

Linux

Linux上でのOS開発

ほとんどのユーザーは、リリース ページから事前にビルドされたバイナリを使用して、手動でインストールするか、Web インストーラーを使用してインストールするだけで済みます。

しかし、もしあなたがエンジンの内部を改造したいのであれば、ここはまさにうってつけの場所です!

前提条件を満たす

コードをコンパイルするために必要なものがすべてインストールされていることを確認してください。

sudo apt update
sudo apt-get install -y build-essential libffi-dev pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev libpipewire-0.3-dev libwayland-dev libdecor-0-dev libv4l-dev librlottie-dev

コードをダウンロード

リポジトリをクローンする:

git clone --recurse-submodules --depth 1 --shallow-submodules https://github.com/MicroPythonOS/MicroPythonOS.git
cd MicroPythonOS/

MicroPython、LVGL、ESP-IDF、およびそれらのすべての依存関係を再帰的に複製するため、しばらく時間がかかります。

オプション:コードの更新

既に古いクローンがあり、それを更新したい場合は、それを削除して再度クローンを作成するのが最も簡単です。

しかし、帯域幅と時間を節約する必要がある場合は、代わりに以下の手順を実行すると、ローカルでの変更がすべて破棄されます。

cd MicroPythonOS/
git submodule foreach --recursive 'git clean -f; git checkout .'
git pull --depth 1
git submodule update --init --depth 1

コードをコンパイルする

利便性を考慮して、build_mpos.sh スクリプトを使用してください。

使用法:

./scripts/build_mpos.sh <target system>

対象システム: esp32esp32s3``、unix(= Linux) およびmacOS`

例:

./scripts/build_mpos.sh esp32
./scripts/build_mpos.sh esp32s3
./scripts/build_mpos.sh unix
./scripts/build_mpos.sh macOS

生成されたビルドファイルは、例えば lvgl_micropython/build/ に作成されます。

  • lvgl_micropython/build/lvgl_micropy_unix
  • lvgl_micropython/build/lvgl_micropy_macOS
  • lvgl_micropython/build/lvgl_micropy_ESP32_GENERIC_S3-SPIRAM_OCT-16.bin

デスクトップで実行

  1. internal_filesystem/フォルダがあることを確認してください
    ソースコードからビルドした場合、既にそれを含むローカルクローンが存在するはずです。
    事前にビルドされたバイナリを使用する場合は、リリースぺージまたはメインブランチから付属の「ソースコード」zipファイルをダウンロードして解凍してください。

  2. ソフトウェアが揃っていることを確認してください
    最も簡単な方法は、リリースぺージからビルド済みのバイナリ(MicroPythonOS_arm64_macOS_0.9.0.binMicroPythonOS_x64_linux_0.9.0.elf など)をダウンロードすることです。
    ダウンロード後、以下のように適切な場所に保存してください。

    mkdir -p lvgl_micropython/build # do this from the top level folder MicroPythonOS from step 1
    cp /Users/yourname/MicroPythonOS_amd64_macOS_0.7.1.bin lvgl_micropython/build/lvgl_micropy_macOS # for macOS
    cp /home/yourname/MicroPythonOS_amd64_linux_0.7.1.elf lvgl_micropython/build/lvgl_micropy_unix # for Linux or WSL2 on Windows 11
    

    あるいは、事前にビルドされたバイナリをダウンロードする代わりに、ソースからビルドすることもできます。その場合、ビルドされたバイナリは lvgl_micropython/build/lvgl_micropy_XXX に格納されます(XXX は Unix または macOS を表します)。

  3. ソフトウェアを起動します:
    これで実行準備が整いました。

    ./scripts/run_desktop.sh
    

macOSに関するメモ

/opt/homebrew/opt/libffi/lib/libffi.8.dylib が見つからないというエラーが表示された場合は、brew install libffi で修正してください。

コードが署名されていないというエラーが発生した場合は、次のように許可してください:

デスクトップでの変更

internal_filesystem/ 内のファイルを変更すると、ファイルを再読み込みしたりアプリを再起動したりすると、デスクトップにその変更がすぐに反映されることに気づくでしょう。

./scripts/run_desktop.sh を実行すると、OS は内部ファイルシステムから直接 MicroPythonOS スクリプトを実行します。これはつまり:

  • Pythonファイルへの変更はすべて即座に反映されます - ビルドやインストールは不要
  • 即時テスト - ファイルを編集し、アプリを再起動すると、変更内容が表示されます
  • 迅速な反復サイクル - 開発とテストの推奨方法

自分で試してみてください:

  1. internal_filesystem/builtin/apps/com.micropythonos.about/assets/about.py を編集します。
  2. ./scripts/run_desktop.sh を実行します。
  3. アプリを開く
  4. 変更内容をすぐに確認できます!

ESP32での変更方法

変更内容をデスクトップ上でテストして正しく動作することを確認した後、またはデスクトップ上でテストできない作業を行う場合は、物理ハードウェアにデプロイできます。

ESP32にインストールする最も簡単な方法は、もちろんWebインストーラーを使用することです。

しかし、そこに掲載されていないバージョンをインストールする必要がある場合、または自分でビルドした場合は、ESP32デバイスに手動でインストールできます。

  1. ファームウェアを入手

    • リリースバイナリをダウンロードします(例:MicroPythonOS_esp32_0.5.0.bin
    • または、 macOSまたはLinux上で独自のビルドを作成することもできます。
  2. ESP32をブートローダーモードにする
    既にMicroPythonOSを使用している場合は、[設定] - [ブートローダーに再起動] - [ブートローダー] - [保存] の順に進んでください。
    それ以外の場合は、ボードの電源を入れる間、「BOOT」(場合によっては「START」と表記されている)ボタンを物理的に押し続けてください。詳細については、Webインストーラーを参照してください。

  3. ファームウェアをフラッシュする
    ~/.espressif/python_env/idf5.2_py3.9_env/bin/python -m esptool --chip esp32s3 write_flash 0 firmware_file.bin
    フラッシュメモリ全体を消去して古いファイルやアプリを一切残さないようにしたい場合は、--erase-allオプションを追加してください。
    また、自分でコンパイルした最新のファームウェアをフラッシュしようとする便利なスクリプト ./scripts/flash_over_usb.sh もあります。

  4. MicroPython REPLシェルにアクセスします
    リセット後、シリアル回線上でREPLシェルが利用可能になるはずです。
    シリアルクライアントであればどれでも構いませんが、lvgl_micropythonに同梱されているmpremote.pyツールを使うと便利です。
    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py

  5. ファイルシステムにデータを書き込む(開発時のみ)
    開発段階では、コンパイル時に組み込まれる「固定」ライブラリやアプリケーションを上書きし、編集可能なソースファイルに置き換えたいと思うでしょう。
    これにより、Pythonスクリプトがビルド時ではなく実行時にコンパイルされるため、MicroPythonOSの起動速度が大幅に低下します。しかし、MicroPythonOSとテスト対象のコードがロードされると、速度は正常に戻ります。
    これを自動で行ってくれる便利なスクリプトがあります。
    使用法:

    ./scripts/install.sh
    
    ./scripts/install.sh com.micropythonos.about # to install one single app
    

    macOS では、install.sh スクリプトには次のものが必要です: brew install cask serial
    少数のファイルを頻繁に更新する必要がある場合は、手動で更新することもできます。
    例:

    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py cp internal_filesystem/lib/mpos/device_info.py :/lib/mpos
    

注記

macOS

macOS上でのOS開発

ほとんどのユーザーは、リリース ページから事前にビルドされたバイナリを使用して、手動でインストールするか、Web インストーラーを使用してインストールするだけで済みます。

しかし、もしあなたがエンジンの内部を改造したいのであれば、ここはまさにうってつけの場所です!

前提条件を満たす

コードをコンパイルするために必要なものがすべてインストールされていることを確認してください。

xcode-select --install
brew install pkg-config libffi ninja make SDL2

コードをダウンロード

リポジトリをクローンする:

git clone --recurse-submodules --depth 1 --shallow-submodules https://github.com/MicroPythonOS/MicroPythonOS.git
cd MicroPythonOS/

MicroPython、LVGL、ESP-IDF、およびそれらのすべての依存関係を再帰的に複製するため、しばらく時間がかかります。

オプション:コードの更新

既に古いクローンがあり、それを更新したい場合は、それを削除して再度クローンを作成するのが最も簡単です。

しかし、帯域幅と時間を節約する必要がある場合は、代わりに以下の手順を実行すると、ローカルでの変更がすべて破棄されます。

cd MicroPythonOS/
git submodule foreach --recursive 'git clean -f; git checkout .'
git pull --depth 1
git submodule update --init --depth 1

コードをコンパイルする

利便性を考慮して、build_mpos.sh スクリプトを使用してください。

使用法:

./scripts/build_mpos.sh <target system>

対象システム: esp32、esp32s3、unix(= Linux) およびmacOS

例:

./scripts/build_mpos.sh esp32
./scripts/build_mpos.sh esp32s3
./scripts/build_mpos.sh unix
./scripts/build_mpos.sh macOS

生成されるビルドファイルはlvgl_micropython/build/、例えば以下の場所に保存されます。

  • lvgl_micropython/build/lvgl_micropy_unix
  • lvgl_micropython/build/lvgl_micropy_macOS
  • lvgl_micropython/build/lvgl_micropy_ESP32_GENERIC_S3-SPIRAM_OCT-16.bin

デスクトップで実行中

  1. internal_filesystem/フォルダがあることを確認してください
    ソースコードからビルドした場合、既にそれを含むローカルクローンが存在するはずです。
    事前にビルドされたバイナリを使用する場合は、リリースぺージまたはメインブランチから付属の「ソースコード」zipファイルをダウンロードして解凍してください。
  2. ソフトウェアが揃っていることを確認してください
    最も簡単な方法は、リリース ページから事前にビルドされたバイナリ (MicroPythonOS_arm64_macOS_0.9.0.binMicroPythonOS_x64_linux_0.9.0.elfなど) をダウンロードすることです。
    ダウンロード後、以下のように適切な場所に保存してください。
    mkdir -p lvgl_micropython/build # do this from the top level folder MicroPythonOS from step 1
    cp /Users/yourname/MicroPythonOS_amd64_macOS_0.7.1.bin lvgl_micropython/build/lvgl_micropy_macOS # for macOS
    cp /home/yourname/MicroPythonOS_amd64_linux_0.7.1.elf lvgl_micropython/build/lvgl_micropy_unix # for Linux or WSL2 on Windows 11
    
    あるいは、事前にビルドされたバイナリをダウンロードする代わりに、ソースからビルドすることもできます。そうすると、lvgl_micropython/build/lvgl_micropy_XXXXXX に格納されます(XXX は Unix または macOS を表します)。
  3. ソフトウェアを起動します。
    これで、以下のコマンドで実行できます。
    ./scripts/run_desktop.sh
    

macOSに関するメモ

/opt/homebrew/opt/libffi/lib/libffi.8.dylib が見つからないというエラーが表示された場合は、brew install libffi で修正してください。
コードが署名されていないというエラーが表示された場合は、次のように許可してください。

デスクトップでの変更

internal_filesystem/ 内のファイルを変更すると、ファイルを再読み込みしたりアプリを再起動したりすると、デスクトップにすぐに変更が反映されることに気づくでしょう。
./scripts/run_desktop.sh を実行すると、OS は MicroPythonOS スクリプトを internal_filesystem/ から直接実行します。つまり、

  • Pythonファイルへの変更はすべて即座に反映されます - 組み立てやインストールは不要
  • 即時テスト - ファイルを編集し、アプリを再起動すると、変更内容が表示されます
  • 迅速な反復サイクル - 開発とテストの推奨方法

自分で試してみてください:

  1. internal_filesystem/builtin/apps/com.micropythonos.about/assets/about.py を編集します。
  2. ./scripts/run_desktop.sh を実行します。
  3. About アプリを開きます。
  4. 変更がすぐに反映されます。

ESP32での変更方法

変更内容をデスクトップ上でテストして正しく動作することを確認した後、またはデスクトップ上でテストできない作業を行う場合は、物理ハードウェアにデプロイできます。

ESP32にインストールする最も簡単な方法は、もちろんWebインストーラーを使用することです。

しかし、そこに掲載されていないバージョンをインストールする必要がある場合、または自分でビルドした場合は、ESP32デバイスに手動でインストールできます。

  1. ファームウェアを入手
    リリースバイナリをダウンロードします(例:MicroPythonOS_esp32_0.5.0.bin
    または、 macOSまたはLinux上で独自のビルドを作成することもできます。

  2. ESP32をブートローダーモードにする
    既にMicroPythonOSを使用している場合は、[設定] - [ブートローダーに再起動] - [ブートローダー] - [保存] の順に進んでください。
    それ以外の場合は、ボードの電源を入れる間、「BOOT」(場合によっては「START」と表記されている)ボタンを物理的に押し続けてください。詳細については、Webインストーラーを参照してください。

  3. ファームウェアをフラッシュする
    ~/.espressif/python_env/idf5.2_py3.9_env/bin/python -m esptool --chip esp32s3 write_flash 0 firmware_file.bin
    フラッシュメモリ全体を消去して古いファイルやアプリを一切残さないようにしたい場合は、--erase-allオプションを追加してください。
    また、./scripts/flash_over_usb.sh自分でコンパイルした最新のファームウェアをフラッシュしようとする便利なスクリプトも用意されています。

  4. MicroPython REPLシェルにアクセスします
    リセット後、シリアル回線上でREPLシェルが利用可能になるはずです。
    シリアルクライアントであればどれでも構いませんが、lvgl_micropythonに同梱されているmpremote.pyツールを使うと便利です。
    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py

  5. ファイルシステムにデータを書き込む(開発時のみ)
    開発段階では、コンパイル時に組み込まれる「固定」ライブラリやアプリケーションを上書きし、編集可能なソースファイルに置き換えたいと思うでしょう。
    これにより、Pythonスクリプトがビルド時ではなく実行時にコンパイルされるため、MicroPythonOSの起動速度が大幅に低下します。しかし、MicroPythonOSとテスト対象のコードがロードされると、速度は正常に戻ります。
    これを自動で行ってくれる便利なスクリプトがあります。
    使用法:

    ./scripts/install.sh
    
    ./scripts/install.sh com.micropythonos.about # to install one single app
    

    macOS では、install.sh スクリプトには次のものが必要です: brew install cask serial
    少数のファイルを頻繁に更新する必要がある場合は、次のように手動で更新することもできます。

    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py cp internal_filesystem/lib/mpos/device_info.py :/lib/mpos
    

注記

Windows

Windows 向けにビルドする

主要な依存関係( LVGLとMicroPythonをバンドルしたlvgl_micropython)がWindowsをサポートしていないため、MicroPythonOSも公式にはWindowsをサポートしていません。

しかし、Linuxデスクトップ版はWindows 11上のWSL2で問題なく動作するというユーザーからの報告が寄せられています。そのため、それを使ってデスクトップ上でアプリを作成・テストすることができ、非常に便利です。

MicroPythonOSをソースコードからコンパイルする必要があるのは、基盤となるMicroPython、LVGL、Cバインディングなどを変更するような、低レベルのOS開発を行う場合のみです。そのため、必ずしも必要とは限りません。もし必要で、どうしてもWindowsを使いたい場合は、Linuxの手順を試した後、Windows 11上のWSL2を使ってビルドできるかもしれません。

すべてを自分でコンパイルしなくても、楽しいことの大部分、つまりクールなアプリを作ることはできます!

そのためには、デスクトップで実行するか、サポートされているデバイスに事前にビルドされたファームウェアをインストールしてから、「アプリの作成」に進んでください。

ESP32へのインストール

ESP32にインストールする最も簡単な方法は、もちろんWebインストーラーを使用することです。

しかし、そこに掲載されていないバージョンをインストールする必要がある場合、または自分でビルドした場合は、ESP32デバイスに手動でインストールできます。

  1. ファームウェアを入手

    • リリースバイナリをダウンロードします(例:MicroPythonOS_esp32_0.5.0.bin
    • または、 macOSまたはLinux上で独自のビルドを作成することもできます。
  2. ESP32をブートローダーモードにする
    既にMicroPythonOSを使用している場合は、[設定] - [ブートローダーに再起動] - [ブートローダー] - [保存] の順に進んでください。
    それ以外の場合は、ボードの電源を入れる間、「BOOT」(場合によっては「START」と表記されている)ボタンを物理的に押し続けてください。詳細については、Webインストーラーを参照してください。

  3. ファームウェアをフラッシュする
    ~/.espressif/python_env/idf5.2_py3.9_env/bin/python -m esptool --chip esp32s3 write_flash 0 firmware_file.bin
    フラッシュメモリ全体を消去して古いファイルやアプリを一切残さないようにしたい場合は、--erase-allオプションを追加してください。
    また、自分でコンパイルした最新のファームウェアをフラッシュしようとする便利なスクリプト ./scripts/flash_over_usb.sh もあります。

  4. MicroPython REPLシェルにアクセスします
    リセット後、シリアル回線上でREPLシェルが利用可能になるはずです。
    シリアルクライアントであればどれでも構いませんが、lvgl_micropythonに同梱されているmpremote.pyツールを使うと便利です。
    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py

  5. ファイルシステムにデータを書き込む(開発時のみ)
    開発段階では、コンパイル時に組み込まれる「固定」ライブラリやアプリケーションを上書きし、編集可能なソースファイルに置き換えたいと思うでしょう。
    これにより、Pythonスクリプトがビルド時ではなく実行時にコンパイルされるため、MicroPythonOSの起動速度が大幅に低下します。しかし、MicroPythonOSとテスト対象のコードがロードされると、速度は正常に戻ります。
    これを自動で行ってくれる便利なスクリプトがあります。
    使用法:

    ./scripts/install.sh
    
    ./scripts/install.sh com.micropythonos.about # to install one single app
    

    macOS では、install.sh スクリプトには次のものが必要です: brew install cask serial
    少数のファイルを頻繁に更新する必要がある場合は、手動で更新することもできます。
    例:

    ./lvgl_micropython/lib/micropython/tools/mpremote/mpremote.py cp internal_filesystem/lib/mpos/device_info.py :/lib/mpos
    

注記

エミュレートされたESP32

デスクトップ上のQEMU ESP32エミュレータで実行中

開発や自動テストにおいては、エミュレートされたESP32デバイス上でMicroPythonOSを実行することが非常に有効です。

デスクトップ上で実行する場合と比較して、エミュレートされたESP32デバイスはより多くの機能を提供します。

  • エミュレートされたWiFiスキャン(ハードコードされたアクセスポイントのリストを検出します)
  • エミュレートされたWi-Fi接続(暗号化には対応していないため、パスワードは空欄のままにしてください)
  • エミュレートされたWiFiアクセスポイント(AP)モード
  • LittleFS2ファイルシステムと無線アップデートのテストを可能にするエミュレートされたストレージ
  • 超低消費電力プロセッサとディープスリープをエミュレート
  • エミュレートされたGPIOボタン
  • エミュレートされた静電容量式タッチボタン
  • エミュレートされたST7789Vディスプレイ

今後、さらに多くの機能が追加される可能性があります。

  • Bluetooth エミュレート - 現在は ESP32 のみで利用可能ですが、将来的には ESP32S3 にも対応する可能性があります。

この目的のために、私たちは素晴らしいa159x36 QEMUエミュレータを使用しています。これはLilyGo T-Display(ESP32)とLilyGo T-Display-S3(ESP32S3)をエミュレートすることができ、いくつかの改良点が上流にマージされるのを待っています。

動作させるには、以下の手順に従ってください。

  1. ESP32 QEMUをコンパイルする
  2. MicroPythonOSのリリースイメージを16MBにパディングしてください(そうしないとQEMUが拒否します)。
  3. パディングされたMicroPythonリリースイメージを使用してQEMUを起動します。

Linux、Windows、macOS(Intel)、macOS(ARM)向けにESP32 QEMUをコンパイルするGitHubワークフローも存在するため、 GitHub Actionsの成果物からビルド済みのバージョンをダウンロードできる可能性があります。ダウンロードするにはログインが必要です。

  1. QEMUをコンパイルする
    前提条件を満たしてください。

    sudo apt-get install -y -q --no-install-recommends build-essential libgcrypt-dev libglib2.0-dev libpixman-1-dev libsdl2-dev libslirp-dev ninja-build python3-pip libvte-2.91-dev wget zlib1g-dev
    

    クローンを作成する:

    git clone https://github.com/MicroPythonOS/qemu/
    cd qemu
    

    設定する:

    ./configure --target-list=xtensa-softmmu --enable-gcrypt --enable-slirp --enable-debug --enable-vte --enable-stack-protector
    

    コンパイルしてください:

    make -j4 # 4 is the number of cores
    
  2. MicroPythonOSビルドにパッドを挿入する
    最新版をダウンロードするか、自分でビルドしたものを使用してください。
    ESP32 QEMUは、サポートされているサイズ(2、4、8、または16MB)でない場合、それを拒否するので、ゼロで埋めてください。
    Linuxでこれを行う簡単な方法は次のとおりです。

    dd if=MicroPythonOS_esp32_0.8.0.bin of=MicroPythonOS_esp32_0.8.0.bin.padded bs=1M count=16 oflag=append conv=notrunc
    
  3. QEMUを起動する

    ./build/qemu-system-xtensa -machine esp32s3 -m 8M -drive file=MicroPythonOS_esp32_0.8.0.bin.padded,if=mtd,format=raw -nic user,model=esp32_wifi,hostfwd=tcp:127.0.0.1:10080-192.168.4.15:80,net=192.168.4.0/24,host=192.168.4.2,hostfwd=tcp:127.0.0.1:10081-192.168.4.1:80,hostfwd=tcp:127.0.0.1:7890-192.168.4.15:7890,hostfwd=tcp:127.0.0.1:7891-192.168.4.1:7890 -display default,show-cursor=on -parallel none -monitor none -serial stdio
    

    hostfwd の転送行:

    • 127.0.0.1:7890 to 192.168.4.15:7890ステーション(WiFiクライアント)モードのデバイスのポート7890で動作するwebreplウェブサーバーの場合
    • 127.0.0.1:7891 to 192.168.4.1:7890ESP32のポート7890でWebREPLを使用する場合、アクセスポイント(ホットスポット)モードでWebREPLを実行します。

    また、これらは現在使用されていませんが、転送されています。

    • 127.0.0.1:10080 to 192.168.4.15:80ESP32がステーション(WiFiクライアント)モードの場合
    • 127.0.0.1:10081 to 192.168.4.1:80ESP32がアクセスポイント(ホットスポット)モードの場合

    注:QEMUは、通常のシェルから起動した場合のみ標準出力にログを出力します。これは、標準入力が設定されているためです。スクリプトや標準入力を設定しないツールから起動する場合は、unbufferコマンドの先頭にツール名をプレフィックスとして追加して標準入力が設定されるようにしてください。そうしないと、ログがほとんど表示されません。

コントロール

エミュレートされたT-Display S3内をナビゲートするには:

  • リセットボタンの場合は r を押します。
  • 「前へ」アクションに割り当てられた GPIO0 ボタンの場合は 1 を押します。
  • 「次へ」アクションに割り当てられた GPIO14 ボタンの場合は 2 を押します。
  • 「決定」アクションの場合は両方を押します。
  • 「戻る」アクションの場合は 1 を長押しします。

ボードの画像にあるボタンをクリックしても構いません。

また、現在未使用の項目:

  • 7、8、9、0は、GPIO01、GPIO02、GPIO12、GPIO13に対応する静電容量式タッチ入力ピン0、1、11、12に割り当てられています。

これらの制御に関するコードは、QEMUのhw/xtensa/esp32s3.chw/display/st7789v.cにあります。

ファイルシステムを使用してイメージを作成する

迅速な開発のために、完全な再構築を行う代わりに、internal_filesystem/ に基づいてファイルシステムを再構築し、それを LittleFS2 ファイルシステムとしてイメージにバンドルすることもできます。

MicroPythonOSリポジトリから./scripts/make_image.shを実行して実行してください。

./scripts/mklittlefs.sh を呼び出してファイルシステムを構築し、他のすべての必要ファイルをバンドルすることで、わずか 1 秒で起動可能なイメージを作成します。

ポーティングガイド

新しいデバイスへの移行

MicroPythonOSを新しいデバイスに移植するのは、それが既にMicroPythonを実行できる一般的なデバイスであれば、比較的簡単です。

理想的には、(お使いのディスプレイ用の)ハードウェアドライバも、 MicroPythonOSが大きく依存しているlvgl_micropythonプロジェクトに既に含まれていて、利用可能です。

もちろん、移植作業は常に高度な技術を要するため、手間を省きたいのであれば、既にサポートされているデバイスを購入するのが一番です。価格もかなり手頃です。

ポート作業を代行してほしい場合、または寄付にご同意いただける場合は、ぜひご連絡ください。喜んで対応させていただきます!

何を書けばいい?

設計上、MicroPythonOS のデバイス固有のコードはinternal_filesystem/lib/mpos/board/<boardname>.pyファイル内にのみ存在します。

新しいデバイスへ移行する手順

  1. 新しいデバイス向けにlvgl_micropythonをコンパイルしてください。
    目標は、システムを起動させ、シリアル回線上にMicroPython REPLシェルを表示させることです。
    build_mpos.shスクリプトをご覧ください。
    移植手順については、公式のlvgl_micropythonドキュメントも参照してください。運が良ければ、お使いのデバイスは既にesp32 BOARDリストに掲載されているはずです。そうでない場合は、BOARD=ESP32_GENERICBOARD_VARIANT=SPIRAMを指定するか、SPIRAMを搭載している場合はBOARD=ESP32_GENERIC_S3BOARD_VARIANT=SPIRAM_OCTを指定するなど、汎用的なBOARDを使用してください。
  2. 新しいデバイスのディスプレイを初期化する方法を調べてください。
    まずはシリアルポート上のMicroPython REPLシェルを使用して、MicroPythonコードを手動で入力または貼り付け(Ctrl+E)して、何が動作するかを確認してください。
    waveshare_esp32_s3_touch_lcd_2.pyまたはfri3d_2024.pyを見てください。
    基本的には、ディスプレイが接続されている正しいピン(LCD_SCLKLCD_MOSIなどLCD_MOSI)を設定し、ディスプレイの解像度(TFT_HOR_RESTFT_VER_RES)も設定する必要があります。
    試行が失敗した場合は、デバイスをリセットして、ハードウェアが既知の初期状態に戻っていることを確認してください。
    ディスプレイが真っ暗なままで、ピンの接続が正しい場合は、reset_state=0とreset_state=1を切り替える必要があるかもしれません。
    色がずれている場合は、color_space=lv.COLOR_FORMAT.RGB565color_byte_order=st7789.BYTE_ORDER_BGRrgb565_byte_swap=True を調整してみてください。
    成功したとしても、LVGLがまだ何も描画していないため、画面は真っ黒なままです。そこで、最後に以下のコード(main.pyとhelloworld.pyを基にしたもの)を使って何かを表示させてください。
    import lvgl as lv
    import task_handler
    task_handler.TaskHandler(duration=5)
    label = lv.label(lv.screen_active())
    label.set_text('Hello World!')
    label.center()
    
  3. 初期化コードを.pyデバイス専用のカスタムファイルに記述してください。
  4. カスタム<boardname>.pyファイルと汎用MicroPythonOSファイルをデバイスにコピーします(install.shを参照)。
    リセット後、カスタム.pyファイルによってディスプレイが初期化され、その後MicroPythonOSが起動し、アイコンなどを表示するランチャーが実行されます。
  5. ハードウェアのサポートを追加する
    お使いのデバイスにタッチスクリーンが搭載されている場合は、Waveshare 2インチタッチスクリーンの初期化方法をご確認ください。入力用のボタンが搭載されている場合は、 Fri3d Camp 2024 Badgeのキーパッドコードをご確認ください。
    これで、デバイスの操作、Wi-Fiへの接続、App Storeからのアプリのインストールができるようになるはずです。
    この機会にプルリクエストを作成して、<boardname>.py ファイルをメインのコードベースにマージし、公式サポートにしましょう。

コンパイル

コードをダウンロード

リポジトリをクローンする:

git clone --recurse-submodules --depth 1 --shallow-submodules https://github.com/MicroPythonOS/MicroPythonOS.git
cd MicroPythonOS/

MicroPython、LVGL、ESP-IDF、およびそれらのすべての依存関係を再帰的に複製するため、しばらく時間がかかります。

オプション:コードの更新

既に古いクローンがあり、それを更新したい場合は、それを削除して再度クローンを作成するのが最も簡単です。

しかし、帯域幅と時間を節約する必要がある場合は、代わりに以下の手順を実行すると、ローカルでの変更がすべて破棄されます。

cd MicroPythonOS/
git submodule foreach --recursive 'git clean -f; git checkout .'
git pull --depth 1
git submodule update --init --depth 1

コードをコンパイルする

利便性を考慮して、build_mpos.sh スクリプトを使用してください。

使用法:

./scripts/build_mpos.sh <target system>

対象システム: esp32esp32s3unix(= Linux) およびmacOS

例:

./scripts/build_mpos.sh esp32
./scripts/build_mpos.sh esp32s3
./scripts/build_mpos.sh unix
./scripts/build_mpos.sh macOS

生成されたビルドファイルは、例えば lvgl_micropython/build/ に作成されます。

  • lvgl_micropython/build/lvgl_micropy_unix
  • lvgl_micropython/build/lvgl_micropy_macOS
  • lvgl_micropython/build/lvgl_micropy_ESP32_GENERIC_S3-SPIRAM_OCT-16.bin

その他

リリースプロセス

リリースチェックリスト

MicroPythonOSの新しいリリースを作成するには、以下の手順に従ってください。

バージョン番号の更新:

  • 増加しCURRENT_OS_VERSIONますinternal_filesystem/lib/mpos/info.py。
  • 変更されたアプリのバージョン番号を更新してください。
git diff --stat 0.6.0 internal_filesystem/  # Check changes since last release, make sure each app change is accompanied by a META-INF/MANIFEST.json change

変更履歴を更新しました:

  • MicroPythonOS/CHANGELOG.md を「git log」または「git log -p」または「git diff 0.6.0」と比較して、前回のリリース タグ以降に何かが欠落していないか確認してください。
  • 文書の変更点CHANGELOG.md
  • ./scripts/changelog_to_json.shCHANGELOG.md が JSON 形式に対応していることを確認するために実行してください。

すべての変更をコミットしてプッシュします。外部リポジトリ( LightningPiggyなど)でも同様です。

これにより、https://github.com/MicroPythonOS/MicroPythonOS/actions で GitHub ビルドがトリガーされます。

ビルドをダウンロード

完了したら、GitHub Actionsからこれらのビルドを成果物としてダウンロードして展開してください。

  • MicroPythonOS_esp32_0.6.0.ota.zip
  • MicroPythonOS_esp32_0.6.0.bin.zip
  • MicroPythonOS_amd64_linux_0.6.0.elf.zip
  • MicroPythonOS_amd64_macOS_0.6.0.bin.zip

Over-The-Air アップデートのリリース

  • MicroPythonOS_esp32_0.6.0.otaアップデートリポジトリにコピーします。
  • osupdate*.json メタデータファイルを新しいファイルと ./scripts/changelog_to_json.sh の出力で更新します。

ウェブインストーラーへのリリース

  • MicroPythonOS_esp32_0.6.0.binファイルをWebインストーラーにコピーします。
  • manifest.jsonメタデータファイルを更新します。
  • 必要に応じて index.html を更新します (たとえば、新しい metadata.json を追加した場合は、2 つの参照を更新する必要があります)

GitHubへのリリース

  • 新しいGitHubリリースにビルドをアップロードします
  • 新しいタグを入力してください(例:0.6.0)
  • CHANGELOG.md からリストをコピー&ペーストしてください
  • 一番下に「やるべきこと」のセクションを追加する

アプリをバンドルして公開する:

./scripts/bundle_apps.sh
pushd ../apps/
git add apps/
git commit -a
git push

リリースを発表する

注記

  • タグ付けを行う前に、すべてのリポジトリがプッシュされていることを確認してください
  • ターゲットハードウェア上でビルドを検証する
0
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
0
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?