組み込みソフトウェア開発の全体像と手戻りを防ぐ設計の役割

近年の組み込みシステムは、かつてないほど高度化し、ソフトウェアが占める重要性は増しています。たとえば自動車に実装されている組み込みソフトウェアは、1台当たりのソースコード行数が2007年ごろには約1,000万行でしたが、2016年には1億行に到達し増え続けています。
組み込みシステムの需要が高まる一方で、組み込みソフトウェア開発の現場では人手不足や納期の短縮、ソフトウェア仕様の複雑化といった課題に直面しているのが現状です。
プロジェクトを破綻させる要因の一つが手戻りです。特に開発終盤で見つかる致命的な不具合は、単なるバグ修正に留まらず、根本的な設計変更に至る場合もあります。
そこで本記事では、組み込みソフトウェアにおける開発工程の全体像と、手戻りを防ぎ高い品質を確保する方法について解説します。この記事を読めば、組み込みソフトウェア開発における要件定義から実装に至る設計フェーズの役割と、致命的な手戻りを防ぐための具体的な方法を理解できます。
組み込みソフトウェア開発の全体像

組み込みソフトウェアの特徴は、ハードウェアと密接に連携している点です。ハードウェア由来の物理的な制約が多く、設計段階で認識齟齬によるミスが生じると、ハードウェアの変更を伴う大幅な手戻りが発生するケースも珍しくありません。
ここでは、組み込みソフトウェア開発特有の難しさや上流工程の重要性について説明します。
ハードウェアとの並行開発が生む難しさ
組み込みソフトウェア開発において難しいポイントは、土台となるハードウェアの仕様が未確定な状態でも設計を進めなければならない点にあります。
たとえば、開発途中で製品に使われる部品が変更になった場合、すでに実装を進めていたドライバや信号処理ロジックの書き直し、仕様変更に伴う周辺機器への影響確認に膨大な工数が費やされます。
そのため、開発の初期段階からハードウェア担当者と密にコミュニケーションを取り、ハードウェア側の開発状況や仕様変更の可能性をリアルタイムで共有することが重要です。
このようなハードウェアを意識した開発が必要である点が、汎用ソフトウェアの開発と組込みソフトウェア開発の一番大きな違いであり、難しい点です。
V字モデル開発における上流工程の重要性
組み込みソフトウェア開発は、一般的にV字モデルに沿って進められます。V字モデル開発とは、左側に設計工程、右側にテスト工程を配置し、それぞれが対になる形で検証する開発手法です。
V字モデル開発では、上流工程である設計フェーズの作り込みが重要視されます。なぜなら、上流工程と比較して下流工程での修正コストがきわめて大きいからです。NIST(米国国立標準技術研究所)の調査によると、設計段階で見つかったバグの修正コストに比べ、リリース後の修正コストは約30倍に達すると報告されています。
バグの修正コストを抑えるためにも、不具合そのものを発生させないように、設計段階で品質を作り込むことも大切です。
組み込みソフトウェアの品質を左右する設計フェーズの役割

設計フェーズは、以下の3工程で構成されます。
- 要件定義
- システム設計(基本設計、詳細設計)
- 実装
各工程が担う役割を解説します。
1.要件定義
要件定義はユーザーからの要望を具体化し、ソフトウェアで実現させる内容(機能)を明確にする工程です。組み込みソフトウェアの場合には、ハードウェアの限界を考慮した非機能要件も数値で確定させる必要があります。
現場で起きる深刻な手戻りは、メモリ不足や処理落ちといった不整合が原因です。この手戻りを防ぐためには、要件定義の段階で具体的な応答速度や消費電力、メモリ占有量などの数値を確定させ、ハードウェア仕様として成り立つか検証することが大切です。
事前の検証により、そもそも実現不可能なのに開発が進んでしまった、という重大なトラブルを未然に防げます。
2.システム設計(基本設計、詳細設計)
システム設計(基本設計、詳細設計)の役割は、要件定義で決まった抽象的な振る舞いを、具体的な動作ロジックへと落とし込む点にあります。実装者が迷いなくコーディングできるレベルまで具体化することがポイントです。
まずシステム全体を独立したモジュールに分割し、それぞれのインターフェースを厳密に定義します。たとえば、通信経由で取得したデータや各センサの値がどのモジュールで処理され、どのタイミングで出力されるかを確定させます。非機能要件であるパフォーマンスに関しても、満たさなければいけない要求がある場合はこの段階で実現方法を検討し、確定させます。たとえ開発途中でハードウェアの仕様変更や部品の載せ替えが発生したとしても、修正の範囲を限定することが可能です。
加えて、各モジュール内のアルゴリズムや状態遷移、バッテリ異常などの例外処理のルールもこの時点で確定させます。設計段階でこれらのルールを決めておくことにより、後のテスト工程での合否基準ができるため、開発終盤での根本的なロジック破綻による手戻りを防止できます。
この段階で、ハードウェアとソフトウェアの両面から、要求される機能、非機能の両方の要件を満たせることを確認しましょう。
3.実装
実装は、設計に込められた意図をソースコードとして実体化する工程です。単にコードを書くだけではなく、実装時点でプログラムの純度を高めることが、プロジェクト全体のリードタイム短縮に直結します。
実機テストで発覚したバグの修正は、設計フェーズで修正する場合と比べ数十倍の工数を要します。この修正工数を抑えるためにも、コードレビューや静的解析によって不具合の原因をなるべく早く取り除くことが大切です。
組み込みソフトウェアの品質は設計で作り込む
組み込みソフトウェアの品質は、テストで見つけるものではなく、設計フェーズにおいて作り込むのが理想です。要件の曖昧さは下流工程において不具合としてあらわれ、プロジェクトに致命的な手戻りをもたらします。
プロジェクトの進行速度を維持しながら品質を高めるためには、開発フェーズにおいて以下のような入念な作り込みが不可欠です。
- 要件定義における具体的な数値化
- 高速な応答といった曖昧な表現を排除し、非機能要件を数値で定義することにより、ハードウェアとの不整合を防止できます。
- システム設計における構造の具体化
- 実装者が迷いなくコーディングできるレベルまで、設計を具体化します。さらにハードウェアとロジックを切り離し、実機の完成を待たずにソフトウェアを検証できるテスタブルな構造の構築が理想です。
- 実装段階での静的検証
- 実機で実際に動かしてから直すのではなく、コーディング規約の遵守や解析ツール、コードレビューによって、実装の段階で不具合を徹底的に排除します。
V字モデルの左側で品質を完結させるような意識を徹底することにより、複雑な組み込みソフトウェア開発においても手戻りを最小化し、スムーズにプロジェクトを進められるようになるでしょう。

