なぜ状態遷移表を使うと、品質の良い開発ができるのか:状態遷移表による設計手法(2)(1/2 ページ)
状態遷移表による設計手法について解説。第2回では、状態遷移表を利用するとなぜ品質の良い設計・開発ができるのか、その理由を詳細に説明する。
はじめに
組み込みソフトウェアが抱える一番の課題は「設計品質の向上」です。そして、この設計品質の向上にはモデルベース設計が有効であり、数あるモデルの中でも“状態遷移系モデル”が最も多く使われています。このあたりの詳細については、前回お伝えした通りです。
本連載の主役である「状態遷移表」は、“イベント“と“状態”を全て網羅的に表現できるため、設計の「モレ」「ヌケ」の発見・防止に大きな効果があり、設計品質の向上が期待できます。
第2回では「なぜ状態遷移表を使うと、品質の良い開発ができるのか」をテーマに、その詳細を説明していきます。
なお、本連載では以下の6つのテーマを順番にお届けしていきます。
- (前回):状態遷移表設計手法の概要
- なぜ状態遷移表を使うと、品質の良い開発ができるのか
- 状態遷移表を使用した要求分析モデル
- 状態遷移表を使用した設計モデル(拡張階層化状態遷移表)
- 状態遷移表からの実装
- 状態遷移表を使用したテスト手法
今回紹介する組み込みシステム環境について
リアルタイム性を強く要求される組み込みシステムの場合、しばしば「リアルタイムOS」が使用されます。
リアルタイムOSは、実行コンテキストを保持するオブジェクト(タスク、もしくはスレッド、以下“タスク”で統一)単位で動作します。そして、確実に実行要求を受け取るハンドラを起動して、実行要求を取りこぼすことがないようにスケジューリングされた動作を行います。そのため、高優先度のタスクを確実に実行しなければならないシステムには、リアルタイムOSがよく利用されています。
本稿では、“リアルタイムOSで動作するタスクの振る舞い設計”を題材に、今回のテーマを詳しく掘り下げていくことにします。
今回説明に使用するタスク構造
まず、今回説明に使用するタスク構造を以下に記します。
- Aデバイスからデータを受信した際は、Aデバイスコントロールタスクへ要求イベントが渡され、メイン管理タスクへイベントが送られる
- Bデバイスからデータを受信した際は、Bデバイスコントロールタスクへ要求イベントが渡され、メイン管理タスクへイベントが送られる
- メイン管理タスクでは、それらの要求イベントを管理し、要求に応じてCデバイスコントロールタスク、もしくはDデバイスコントロールタスクへ送信要求イベントを送信する
- Cデバイスコントロールタスクは、メイン管理タスクから送信要求イベントを受け取ると、Cデバイスドライバへデータを送信する
- Dデバイスコントロールタスクも、メイン管理タスクから送信要求イベントを受け取ると、Dデバイスドライバへデータを送信する
そして、図1は上記のタスク構造を図で示したものです。
今回説明に使用するタスクの要求仕様書
図1の例では、「Aデバイスコントロールタスク」「Bデバイスコントロールタスク」「Cデバイスコントロールタスク」「Dデバイスコントロールタスク」と、4つのデバイスコントロールタスクが存在しています。
ここでは、それらの中から“Cデバイスコントロールタスクの要求仕様書”について考えてみましょう。
図2に示す要求仕様書では、Cデバイスドライバが正常に動作したケースと、正常に送信が完了しなかった異常ケースについて記しています。
シーケンス図で表現してみよう
図2の要求仕様書はご覧の通り、日本語で記述されています。まずは、タスク間におけるイベントの関連をイメージしやすくするために、これを「シーケンス図」で表現してみます。
図3のシーケンス図は、「メイン管理タスク」「Cデバイスコントロールタスク」「Cデバイスドライバ」「タイマ」におけるイベントの関連を表現したものです。また、正常ケース(図3左)と異常ケース(図3右)の動作を分割して表しています。
フローチャートで表現してみよう
次に、状態遷移表設計手法を使用せずに、シーケンス図からフローチャートを作成した場合を考えてみます。
シーケンス図のうち、Cデバイスコントロールタスクに向けて内側に矢印「→」が向いているイベントが、Cデバイスコントロールタスクへの“入力イベント”になります。該当するのは、「メイン管理タスクからの送信要求」「Cデバイスドライバからの送信完了」「タイマからのタイムアウト」の3つです(図4)。
また、Cデバイスコントロールタスクから外側に矢印「→」が向いているイベントが、Cデバイスコントロールタスクからの“出力イベント”になります。該当するのは、「Cデバイスドライバへのデータ送信」「メイン管理タスクへの送信完了」「メイン管理タスクへの異常完了」の3つです(図5)。
通常は、図4と図5の情報を参考にして実装を行いますが、今回はさらにフローチャートで表現してみたいと思います。
「メイン管理タスクからの送信要求」「Cデバイスドライバからの送信完了」「タイマからのタイムアウト」などの入力イベントと、「Cデバイスドライバへのデータ送信」「メイン管理タスクへの送信完了」「メイン管理タスクへの異常完了」などの出力イベントを記述していくと、図6のようなフローチャートになります。
現場で発生する不具合の例
それでは、図6のフローチャートを基に“不具合の可能性”を考えてみましょう。
組み込みシステムの開発現場で実機試験を行っていると、「通常は、ドライバから正常にデータが送信されているが、何かのタイミングで正常にデータが送信されず、ハードウェアがハングアップしてしまう」などの不具合が発生することがよくあります。
実際に、こうした不具合の原因を調べてみると、「メイン管理タスクから送信要求イベントを受け、デバイスドライバに対してデータを送信している最中に、連続してメイン管理タスクから送信要求イベントが発生するといったケースの対応(処理)が設計から抜けてしまっていた……」などということがあり得ます(図7)。
ソースコードは、フラグの嵐になってしまう
先の不具合対応として、「送信中」と「送信中以外」を判断するための“フラグ”を使用します。具体的には、送信中にメイン管理タスクから送信要求があった場合に、「メイン管理タスクにビジーを返す」などの処理を追加するのです(図8)。
こうした対応を繰り返していくうちに、フラグが増えていき……。結果的にソースコードは“フラグの嵐”になってしまいます。
Copyright © ITmedia, Inc. All Rights Reserved.