組み込み機器・ハードウェアの設計開発から装置製作まで社内一貫対応!

組み込み機器・ハードウェア設計製作.com
組み込み機器・ハードウェア設計製作.com

produced by株式会社アイディアイ

設計のポイント

構造体の宣言にpackedを指定する

設計内容分類組み込みソフトウェアにおけるC言語記述

実現したい仕様・課題

構造体を通信フレームや外部保存データ、メモリマップされたデバイスのレイアウト定義として使う場合、コンパイラがアラインメント(整列)のためにパディングバイトを自動挿入し、構造体のサイズがメンバ変数の合計サイズと一致しないことがあります。パディングの入り方は処理系依存のため、通信相手や保存フォーマットとバイト位置がずれ、データ化けや互換性問題の原因になります。構造体のメモリレイアウトを意図どおりに制御したいというのが課題です。

設計のポイント

構造体の宣言時に __packed や __attribute__((__packed__)) を指定することで、パディングバイトの挿入を抑制し、構造体サイズをメンバ変数の合計サイズに一致させることができます(指定方法はコンパイラによって異なります)。たとえば char a; int b; を持つ構造体は、通常はaの後に3バイトのパディングが入り8バイトになりますが、packed指定により5バイトちょうどになります。通信フレームの構造体定義や、外部メモリに保存するデータレイアウトなど、バイト配置が仕様で決まっている用途で有効です。一方で注意点もあります。packedにするとメンバが非整列アドレスに配置されるため、CPUによってはアクセスが遅くなり、非整列アクセスを許さないCPUではフォルト(例外)の原因になり得ます。したがってpacked構造体は「外部とのレイアウト互換が必要な境界部分」に限定し、内部処理では通常の構造体へコピーして扱う構成が安全です。また、そもそもメンバをサイズの大きい型から順に並べることでパディング自体を減らす設計も有効です。sizeofで意図どおりのサイズになっているかをコード上で検証しておくと、コンパイラ変更時の差異も早期に検出できます。なお、packedはバイト順(エンディアン)までは制御しない点にも注意が必要です。

【コード例】

// 通常宣言:パディングが入りsizeofは8になることが多い
typedef struct {
  char a;      // +0
  int  b;      // +4(+1〜+3はパディング)
} st_data;

// packed指定:sizeofは5(GCC系の例)
typedef struct __attribute__((__packed__)) {
  char a;      // +0
  int  b;      // +1〜+4
} st_data_packed;

補足情報

当事例のような、マイコンのファームウェアにおけるC言語記述のポイントをまとめた冊子の無料DLが可能です。
是非以下よりご確認ください。

マイコンのファームウェア C言語記述のポイント

>>ダウンロードはこちら!

お問い合わせ

組み込み機器・ハードウェア 設計製作.comを運営する株式会社アイディアイは、組み込み機器・ハードウェアの設計開発代行サービスを提供しています。
試験装置や制御機器、組み込みボードなど、設計・開発委託先をお探しの皆様、お気軽に当社に御相談ください。

技術資料のダウンロードはこちらから 技術資料ダウンロ―ド メールフォームでのお問い合わせはこちらから ご相談・お問合せ