26

シリアル経由で受信する命令、コマンドを保存する必要があります。コマンドの長さは 8 ビットです。

コマンド名とその値の間の透明性を維持する必要があります。シリアルで受信した 8 ビットの数値を任意の型に変換する必要がないようにします。

コードでそれらを処理するために列挙型を使用したいと思います。このプラットフォームでは、列挙のみが 16 ビット整数に対応します。

プラットフォームは、Butterfly デモ ボード上の AVR ATmega169V マイクロコントローラーです。これは、16 ビット操作のサポートが一部制限された 8 ビット システムです。これは高速なシステムではなく、約 1KB の RAM を備えています。ファイル I/O やオペレーティング システムなどの贅沢はありません。

8ビットコマンドを保存するためにどのタイプを使用する必要があるかについての提案はありますか?
#defines の大量のヘッダーよりも優れたものがあるに違いありません。

4

6 に答える 6

41

gcc-fshort-enums役に立つかもしれません:

可能な値の宣言された範囲に必要な数のバイトだけを「enum」型に割り当てます。具体的には、「enum」型は、十分な余裕がある最小の整数型と同等になります。

実際、ここには関連情報がたくさんあるページがあります。存在を知らなかった多くの GCC スイッチに出くわすことを願っています。;)

于 2009-11-09T06:54:08.257 に答える
8

存在しない問題を解決しようとしています。

あなたの質問は C とタグ付けされています。C 言語では、値コンテキストの列挙型は整数型と完全に互換性があり、他の整数型と同じように動作します。式で使用すると、他の整数型とまったく同じ整数昇格の対象となります。それを考慮に入れると、列挙定数によって記述された値を 8 ビット整数型に格納する場合は、適切な汎用 8 ビット整数型 (たとえばint8_t) を選択して使用するだけでよいことに気付くはずです。列挙型の代わりにそれ。int8_t(列挙型で明示的に宣言されたオブジェクトとは対照的に)型のオブジェクトに列挙定数値を格納することによって、まったく何も失うことはありません。

あなたが説明する問題は、列挙型が他の整数型からはるかに離れている C++ に存在します。C++ では、メモリを節約する目的で列挙型の代わりに整数型を使用することはより困難です (可能ではありますが)。ただし、追加の作業がまったく必要ない C では違います。

于 2010-02-27T07:57:46.163 に答える
3

列挙型が機能しない理由がわかりません。列挙型との比較および列挙型からの代入は、すべてデフォルトの拡大で正常に機能するはずです。8ビット値が正しく署名されていることに注意してください(署名なしの拡張が必要だと思います)。

この方法で 16 ビットの比較が得られますが、これがパフォーマンスの問題にならないことを願っています (特に、プロセッサが 16 ビットのように聞こえる場合はそうであってはなりません)。

于 2009-11-09T06:43:21.020 に答える
2

Microsoft の C コンパイラを使用すると、次のようなことができますが、これは拡張機能です (C++0x では標準です)。

enum Foo : unsigned char {
    blah = 0,
    blargh = 1
};

GCCにタグを付けたので、同じことが可能かどうかは完全にはわかりませんが、GCCにはgnu99モードまたはそのための拡張機能がある可能性があります。やってみて。

于 2009-11-09T06:45:51.297 に答える
0

ARC コンパイラに関連する回答 (DesignWare MetaWare C/C++ Programmer's Guide for ARC から引用; セクション 11.2.9.2)

列挙型のサイズ 列挙型のサイズは、トグル *Long_enums* のステータスによって異なります。

■ トグル *Long_enums* がオフの場合、すべての値を表現できるように、列挙型は 1、2、または 4 バイトの最小値にマップされます。

■ トグル *Long_enums* がオンの場合、列挙型は 4 バイトにマップされます (AT&T Portable C Compiler の規則に一致します)。

于 2014-03-05T11:57:47.643 に答える
0

次の理由から、いずれにしても enum のままにすることをお勧めします。

  • このソリューションを使用すると、コマンド値をシリアル プロトコルが期待する値に直接マップできます。
  • 実際に 16 ビット アーキテクチャを使用している場合、8 ビット タイプに移行する利点はそれほど多くありません。メモリ バイトが 1 バイト節約される以外の側面について考えてみましょう。
  • 一部のコンパイラでは、実際の列挙型サイズを使用して最小限のビット数を使用しました (バイトに収まる列挙型はバイトのみを使用し、次に 16 ビット、次に 32 ビットを使用しました)。

まず、実際のタイプの幅を気にする必要はありません。本当に効果的な保存方法が必要な場合にのみ、GNU コンパイラで -fshort-enums などのコンパイラ フラグを使用する必要がありますが、本当に必要でない限りお勧めしません。

最後のオプションとして、「enum」をコマンドのプレゼンテーション データとして定義し、2 つの簡単な操作でバイトへの変換を使用して、コマンド値をメモリに保存/メモリから復元する (そしてこれを 1 か所にカプセル化する) ことができます。これはどうですか?これらは非常に単純な操作であるため、インライン化することもできます (ただし、これにより、実際にはストレージに 1 バイトしか使用できず、反対側から、好きなように定義された最も使用可能な列挙型を使用して操作を実行できます。

于 2009-11-09T07:00:41.693 に答える