column
技術情報・基礎知識
組み込みソフトウェアの基本 組み込みソフトウェアとは?種類・特徴・開発の流れを解説
家電や自動車、産業機器、医療機器など、私たちの身の回りで動いている「電気で動くモノ」のほぼすべてに組み込みソフトウェアが搭載されています。ところが「組み込みソフトウェア」という言葉自体は普段あまり意識されることがなく、PCアプリやスマートフォンアプリとの違いを聞かれると言葉に詰まる方も少なくありません。本記事では、組み込みソフトウェアとは何かという定義から、種類、ハードウェアとの関係、動作環境の違い、開発の流れ、そして組み込みソフトウェア特有の難しさまでを順を追って解説します。これから組み込み開発に関わる方や、ハードウェア側から組み込みソフトウェアに関わることになった方が、全体像を一気に掴むことを目指した内容です。
組み込みソフトウェアとは
組み込みソフトウェアとは、特定の機器に内蔵され、その機器を制御するために動作するソフトウェアの総称です。汎用のPCで動くアプリケーションのように利用者が自由にインストール・アンインストールするものではなく、出荷時点であらかじめ機器の中に書き込まれており、その機器の機能そのものを実現する役割を担います。電子レンジが温め時間を計測してマグネトロンを制御するのも、エアコンが室温に応じて圧縮機の回転数を変えるのも、すべて内部の組み込みソフトウェアが行っています。
PCソフトウェアやスマートフォンアプリと組み込みソフトウェアの最大の違いは、ハードウェアとの距離感にあります。PCアプリはOSの上に乗り、ハードウェアの違いをOSが吸収してくれるためハードウェアを意識せずに動きます。一方の組み込みソフトウェアは、対象機器のCPU・メモリ・周辺回路の仕様に合わせて作り込まれることが多く、ハードウェアが変われば書き換えが必要になることも珍しくありません。
組み込みソフトウェアの主な種類
組み込みソフトウェアは、機能の階層によっていくつかの層に分けて考えると整理しやすくなります。最も下層に位置するのがファームウェアです。ファームウェアはハードウェアを直接叩く役割を担い、電源投入時の初期化処理、デバイスドライバ、入出力ポートの制御といった、機器が動き出すための土台部分を構成します。利用者が直接目にすることはありませんが、ファームウェアが正しく動かなければ上位のソフトウェアは一切動作しません。
その上に位置するのがミドルウェアです。ミドルウェアは、通信プロトコルスタック、ファイルシステム、GUI描画ライブラリ、暗号化処理など、複数のアプリケーションで共通して使われる機能をまとめて提供する層です。ミドルウェアを活用することで、アプリケーション開発者は車輪の再発明をせずに済み、機器固有のロジックづくりに集中できます。
最上位がアプリケーション層で、機器の機能そのものを実現するロジックが置かれます。利用者から見える動作、たとえば「ボタンを押したら何が起きるか」「センサーの値に応じてどう応答するか」といった振る舞いは、ほぼこの層で決まります。組み込みソフトウェアと一口に言っても、どの層を担当するのかによって必要な知識領域は大きく異なるため、自分が関わる層を意識することが開発を進めるうえでの第一歩になります。
ハードウェア構成との関係
組み込みソフトウェアは、搭載されるハードウェアの構成によって設計の前提が大きく変わります。最も一般的なのがマイコン(MCU)を中核とした構成で、CPU・メモリ・ペリフェラルを1チップに統合した部品を基板に載せ、その上で動くソフトウェアを開発する形になります。多くの産業機器、家電、車載ECU、IoT機器がこの構成を採っており、組み込みソフトウェア開発の入口として最もメジャーな選択肢です。
より高い処理性能が必要な場合には、SoCと呼ばれる高集積チップが選ばれます。CPUコアの性能が高く、GPU、通信機能、各種インターフェイスが1チップに集約されているため、スマート機器、車載インフォテインメント、産業用コンピュータなどで採用が広がっています。一方、ソフトウェアだけでは間に合わないほどの高速処理や信号処理が必要な場面では、論理回路そのものを書き換えられるFPGAが使われ、組み込みソフトウェアと組み合わせて高度な制御を実現することもあります。どのハードウェアを選ぶかでソフトウェア設計の自由度・難易度・必要工数が変わるため、初期段階でのハード/ソフトの擦り合わせが極めて重要です。
動作環境による分類
組み込みソフトウェアを動かす土台、いわゆる動作環境にも選択肢があります。リソース、リアルタイム性、必要な機能によって使い分けることになりますが、現場で選ばれるのはおおむね3つの方向性です。
ひとつ目はベアメタル開発と呼ばれる方式で、OSを介さずハードウェアを直接制御します。OSの分のメモリやCPU負荷がかからず、応答時間も予測しやすいため、メモリ数十KB級の小型マイコンや、シンプルな制御で十分な機器に向いています。ただしマルチタスクや通信スタックといった機能はすべて自前で実装する必要があり、機能が増えるほど開発・保守の負担が大きくなります。
ふたつ目がRTOS(リアルタイムOS)の採用です。RTOSは、決められた時間内に決められた処理を必ず終わらせる「リアルタイム性」を保証することを目的としたOSで、複数タスクの優先度制御や同期機構を提供します。FreeRTOSやμITRON系、Zephyr、Azure RTOSといった選択肢があり、モーター制御、計測機器、医療機器、車載ECUなど、応答時間に厳しい要件がある機器で広く使われています。
みっつ目が組み込みLinuxです。一般的なLinuxを組み込み向けに最適化したもので、TCP/IPスタックやファイルシステム、GUIライブラリ、各種言語処理系といった豊富な資産をそのまま活用できる点が魅力です。ネットワーク機能やリッチなUIが求められる機器、データ処理量の多い機器に向いており、ゲートウェイ機器や産業用コンピュータ、医療機器などで採用が進んでいます。一方で、起動時間の長さや厳密なリアルタイム性の確保が難しいといった弱点もあるため、要求仕様に応じて他方式と組み合わせることもあります。
組み込みソフトウェア開発の基本フロー
組み込みソフトウェアの開発は、PCアプリのようにいきなりコードを書き始めるのではなく、ハードウェアと擦り合わせながら段階的に作り上げていきます。最初の工程となるのが要件定義で、機器に求められる機能・性能・動作環境・寿命・規格対応などを明確化します。要件があいまいなまま実装に進むと、後工程で大規模な手戻りが発生するため、ここでハードウェア担当者・機構担当者・調達担当者を巻き込んで仕様を固めることが重要です。
続く基本設計・詳細設計のフェーズでは、ソフトウェアをモジュールに分割し、状態遷移、割り込み構成、メモリマップ、タスク構成といった「動く前の骨格」を設計します。組み込みソフトウェアでは、この設計の質がそのまま信頼性に直結します。リアルタイム性を要求される処理を割り込みに置くか通常タスクに置くか、メモリをどう配置すれば断片化を防げるかといった判断は、後から修正するコストが非常に高いため、設計段階で時間をかけて検討します。
実装フェーズでは、C言語を中心にC++、近年ではRustも選択肢に加わってきました。ハードウェアに直接触れる部分と上位ロジックを明確に分けて記述するのが鉄則で、移植性とテスト容易性を確保しておくと、後の派生開発で大きな差が出ます。検証フェーズでは、単体テスト、結合テスト、システムテストの順に粒度を上げ、シミュレータと実機の両方を使い分けて確認します。実機では、JTAGやICEなどのデバッガ、ロジックアナライザ、オシロスコープといった物理的な計測手段が活躍します。
最終的な量産・保守フェーズでは、製造ラインでのプログラム書き込み、出荷検査、フィールドで発生する不具合への対応が中心になります。組み込み機器は出荷後も長く使われるため、開発が終わってからのほうが付き合いが長くなることも珍しくありません。
組み込みソフトウェア特有の難しさ
組み込みソフトウェア開発には、PCアプリ開発にはない難所がいくつもあります。最も象徴的なのがリアルタイム性の確保で、「動けばいい」ではなく「決められた時間内に必ず動く」ことを保証しなければなりません。タイミングが数ミリ秒ずれただけで装置が止まる、製品が不良品になる、安全性が損なわれるといった世界です。
加えて、限られたリソースのなかで最適化を行う必要があります。メモリ容量、CPU処理能力、消費電力、発熱、コストといった制約は互いにトレードオフの関係にあり、ひとつを優先すれば他が犠牲になります。ハードウェアとソフトウェアを横断して最適点を探る感覚が、組み込みエンジニアには欠かせません。
デバッグ環境にも独特の難しさがあります。PCアプリのようにブレークポイントを置いて止めて中身を覗く、という操作が常に使えるとは限りません。割り込みの瞬間や通信の一瞬の挙動を捉えるには、波形を計測したり、デバッグ用のログ出力経路を別途用意したりといった工夫が必要になります。さらに、出荷後10年以上にわたって部品EOLや仕様変更に対応し続ける長期保守の負担もあり、設計段階から「保守を見越した作り」が求められます。
組み込みソフトウェア開発にはハードウェアの視点が必要
組み込みソフトウェアは、機器のハードウェアと一体になって設計される、特殊な制約と高い信頼性要求を抱えたソフトウェアです。ファームウェア・ミドルウェア・アプリケーションといった層構造、マイコン・SoC・FPGAといったハードウェア構成、ベアメタル・RTOS・組み込みLinuxといった動作環境の選択肢が複雑に絡み合い、要件に応じて最適な組み合わせを選び取っていくことになります。プロジェクトを成功させるためには、開発の早い段階から全体像を把握し、ハードウェア設計と歩調を合わせて進めることが何より重要です。