9

多くの組み込みアプリケーションでは、コードを非常に効率的にするか、特定のシステム構成からコードを分離して要件の変化の影響を受けないようにするかのトレードオフがあります。

両方の長所 (効率を損なうことなく柔軟性と再構成可能性) を実現するために、通常どのような種類の C コンストラクトを採用していますか?

時間があれば、私が話していることを正確に理解するために読んでください。

私がエアバッグ コントローラー用の組み込み SW を開発していたとき、特定の要件に関して顧客が気が変わるたびに、コードの一部を変更しなければならないという問題がありました。たとえば、エアバッグの展開をトリガーする条件とイベントの組み合わせは、開発中に数週間ごとに変更されました。そのコードを頻繁に変更するのは嫌でした。

当時、私は組み込みシステム カンファレンスに出席し、Stephen Mellor 氏による「変化する要件への対応」という素晴らしいプレゼンテーションを聞きました。ここで論文を読むことができます(サインアップする必要がありますが、無料です)。

これの主なアイデアは、コアの動作をコードに実装し、特定の詳細をデータの形式で構成することでした。データは簡単に変更できるものであり、EEPROM またはフラッシュの別のセクションでプログラムすることもできます。

このアイデアは、私たちの問題を解決するのに最適です。私はこれを同僚と共有し、すぐに SW モジュールの一部を作り直しました。

このアイデアをコーディングで使用しようとすると、実際の実装でいくつかの問題が発生しました。私たちのコード構成は、制約のある組み込みシステムにとって非常に重く複雑になりました。

これを説明するために、前述の例について詳しく説明します。入力の組み合わせがエアバッグの展開を必要とする状態にあるかどうかを判断するための多数の if ステートメントを使用する代わりに、テーブルの大きなテーブルに変更しました。いくつかの条件は自明ではなかったため、多くの関数ポインタを使用して、いくつかの条件を何らかの方法で解決する多くの小さなヘルパー関数を呼び出せるようにしました。いくつかのレベルの間接化があり、すべてが理解しにくくなりました。簡単に言うと、大量のメモリ、ランタイム、コードの複雑さを使用することになりました。物事のデバッグも簡単ではありませんでした。モジュールが重くなりすぎたので、上司は私たちにいくつかの変更を加えました (そして彼はおそらく正しかったでしょう!)。

PS: SO にも同様の質問がありますが、焦点が異なるようです。変化するビジネス要件を満たすために適応していますか?

4

7 に答える 7

3

要件の変更に関する別の観点として...要件はコードの構築に入ります。では、これにメタアプローチを採用してみませんか。

  1. 変更される可能性が高いプログラムの部分を分離する
  2. ソースの一部を結合するスクリプトを作成する

このようにして、互換性のある論理構成ブロックを C で維持し、互換性のある部分を最後にまとめます。

/* {conditions_for_airbag_placeholder} */
if( require_deployment)
     trigger_gas_release()

次に、独立した条件を維持します。

/* VAG Condition */
if( poll_vag_collision_event() )
    require_deployment=1

そしてもう一つ

/* Ford Conditions */
if( ford_interrupt( FRONT_NEARSIDE_COLLISION )) 
    require_deploymen=1

ビルド スクリプトは次のようになります。

BUILD airbag_deployment_logic.c WITH vag_events
TEST airbag_deployment_blob WITH vag_event_emitter

本当に声に出して考えます。このようにして、構成を読み取らずにタイトなバイナリ blob を取得します。これは、オーバーレイ http://en.wikipedia.org/wiki/Overlay_(programming)を使用するようなものですが、コンパイル時に実行します。

于 2009-06-11T21:03:27.070 に答える
2

私たちのシステムは多くのコンポーネントに細分されており、構成とテストポイントが公開されています。起動時に読み取られる構成ファイルがあります。これは、実際にコンポーネントをインスタンス化し、それらを相互に接続し、それらの動作を構成するのに役立ちます。

これは、Cでは非常にOOに似ており、継承のようなものを実装するためのハックがときどきあります。

防衛/アビオニクスの世界では、ソフトウェアのアップグレードは非常に厳密に制御されており、SWをアップグレードして問題を修正することはできません...ただし、奇妙な理由で、大きな争いなしに構成ファイルを更新できます。したがって、これらの構成ファイルで多くの実装を指定できることは非常に便利です。

魔法はありません。システムを設計する際の関心の分離と、開発者側の少しの先見性があります。

于 2009-06-11T20:57:34.540 に答える
2

コード自体が要件の変更の影響を受けないようにするわけではありませんが、要件を実装するコードのセクションには常に、コメントに一意の文字列を挿入してタグ付けします。要件タグを配置すると、要件の変更が必要になったときにそのコードを簡単に検索できます。このプラクティスは、CMMI プロセスも満たしています。

たとえば、要件ドキュメントでは次のようになります。

以下は、RST に関連する要件のリストです。

  • [RST001] ジュリエットは、イグニッションがオフになったときに 5 分遅れて RST を開始する必要があります。

そしてコードで:

/* Delay for RST when ignition is turned off [RST001] */
#define IGN_OFF_RST_DELAY 5

...snip...

                        /* Start RST with designated delay [RST001] */
                        if (IS_ROMEO_ON())
                        {
                            rst_set_timer(IGN_OFF_RST_DELAY);
                        }
于 2009-06-25T17:50:55.413 に答える
1

できることは、必要に応じて EEPROM または I/O ポートからフェッチできるデータのバイトまたはワードに基づいていくつかの有効な動作を指定し、それらのバイトによって記述されるすべての可能なイベントを処理する汎用コードを作成することだと思います。

たとえば、エアバッグを解放するための要件を指定したバイトがある場合、次のようになります。

ビット 0: 後方衝突

ビット 1: 時速 55 マイルを超える速度 (速度値を一般化するためのボーナス ポイント!)

ビット 2: 車の乗客

...

次に、どのイベントが発生したかを示す別のバイトを取り込み、2 つを比較します。それらが同じ場合はコマンドを実行し、そうでない場合は実行しないでください。

于 2009-06-11T23:52:27.680 に答える
1

変化する要件に適応するために、コードをモジュール化して変更しやすいものにすることに専念します。たとえば、変更される可能性のあるパラメーターにマクロやインライン関数を使用するなどです。

コードから独立して変更できる構成については、再構成可能なパラメーターも要件で指定されることを願っています。特に、エアバッグ コントローラーのような安全性が重要な要素の場合。

于 2009-06-12T06:45:01.243 に答える
0

動的言語のフックは、メモリとプロセッサの能力があれば、命の恩人になる可能性があります。

C にハードウェアと通信させ、既知の一連のイベントを Lua などの言語に渡します。Lua スクリプトでイベントを解析し、適切な C 関数にコールバックします。

C コードが正常に動作するようになったら、ハードウェアが変更されない限り、再度コードを変更する必要はありません。すべてのビジネス ロジックがスクリプトの一部になるため、作成、変更、保守がはるかに簡単になると思います。

于 2009-06-11T21:31:36.240 に答える