2

質問をする前に、背景を説明させてください。

Autosarに関する技術記事を読んでいましたアプリケーション層ソフトウェア コンポーネントのプラグ アンド プレイ アプローチを提案したアーキテクチャ。基本的に、この記事では、メモリを個別のコンポーネントに分割し、ソフトウェア イメージ全体ではなく、変更されたコンポーネントのみをプログラム /flash できることを提案しました。これにより、ディーラー訪問時の再プログラミング時間を節約できます。再プログラムされる関数のアドレスが変更される可能性があるため、これらの変更された関数が別のパーティション (メモリのセクション) にある関数によって呼び出されると、問題が発生します。この記事では、固定アドレスにあり、更新された関数のアドレスを含むジャンプ/間接テーブルを使用して、このアプローチの解決策を提案しています。

それでは、質問の部分に行きましょう:

私はこの問題をAutosarアーキテクチャからではなく、組み込みエンジニアの観点から考えていました。このアプローチは機能しますが、スループットの向上につながると考えました。私が使用できると思った別のオプションは、おそらく関数ポインターです。しかし、通常のシナリオでは、関数シンボル名を実際のアドレスに置き換えるのはリンカであると考えたため、関数 A (変更されていないパーティションにある) が関数 B (更新されたパーティションにある) に初期化され、おそらく別のアドレスにあります)は機能しません。

これは最終的に私の最後の質問に私をもたらします:

  1. 関数ポインターのアプローチは機能しますか? (多分無いと思います。)
  2. 上記の質問に対する答えが「いいえ」の場合、すべての関数ポインターを固定アドレスに保持し、スクリプトとマップ ファイルを使用して実際のアドレスにパッチを適用するなど、関数ポインター アプローチを使用できますか。

こんなに長い質問に辛抱強く答えてくれた皆さんに感謝します。もっと小さな質問を思いつくことができればいいのにと思います。

4

1 に答える 1

1

関数へのポインターは機能すると思いますが、実際にはジャンプ テーブルと変わりません。最終関数のアドレスを見つける固定アドレスにテーブルが必要です。関数へのポインターを初期化する必要があります。リンカーはそのためには役に立ちません。唯一の利点は実行時です。関数は直接呼び出され、間接的なジャンプからではありません。

次のコードでは、コンポーネントが固定アドレス 0xf800 にあり、このコンポーネントの関数のアドレスがこのメモリの先頭に格納されていると想定しています。

// Functions addresses table at 0xf800
// 0xf800 stores the @ of func1 of the component
// 0xf804 @func2
// 0xf808 @func3
// etc.

// Initialization of the pointers to function
// Here each function has a int as parameter and returns an int 
int (*func1)(int) = *((int(**)(int))(0xf800));
int (*func2)(int) = *((int(**)(int))(0xf804));
int (*func3)(int) = *((int(**)(int))(0xf808));

// Use of a pointer to call a function of the component
int result = func1(1234);
于 2015-07-13T07:56:57.073 に答える