2011-12-15 34 views
5

私はARM cortex M3の内部フラッシュに保存したいコンフィギュレーション構造を持っています。 仕様によると、内部フラッシュのデータ保存は32ビットに合わせる必要があります。 私はたくさんの論理値と構造体の文字を持っているので、私は8ビットを格納するために32ビットを使用したくありません... __packedプリプロセッサプラグマを使用して構造体をパックすることにしました。構造体のサイズが4(4バイト= 32ビット)で割り切れることを確認する必要があります。必要に応じてパディングバイトを追加することでそれを行います。 現在、開発中に構造を大きく変更し、32ビットに整列させるために、常にパディングバイトを変更する必要があります。 現在、構造がこの内部フラッシュメモリ内のC構造のアライメント

typedef __packed struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...] // this has to be changed every time I alter the structure. 
} CONFIG; 

をslike見て、私がやっているものを達成するためのより良い方法はありますか? 私は組み込みプログラミングではかなり新しいので、間違いをしないようにしたいと思います。

編集:ご注意ください。データは、内蔵フラッシュの終わりに固執し、その動作しませんパディング...

+1

私はあなたの理解が正しくないと信じていました。フラッシュメモリ内の命令は、整列されなければならず、コンパイラによって保証される。しかし、フラッシュに格納されたデータは、アライメントされていなくても、アーム・コルテックスm3コアで管理することができます。どの会社のMCUを使用していますか? –

答えて

4

を省略すると、おそらくこれはアイデアです:

typedef __packed struct { 
    uint8_t status; 
    uint16_t delay; 
    uint32_t blabla; 
    uint8_t foo[5]; 
} CONFIG; 

typedef __packed struct { 
    CONFIG cfg; 
    uint8_t padding[4 - (sizeof(CONFIG) % 4)] 
} CONFIGWRAPPER; 
+0

実際に私がそれを考えるとき。すでに整列している場合は、何もないのに4バイトを追加します。 – stdcall

4

解決策1:あなたは労働組合の内部でそれを置くことができ

union 
{ 
    CONFIG config; 
    uint8_t total_size[32]; 
} my_union; 
+0

これは面白いことですが、sizeof(CONFIG)がtotal_sizeのサイズより小さいとしましょう。私はユニオンに設定を設定します。 sizeof(my_union)は何になりますか? – stdcall

+0

'CONFIG'が' total_size'より小さい場合、 'sizeof(my_union)'は 'total_size'のサイズになります。具体的には、32. – Lindydancer

1

解決方法2:あなたの構造と文字の配列を含むあなたはフラッシュの終わりから32のように、特定の場所に設定データを配置するためにIAR固有の機能#pragma locationを使用することができます。あなたはどのような方法でパッドに構造を必要としないその方法:あなたが彼らの自然な境界にアラインされていないデータで終わる場合

まず
/* Fictitious end of flash location. */ 
#pragma location=0x1234FFE0 
struct [... your struct goes here ...] 
3

、パックアライメントが通常であるが、避けなければならない、いくつかのCPUだけで発行されますあなたがそれらにアクセスしようとするときにトラップします。

最初に、コンパイラがアライメントのためのギャップを追加しないように、メンバを順序で格納します(または、そうであれば、最後に追加します)。可能であれば、1.メンバーにあなたが望むアラインメント要件を持たせるようにしてください。そうすれば、コンパイラーは少なくとも構造体に多くのアライメントを与えることができます。

これには、使用しているプラ​​ットフォームとコンパイラのアライメント要件に関する知識が必要です。そして、この構造体は、この場合には(4バイトaligmentを必要とするコンパイラに伝えるパディング配列を取り除く、と

typedef struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...]; 
} CONFIG; 

typedef struct 
{ 
uint32_t blabla; 
uint16_t delay; 
uint8_t status; 
uint8_t foo[5]; 
} CONFIG; 

を変更することおそらくすでに意志最初のメンバーは、4バイトを持っているとして、またはより多くの整列要件)。例えばgccの使用attribute((__aligned__(4))

次に、sizeof()とalignof()を構造体に使用する小さなプログラムである整列要件を検証する小さなテストプログラムを作成します。構造体を整列させるための命令を追加する必要があります。そのプログラムをビルド/パッケージ化の一部として実行します。

+0

優れた答えです。コンパイルドメイン全体で構造体を使って何をしようとしているのか(ハードウェアをコンパイルドメインと見なすことを検討する場合)、サンプルテストプログラムは成功または失敗にとって重要です。 –

関連する問題