工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial Internet of Things >> 埋め込み

組み込みC言語の共用体解説:効率的なメモリ共有とメッセージング

組み込みC言語における共用体の理解

組み込みシステムにおいて、共用体は異なるデータ型を同じメモリ位置に格納できる強力なデータ構造です。この記事では共用体の基礎を解説し、実践的な例を示し、メモリ制約と帯域幅に敏感なアプリケーションでなぜ定番ツールなのかを説明します。

組み込みCにおける構造体と共用体の違い

以前、構造体について説明しました:異種の変数を単一のエンティティにグループ化する方法です。C言語では、共用体も異なる型をグループ化する補完的な構成要素ですが、重要な違いは各メンバが同じメモリアドレスを共有することです。

導入例

共用体の宣言は構造体とほぼ同じで、structをunionに置き換えるだけです:

union test { uint8_t c; uint32_t i; };

このテンプレートは2つのメンバを定義します:cは1バイト、iは4バイトを占有します。この型の変数を作成するには:

union test u1;

メンバへのアクセスにはドット演算子を使用します:

u1.i = 10; m = u1.c; // mはuint8_tでなければならない

共用体のストレージサイズは最大メンバのサイズと等しいため、u1は4バイトを占有します。iへの書き込みはcが使用する同じメモリを上書きするため、2つのメンバは相互排他的です。

共有メモリ空間は必要か?

2台の組み込みデバイスデバイスAとデバイスBがステータス、速度、位置データを交換するシナリオを想像してください(図1参照)。データ項目とサイズは以下の通り:

組み込みC言語の共用体解説:効率的なメモリ共有とメッセージング

図1
変数 サイズ(バイト) 意味
power 1 バッテリー充電
op_mode 1 動作モード
temp 1 周囲温度
x_pos 2 X座標
y_pos 2 Y座標
vel 2 速度

デバイスBがすべての情報を必要とする場合、単純な構造体では9バイト必要で、各通信ラウンドで9バイトフレームを転送します(図2参照)。しかし現実的な多くのシナリオでは、3つのメッセージタイプは相互排他的です:時にはステータスのみ、時には位置のみ、時には速度のみ。その場合、最大ペイロードは4バイト(位置メッセージ)です。4バイトバッファを共有する共用体なら、3つのメッセージのいずれかを保持でき、フレームサイズを9バイトから4バイトに削減できます(図3参照)。

組み込みC言語の共用体解説:効率的なメモリ共有とメッセージング

図2

組み込みC言語の共用体解説:効率的なメモリ共有とメッセージング

図3

メッセージパケットへの共用体の利用

以下ではステータス用と位置用の2つの構造体を作成し、速度フィールドとともに共用体に埋め込みます:

struct status_s { uint8_t power; uint8_t op_mode; uint8_t temp; }; struct position_s { uint16_t x_pos; uint16_t y_pos; }; union msg_union { struct status_s status; struct position_s position; uint16_t vel; };

共用体のサイズは4バイト(position_sのサイズ)で、3つのメッセージタイプすべてで共有されます。

共用体のアクティブメンバを追跡する方法

受信側が共用体を読み取る際、どのメンバが有効かを知る必要があります。一般的なパターンはタグ付き共用体:アクティブなメンバを記録する別フィールドを設けることです。共用体の前に1バイトのmsg_typeを追加できます:

struct message_s { uint8_t msg_type; // 's' = ステータス, 'p' = 位置, 'v' = 速度 union { struct status_s status; struct position_s position; uint16_t vel; } msg; };

msg_typeバイトを共用体とともに送信することで、受信側はペイロードの形状を事前に知らなくても正しく解釈できます。

代替案:動的メモリ割り当て

別のアプローチは、各メッセージタイプごとにメモリを動的に割り当てることです。送信側はmsg_typeを設定し、そのペイロードに必要なバイト数だけ割り当てます。受信側はmsg_typeに基づいて着信データを解釈し、終了時にメモリを解放します。これはわずかにメモリ効率が良いかもしれませんが、動的割り当ては実行時オーバーヘッドと明示的な解放の必要性を導入するため、多くの組み込み開発者は静的共用体戦略を好みます。

次回:共用体の応用

共用体は、より大きなワードから小さなデータ片を抽出するためにも頻繁に使用されます。これは通信プロトコルやハードウェアレジスタの解析で特に価値があります。次回の記事ではそれらのユースケースに深く潜ります。

組み込みCに関する記事をさらに探すには、記事インデックスをご覧ください。

埋め込み

  1. クラウド×IoTの力を解き放つ:シームレスな接続とデータインサイトの実現
  2. ロボットプログラミングの理解:3つの主要手法を解説
  3. マイクロプロセッサプログラミングの基礎
  4. 2021年 必ず学ぶべき9つのプログラミング言語:Go、Rust、Kotlinなど注目言語を解説
  5. コンプレッサー単位のマスター:一般的な測定用語の明確なガイド
  6. 組み込みシステムプログラミング:言語、アーキテクチャ、応用
  7. 産業用IoTソリューションに最適なプログラミング言語の選び方
  8. 「信頼性のインターネット」におけるデータ活用:効果的管理のための戦略
  9. IoTの民主化:次世代衛星IoTがもたらす普遍的で手頃な接続性
  10. データセンターの未来:トレンド、技術、持続可能性
  11. C言語共用体:複数データ型の効率的なメモリ管理