3

私は 16 ビット PIC 用のファームウェアに取り組んでおり、C (Microchip C30 コンパイラ) で書いています。デバイスが外部デバイスから長いバイト リストを受信し、それらのバイトを構造体にコピーしようとしています。構造は次のように定義されます。

typedef struct __attribute__((__packed__)) {
    char    F1Nickname[17];
    char    F2Nickname[17];
    DWORD   F1CurrentPos;
    DWORD   F2CurrentPos;
    WORD    F1CurrentTemp;
    WORD    F2CurrentTemp;
    DWORD   F1MaxPos;
    DWORD   F2MaxPos;
    BYTE    F1TempCompOn;
    BYTE    F2TempCompOn;
    BYTE    CheckSum;
} deviceStatus;

構造内の合計バイト数が奇数になると、プログラムがフリーズして AddressError サービス ルーチンに引っかかるという奇妙な問題がありました。構造体に余分なバイトを追加するだけで問題を解決できますが、それは応急処置のようです。

コンパイラが変数の間にフィラー バイトを挿入しないようにしたかったので、packed 属性を構造体に配置しました。その場合、受信した文字配列からコピーすると、構造体の値が正しくなくなります。

また、aligned という属性があることも知っています。整列は構造体の先頭を偶数バイトに整列させるだけですか、それとも構造体のすべての項目を偶数バイトに整列させますか? ここで、aligned 属性が必要だと思いますか? この構造体にaligned属性を追加する場合、データを送信しているデバイスの構造体にも追加する必要がありますよね? 現時点では、どちらも上記とまったく同じ方法で定義されています。

整列された属性を追加する場合、packed 属性を削除する必要がありますか? 彼らは基本的に反対のことをしていませんか?

4

2 に答える 2

2

__attribute__とは C 標準の__packed__一部ではなく、コンパイラが提供する拡張機能です。それらが何を意味するのかを確実に知る唯一の方法は、コンパイラのドキュメントで調べることです。

于 2011-08-11T12:55:15.927 に答える
2

特定のマイクロプロセッサ アーキテクチャは、ワード境界にアラインされたアドレスでのみデータ フェッチを実行でき、ワード アラインされていない場合は例外をスローします。多くの場合、コンパイラは必要なアクロバットを実行してフェッチをワード アラインメントするコードを生成しますが、これはコンパイラには当てはまらないようで、例外が発生するのはそのためです。

あなたの場合、structデータをシリアル化するために a を使用しているため、パックする必要があります。この場合、struct単語の境界を越えて読み取りが行われないように再配置するか、構造体を使用して展開し、データを手動でシリアル化する必要があります。

于 2011-08-11T13:12:07.777 に答える