11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RTOSとRust Embassyフレームワーク(async/await)の比較:組み込み開発の新たな選択肢

11
Last updated at Posted at 2025-12-11

はじめに

こんにちは!東芝で組み込みソフトウェアを開発しているエンジニアです。
私が所属する部署では、RTOSを用いた組み込み開発が主流ですが、より複雑化する要求に応える中で、可読性の高いコーディングが求められています。
そんな中、RustとRustのasync/awaitをベースにしたEmbassyフレームワークが、これらの課題を解決する新たな選択肢となり得るのではないかと考え、調査・比較したのが本記事の執筆動機です。

本記事では、組み込みシステムの開発で広く使われているRTOS(Real-Time Operating System)と、モダンなプログラミング言語RustのエコシステムであるasyncフレームワークEmbassyを比較し、それぞれのアーキテクチャ、メモリ効率、開発体験の違いについて記載しました。

RTOSとは

RTOS(Real-Time Operating System)は、組み込みシステムで複数の処理(タスク)をリアルタイムに実行するためのOSです。

主な役割は以下の通りです。

  • マルチタスク: 複数のタスクを同時に実行しているように見せます。
  • スケジューリング: どのタスクをいつ実行するかを決定します。
  • タスク間通信: タスク同士がデータをやり取りする仕組みを提供します。

従来のRTOSでは、多くの場合「プリエンプティブマルチタスク」方式が採用されています。これは、実行中のタスクがタイムスライスを使い切るか、sleepなどで能動的に処理を中断(ブロック)するか、あるいはより高優先度のタスクによって強制的に割り込まれるまで実行され、その後スケジューラが次のタスクに切り替える、というものです。各タスクはそれぞれ専用のスタックメモリを必要とするため、タスクが増えるとメモリ消費が大きくなる傾向があります1

async/awaitフレームワークEmbassyとは

Embassyは、Rustのasync/await構文をマイコンなどのベアメタル環境で利用可能にする、次世代の組み込み向け非同期フレームワークです。

RTOSがOSとしてスケジューリング機能を提供するのに対し、Embassyはasync/awaitを利用して、タスクが「待つ」時間を効率的に利用することでマルチタスクを実現します。このとき、asyncで定義されたタスクはコンパイル時に「ステートマシン」に変換されます2。これにより、タスクごとに大きなスタックを確保するのではなく、タスクの状態を保持するために必要な最小限のメモリ(RAM)で動作します3

なお、Embassyを使用すると、プログラムサイズ(Flash使用量)が若干増加する可能性がありますが、STM32などのマイコンでは、この増加は問題になるほどではありません3。重要なのは、多数のタスクを実行する場合、各タスクが作成時に確保したスタック領域を常に占有し続けるRTOSと比較して、Embassyの方がRAM効率が良くなる傾向があるという点です。

Embassyの利点

Embassyフレームワークには、従来のRTOSにはない以下のような利点があります。

  • 実行モデル: async/await構文を用いた協調的マルチタスキング。プリエンプティブ方式と異なり、タスクは.awaitポイントで自発的に制御を手放します。これにより、タスクはFutureとして表現され、エグゼキューター(イベントループ)によって効率的に実行されます。
  • メモリ効率: タスクはステートマシンにコンパイルされ、待機中のタスクの状態のみが保存されます。これにより、タスクごとに大きなスタックを確保する必要がなくなります。

RAMメモリ使用量の比較(概念図)

以下の図は、RTOSとEmbassyのRAMメモリ使用方法の概念的な違いです。

ポイント:

  • RTOS: 各タスクは作成時に指定されたサイズのスタック領域を持ち、実行中でなくても常にそのメモリを占有し続けます1。タスクが待機状態やブロック状態でも、スタック領域は解放されません。
  • Embassy: すべてのタスクが1つのスタックを共有し、実行中のタスクのみがスタックを使用します。待機中のタスクは、.awaitポイントで必要な状態(ローカル変数など)のみをRAMに保持します。

この違いにより、特に多数のタスクを実行する場合や、タスクの多くが待機状態にある場合(I/O待ちなど)、Embassyの方がRAM効率が良くなる傾向があります。

具体的な動作例

今回は、STM32F303VC®マイコン上でEmbassyを動かしてみました。
実装したのは、ボタンのクリックパターン(シングル、ダブル、長押し)を検出し、複数のLEDを制御するという、アプリケーションです。

タスク構成

全体の構成は以下のようになっています。

コード例:ボタンイベント検出タスク

async/awaitの強力さが最も表れているのが、ボタンイベントを検出するタスクです。

// Task1: Button Handler - ボタンイベント検出タスク
#[embassy_executor::task]
async fn button_handler_task(mut button: ExtiInput<'static>) {
    info!("Task1: Button Handler 起動");

    loop {
        // ボタン押下を待機 (CPUを消費しない)
        button.wait_for_rising_edge().await;
        info!("ボタン押下検出 [1回目]");

        // リリース待ち(タイムアウトで長押し判定)
        let is_long_press =
            embassy_time::with_timeout(LONG_PRESS_DURATION, button.wait_for_falling_edge())
                .await
                .is_err();

        if is_long_press {
            info!("→ 長押し検出");
            BUTTON_EVENT.signal(ButtonEvent::LongPress);
            button.wait_for_falling_edge().await; // リリース待ち
            continue;
        }

        // ダブルクリック判定(2回目のクリックを待機)
        info!("ボタンリリース、ダブルクリック待機中...");

        match select(
            Timer::after(DOUBLE_CLICK_TIMEOUT),
            button.wait_for_rising_edge(),
        )
        .await
        {
            Either::First(_) => {
                // タイムアウト → シングルクリック確定
                info!("→ シングルクリック確定");
                BUTTON_EVENT.signal(ButtonEvent::Click);
            }
            Either::Second(_) => {
                // 2回目のクリック検出
                info!("→ ダブルクリック確定");
                BUTTON_EVENT.signal(ButtonEvent::DoubleClick);
            }
        }
    }
}

このコードのawaitに注目してください。これは、button.wait_for_rising_edge()(ボタンが押される)やTimer::after()(一定時間が経過する)といったイベントが発生するまで、CPUを他のタスクに明け渡すことを意味します。RTOSのsleepやイベント待機に似ていますが、より直感的で可読性の高いコードになっていることが分かります。

実行ログ

実際に動作させた際の写真とログです。シングルクリック、ダブルクリック、長押しが検出されています。

IMG_0001 (1).JPG

VSCodeのデバッグコンソールに表示された実行ログの一部です。
image.png

RTOSとEmbassyの比較まとめ

特徴 RTOS (従来のアプローチ) Embassy (新しいアプローチ)
ベースの仕組 プリエンプティブマルチタスキング 協調的マルチタスキング (async/await)
RAMメモリ効率 △ (タスクごとにスタックが必要) ◎ (スタックを共有し、状態のみ保持)
Flashメモリ使用量 〇 (比較的軽量) △ (バイナリサイズが大きくなる傾向)
スケジューリング 優先度ベース、ラウンドロビンなど多彩 フェアスケジューリングが基本
タスクの優先度 設定可能 基本的にフラット
非同期処理の抽象度(※1) APIベース (セマフォ、キューなど) 言語機能 (async/await)
エコシステム 成熟しており、実績が豊富 成長中、Rustの強力な型システムを活用
安全性 データ競合のリスク (要排他制御) データ競合のリスクが低い (Rustため安全)

※1:RTOSではAPI呼び出しで行っていた処理の多くが、EmbassyではRustのasync/await構文と型システムに統合され、よりモダンなスタイルで記述が可能です。

まとめ

本記事では、RTOSとRust Embassyフレームワークを比較しました。Embassyは、async/await構文によって、省メモリかつCPU利用効率の高い、そして個人的には書いていて楽しい組み込み開発を実現してくれそうだなと思いました。Rustの強力な型システムや安全性と相まって、これからの組み込み開発における有力な選択肢の一つとなる可能性を秘めていると感じています。

最後に我々の部門の紹介です。
私は、東芝の電力プラットフォーム開発部(通称:P開ブ)という部署に所属しています。
P開ブでは、発電所の安定稼働を支える制御システムなど、電力の安定供給に不可欠なプラットフォームを開発しています。
その領域は、デバイスドライバのような低レイヤから、ハードウェア開発、Linux向けアプリケーション、Webアプリケーションまで多岐にわたります。

私たちの代表的な製品の一つに、火力発電所向けの高信頼性コントローラTOSMAP-LX®があります。
これは、Linux®をベースとしながら、リアルタイム性能と高い信頼性を両立させた自社開発のプラットフォームです。
TOSMAP-LX®は、発電所のボイラーやタービンといった重要設備を精密に制御する頭脳として、国内外の多くのプラントで活躍しています。

P開ブでは、TOSMAP-LX®のような既存製品の機能強化に加え、機能安全(Functional Safety)への対応や、新しい技術を用いた次世代製品の先行開発にも積極的に取り組んでいます。

ご興味があれば、P開ブに関連する以下の技術解説もぜひご覧ください。

もし「電力という社会インフラを支える仕事がしたい」「ソフトウェアからハードウェアまで幅広い技術に触れたい」と思っている方がいれば、ぜひ私たちと一緒に次世代の電力プラットフォームを創っていきませんか?
P開ブは、技術への探求心にあふれるエンジニアをいつでも歓迎しています!

最後までお読みいただき、ありがとうございました。
Happy Hacking!


商標について

  • TOSMAP-LX®は、東芝エネルギーシステムズ株式会社の登録商標です。
  • Linux®は、Linus Torvalds氏の米国およびその他の国における登録商標または商標です。
  • STM32®は、STMicroelectronics社の登録商標です。
  • FreeRTOS™は、Amazon.com, Inc.またはその関連会社の商標です。
  • Embassyは、オープンソースプロジェクトであり、特定の企業や組織による商標登録はありません。
  1. FreeRTOS™ - Stack usage and stack overflow checking 2

  2. The Async Book - async/.await Primer

  3. The Embassy Book - What is async? 2

11
1
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
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?