目次


組み込み機器のための実行可能コマンド・シーケンスを作成する

OpenOffice スプレッドシート、XML、PHP、そして BLOB を使ってコマンドを作成する

スプレッドシートから XML 文書への変換は、最新バージョンの Microsoft® Office Excel® と OpenOffice.org Calc の両方に備わっている機能です。この変換機能は、特に組み込みシステムを開発、テストする上で、見掛け以上の力を発揮します。

組み込みシステムの開発者には、設計プロトタイプや初回製品の検証に使用する一連のテスト・シナリオを生成するための手段が必要です。しかも、これらのシナリオを生成するためのコストは最小限に抑えなければなりません。このことは、特化したファームウェアを非常に小さなメモリー・フットプリントで生成する、コスト・エフェクティブな開発環境を作成する場合にも当てはまります。

この記事で説明する手法では、OpenOffice.org Calc、XML、そして PHP スクリプトを使用することで費用をかけずに、テスト・シナリオまたはファームウェア開発環境を作成します。この手法を説明するために、一例として、Modbus コマンドのテスト・シナリオを生成する手順を追っていきます。

スプレッドシートを XML 文書に変換する

OpenOffice.org Calc は Excel と同じく、スプレッドシートを表す XML 文書を 2 つのファイル形式のいずれかで生成することができます。Microsoft Office Excel 2003 XML 形式は XML (.xml) ファイルを生成し、OpenOffice.org Calc のフラットな XML 形式は FODS (.fods) ファイルを生成します。一例として、地元の各映画館で上映される映画のスケジュールが一覧にされた MovieSchedule.xls というスプレッドシートがあるとします。図 1 に、このスプレッドシートの内容を示します。

2 つの映画のタイトル、2 つの映画館、それぞれの上映時間が記載された MovieSchedule スプレッドシートのスクリーン・キャプチャー
2 つの映画のタイトル、2 つの映画館、それぞれの上映時間が記載された MovieSchedule スプレッドシートのスクリーン・キャプチャー
映画のスケジュールのスプレッドシートをテキストで表示したもの (図 1)
     A            B             C
1 Title        Theater      Schedule
2 Avatar       Criterion    3:00 PM, 7:00 PM, 10:30 PM
3 Surrogates   Palace       5:00 PM, 8:00 Pm, 11:00 PM
4
5

次に PHP CLI から PHP スクリプトを実行して、一連のテスト・シナリオの仕様が含まれるスプレッドシートを、それに相当するバイナリー・フォーマットに変換します。リスト 1 に、このスプレッドシートの XML 文書 (Excel 2003 形式) のなかで、スプレッドシートの内容を記述している部分を抜粋します。

リスト 1. 映画のスケジュールの XML 文書
<ss:Worksheet ss:Name="Movies">
     <Table ss:StyleID="ta1">
          <Column ss:Width="127.8144"/>
          <Column ss:Width="127.0512"/>
          <Column ss:Width="191.34"/>
          <Row ss:Height="14.2848">
               <Cell>
                    <Data ss:Type="String">Title</Data>
               </Cell>
               <Cell>
                    <Data ss:Type="String">Theater</Data>
               </Cell>
               <Cell>
                    <Data ss:Type="String">Schedule</Data>
               </Cell>
          </Row>
          <Row ss:Height="14.2848">
               <Cell>
                    <Data ss:Type="String">Avatar</Data>
          </Cell>
               <Cell>
                    <Data ss:Type="String">Criterion</Data>
               </Cell>
               <Cell>
                    <Data ss:Type="String">3:00 PM, 7:00 PM,
                    10:30 PM</Data>
               </Cell>
          </Row>
          <Row ss:Height="14.2848">
               <Cell>
                    <Data ss:Type="String">Surrogates</Data>
               </Cell>
               <Cell>
                    <Data ss:Type="String">Palace</Data>
               </Cell>
               <Cell>
                    <Data ss:Type="String">5:00 PM, 8:00 PM,
                    11:00 PM</Data>
               </Cell>
          </Row>
     </Table>
     <x:WorksheetOptions/>
</ss:Worksheet>

PHP を使用して XML 文書を BLOB に変換する

スプレッドシートの XML 文書は、どのようにしてバイナリー・コードに変換されるのでしょうか。それは、PHP スクリプトによって、以下の処理を行うクラスを使用して行われます。

  1. PHP の DOM クラスによって XML 文書をトラバースします。
  2. トラバースした要素に含まれるコンテンツを一連の中間表現に変換し、これらの中間表現を配列として保存します。
  3. 変換データベースを使用して、中間表現をターゲットとするバイナリー・コードに変換します。
  4. 変換後のバイナリー・コードを BLOB として変換データベースに保管します。

XML 文書のトラバース、そしてコンテンツから中間表現への変換は、ドメインに固有の処理です。つまり、使用されるスプレッドシートの構造に合わせてカスタマイズされるということです。例えばプロトコル・テストのスプレッドシートでは、トラバース用および変換用の 2 つのクラスがその特定のプロトコルの構造に応じてカスタマイズされることになります。変換データベースには、変換参照テーブルとバイナリー・シーケンス・テーブルという 2 つのテーブルがあります。変換参照テーブルは、中間「コード」を対応するバイナリー・シーケンスにマッピングするために使用されます。バイナリー・シーケンス・テーブルは、入力された XML スプレッドシート文書に対応するバイナリー・シーケンスを保管するテーブルです。

例: Modbus テスト・シナリオのシーケンスを作成する

以上の仕組みを具体的に説明するため、これから、シリアル・インターフェース (RS-232 または RS485) を介したデバイスとのシリアル通信のテスト・シナリオとして使用する、Modbus コマンドのシーケンスを指定するためのスプレッドシートを作成します。この OpenOffice.org Calc スプレッドシート (ModbusExample.ods) のワークブックは 2 つのワークシートで構成されます。Modbus はマスター/スレーブ方式のアプリケーション・レベルのプロトコルなので、ホストと一連のスレーブ・デバイスとの通信をサポートする下位レイヤーのネットワーク・タイプには依存しません。通常、シリアル通信ネットワークでは Modbus が使用されますが、TCP/IP で動作するデバイスもいくつかあります。

リクエスト・コマンドは、下位レイヤーのネットワーク・パケットのデータ・セクションまたはメッセージ・セクションの中に組み込まれます。このコマンドは、デバイスの信号データが含まれるデバイス・レジスターの内容を要求します。リクエスト・コマンドのフォーマットは以下のとおりです。

[Device address][Request command][Start register][End register]

[Device address] は Modbus デバイス・アドレス (1 ~ 255) で、長さは 1 バイトです。[Request command] も同じく 1 バイトの長さで、その値はアドレス指定されたレジスターのタイプに応じて設定されます。レジスターの値は、それぞれ以下の内容を表します。

  • 1 = コイル (イベント標識: 1 ビット長)
  • 2 = ステータス (イベント標識: 1 ビット長)
  • 3 = 保持 (内部デバイス信号の値: 4 バイトの浮動小数点値または 2 バイトの整数値)
  • 4 = 入力 (デバイス入力信号の値: 4 バイトの浮動小数点値または 2 バイトの整数値)

レジスターに書き込み可能なコマンドは他にもありますが、通常使用されるのは読み取りアクセス・コマンドです。[Start register][End register] はそれぞれ 2 バイトの長さで、値が要求されているレジスターのアドレス範囲を指定します。Modbus プロトコルに関するその他の詳細は、「参考文献」に記載されている Modbus 標準へのリンクを参照してください。

図 2. デバイス通信設定
デバイス通信設定が記載されたスプレッドシートのスクリーン・キャプチャー
デバイス通信設定が記載されたスプレッドシートのスクリーン・キャプチャー
デバイス通信設定が記載されたスプレッドシートをテキストで表示したもの (図 2)
     A          B         C          D      E        F       G
1 Address    Type      Interface    Baud   Data    Parity   Stop
2 2          Modbus    RS232        9600   8       None     1
3
4

サンプル・スプレッドシートのワークブックに話を戻すと、最初のワークシート Comm (図 2 を参照) には、テスト対象のデバイスにアクセスするためのシリアル通信設定が記載されています。この設定には以下のパラメーターが使用されています。

  • Address: テスト対象デバイスの Modbus ネットワーク・アドレス
  • Type: テスト対象デバイスとの通信に使用されるプロトコル (文書化のためだけに使用)
  • Interface: テスト対象デバイスとホストを接続するために使用されているケーブル・コネクターの物理タイプ
  • Baud: テスト対象デバイスとホストとの間の通信データ転送速度
  • Data: 通信パケットに含まれるデータのビット数
  • Parity: テスト対象デバイスとホストとの間の通信のパリティー設定
  • Stop: テスト対象デバイスとホストとの間の通信のストップ・ビット数

2 番目のワークシート Scenario (図 3 を参照) が指定する項目は以下のとおりです。

  • Register Type: アドレス指定されている Modbus レジスターのタイプ (入力 (Input)、保持 (Hold)、コイル (Coil)、ステータス (Status))
  • Start Register: レジスター・テスト範囲の開始 Modbus レジスター・アドレス
  • End Register: レジスター・テスト範囲の終了 Modbus レジスター・アドレス
  • Type: テスト範囲のレジスターからのレスポンスとして想定される値のデータ型。これらのセルの内容が、レスポンスとして想定される値に要求されるバイト数に変換されます。Int は 2 に変換され、float は 4 に変換されます。ビットは以下の式に変換されます。
    Number of bytes =int((Number of bits + 1) / 8) + 1

    ここで、int([arg])[arg] に含まれる値の整数部分です。

  • Min: Modbus レスポンス・パケットに含まれるレジスターに有効な最小値
  • Max: Modbus レスポンス・パケットに含まれるレジスターに有効な最大値

図 3 をテキストのみで表示したものを見るには、ここをクリックしてください。

図 3. Modbus リクエスト・シナリオ
Modbus リクエスト・シナリオのスクリーン・キャプチャー
Modbus リクエスト・シナリオのスクリーン・キャプチャー
Modbus リクエスト・シナリオが記載されたスプレッドシートをテキストで表示したもの (図 3)
        A               B               C          D      E     F
1 Register Type   Start Register   End Register   Type   Min   Max
2 Input           310              310            Int    0     400
3 Hold            450              452            Int    20    350
4 Hold            530              535            Int    0     100
5 Coil            285              290            Bit    0     1
6

ProtoConvert.php という名前の PHP スクリプト (コピーを入手するには「ダウンロード」を参照) は、スプレッドシートの XML 文書をバイナリー・コマンド・シーケンスに変換します。変換されたコマンド・シーケンスは、上記のスプレッドシートの行ごとに、Modbus リクエスト・パケットによって要求されたレジスター範囲を取得します。そして Modbus レスポンス・パケットに含まれるレジスター値を、それぞれに対応する有効な値の範囲に対して検証します。このスクリプトのベースとなっているのは、以下の 5 つのクラスです。

  • SupportDB: サポート・データベースとの接続を確立し、データベースに対してクエリーを実行して更新を行うためのアクセス・メソッドを提供します。このスクリプトで使用するデータベース・パッケージは MySQL ですが、代わりに IBM® DB2® や PostgreSQL などのデータベース・パッケージを使用することもできます。
  • XMLWorkbook: スプレッドシートの XML 文書ファイルの内容を抽出します。
  • CommSheet: スプレッドシートの Comm ワークシートの内容を、対応する XML 文書から抽出します。
  • ScenarioSheet: スプレッドシートの Scenario ワークシートの内容を、対応する XML 文書から抽出します。
  • ModbusReqSet: Comm および Scenario ワークシートの内容から生成された実行可能コマンドのシーケンスを生成します。

以下に、これらのクラスを使用する根拠となるロジックを説明します。

  1. ProtoTransDB という名前のサポート・データベースとの接続を確立します。このサポート・データベースのメタデータをリスト 2 に記載します。
    リスト 2. 変換データベースのメタデータ
    # 
    #       Protocol test translation support database schema 
    # 
    # 
    
    DROP DATABASE IF EXISTS ProtoTransDB; 
    CREATE DATABASE ProtoTransDB; 
    USE ProtoTransDB; 
    
    # 
    #     Repository of translated protocol test sequences 
    # 
    #     NOTES - 
    # 
    #          (1) TestID = test sequence ID consisting of: 
    # 
    #               1. <TestSpec> = Name of the test sequence 
    #                         specification spreadsheet 
    #               2. <TestStored> = Time stamp when test sequence 
    #                         was translated 
    # 
    #               stored in the format <TestSpec>_<TestStored> 
    # 
    #          (2) TestSequence = executable test sequence 
    # 
    #          (3) The contents of TestSequence consists of 
    #               a sequence of commands as follows: 
    # 
    #               <set_comm> 
    #               <request_1> 
    #               <response_1_verify> 
    #               .................... 
    #               <request_N> 
    #               <response_N_verify> 
    # 
    #          where, 
    #               <set_comm> = communication port configuration 
    #                         consisting of the following: 
    # 
    #                    1. test sequence command (0x0A) 
    #                    2. interface type (0x01 = RS232, 
    #                                   0x02 = RS485 2 wire, 
    #                                   0x03 = RS485 4 wire) 
    #                    3. baud rate (2 bytes) 
    #                    4. number of data bytes (1 byte) 
    #                    5. parity (0x00 = none, 
    #                              0x01 = odd, 
    #                              0x02 = even) 
    #                    6. number of stop bits (1 byte) 
    # 
    #               <request_i> = register value request consisting of the following 
    # 
    #                    1. register requested command (0x0B) 
    #                    2. Modbus register request command (6 bytes): 
    #                         Device address (1 byte) 
    #                         Register read command (1 byte) 
    #                         Start register (2 bytes) 
    #                         End register (2 bytes) 
    # 
    #               <response_i_verify> = register value response verification rule 
    #                    for preceding request consisting of the following: 
    # 
    #                    1. verification rule command (0x0C) 
    #                    2. Bytes per value (Int = 0x02, Float = 0x04, Bit = 0x00) 
    #                    3. Total number of value bytes (2 bytes, 
    #                              Bytes per value * 
    #                              (End register - Start register + 1)) 
    #                    4. Valid minimum for each register value (2 bytes) 
    #                    5. Valid maximum for each register value (2 bytes) 
    #
    
    CREATE TABLE TestScenario 
    ( 
         TestID                         VARCHAR(50) NOT NULL, 
         TestSequence         BLOB,	 
         PRIMARY KEY (TestID ASC) 
    );
  2. スプレッドシートの XML 文書ファイルの内容を抽出します。
  3. XML 文書ファイルから Comm ワークシートの内容を抽出します。
  4. XML 文書ファイルから Scenario ワークシートの内容を抽出します。
  5. Comm および Scenario ワークシートの内容を、Modbus プロトコルで通信するデバイスに対するテスト・シーケンスを定義する実行可能コマンドのシーケンスに変換します。

PHP スクリプトを実行するには以下のコマンドを使用します。

php ProtoConvert.php <database_access> <XML_doc>

ここで、<database_access> はデータベース接続パラメーターが含まれるファイルの完全パス名です。<XML_doc> は、Modbus テスト・シーケンス・スプレッドシートを表す XML 文書が含まれるファイルの完全パス名です。

ステップ 1 からステップ 4 までのいずれかが失敗すると、失敗したステップ以降のステップは実行されません。リスト 2 には、データベースに BLOB として保管されるテスト・シーケンス・コマンドの記述もあります。この例で使用するデータベースには、テスト・シーケンスを保管するテーブルしかありません。変換参照に関する情報は、PHP スクリプトに組み込まれているためです。

リスト 3 に、図 2図 3 に概要を示した Modbus スプレッドシートのテスト・シーケンスを記載します。このシーケンスは実際にはバイト (16 進数値) の連続ストリームですが、シーケンスの構成要素を明らかにするため、リスト 2 のメタデータ・コメントに説明しているテスト・シーケンス構造体ごとの要素に分けて記載しています (16 進数値として表示)。

リスト 3. テスト・コマンド・シーケンスの例
0A 01 2580 08 00 01 

0B 02 04 0136 0136 
0C 02 0002 0000 0190 

0B 02 03 01C2 01C4 
0C 02 0006 0014 015E 

0B 02 03 0212 0217 
0C 02 000C 0000 0064 

0B 02 01 011D 0122 
0C 00 0001 0000 0001

0A で始まるコマンドは、シリアル通信構成の設定を示します。その後の 0B で始まるコマンドと 0C で始まるコマンドのペアは、それぞれリクエスト・コマンドと検証ルール・コマンドです。このコマンドのペアによって、テスト対象デバイスで Modbus レジスターから値を抽出し、抽出した値をチェックします。

実行環境は、ホスト・コンピューターとシリアル回線で接続されたテスト対象デバイスからなります。ホストが実行するテスト・シーケンス・コマンドのインタープリターは、以下のコマンドのそれぞれを実行します。

  • シリアル・ポートの設定 (0A): ホストをテスト対象デバイスに接続するシリアル・ポートを設定します。
  • レジスター・アドレスのリクエスト (0B): 標準 Modbus コマンドによって、テスト対象デバイスの Modbus レジスターの内容を要求します。
  • 検証ルール (0C): 上記のレジスター・アドレスのリクエストによって返された値を、有効な値の範囲に対してテストします。

テスト・シーケンス・コマンドのインタープリターはさらに、後で分析できるように各コマンドに対するレスポンスをログに記録します。

まとめ

OpenOffice.org Calc の XML 文書生成機能、PHP の DOM トラバース機能、そして BLOB 表現のデータベースを使用することによって、スプレッドシートのテスト・シナリオ仕様を正常にテスト・コマンド・シーケンスに変換することができます。けれども、この手法で可能なことはそれだけではありません。

この ModbusExample.ods スプレッドシートの例では、仕様を実際にコマンド・シーケンスに変換しました。スプレッドシートの構造が適切であれば、他にも同様の、仕様からコマンド・シーケンスへの変換ツールを作成することができます。以下はその例です。

  • 入出力仕様に基づいてバッチ生産制御シーケンスを生成
  • デバイス仕様から自動テスト装置プログラムを生成
  • 命令セット数を削減したデバイスのファームウェアを生成

ダウンロード可能なリソース


関連トピック

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=485258
ArticleTitle=組み込み機器のための実行可能コマンド・シーケンスを作成する
publish-date=03302010