1

私の質問は、関数への参照によってビットフィールド インスタンスを渡す方法です。以下に示すようにこれを実行しましたが、関数 DAC_set_gain_code を入力すると、プロセッサは割り込みエラーをスローします。ビットフィールドを渡す限り、私がしていることは正しいですか?

DAC チップ上の 24 ビット レジスタを表すビットフィールド (以下を参照) を作成しました。

typedef struct {
    uint8_t rdwr_u8:        1;
    uint8_t not_used_u8:    3;
    uint8_t address_u8:     4;
    uint8_t reserved_u8:    8;
    uint8_t data_u8:        8;
}GAIN_REG_st;

次のようにビットフィールドを初期化する関数があります。

void init(void)
{
    GAIN_REG_st GAIN_x;  //Create instance of bitfield

    //other code here...

    DAC_set_gain_code(channel_u8, gain_code_i8, &GAIN_x);   //Pass address of bitfield

    return;
 }

実際にビットフィールドに入力する関数を以下に示します。

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN)
{
    /* Populate ZERO_REG_st bitfield */
    GAIN->rdwr_u8       = 0;
    GAIN->not_used_u8 = 0;

    if(channel_u8==0){
        GAIN->address_u8 = GAIN_REGISTER_0;
    }
    else if(channel_u8==1){
        GAIN->address_u8 = GAIN_REGISTER_1;
    }
    else if(channel_u8==2){
        GAIN->address_u8 = GAIN_REGISTER_2;
    }
    else if(channel_u8==3){
        GAIN->address_u8 = GAIN_REGISTER_3;
    }

    GAIN->data_u8 = gain_code_i8;

    return;
}

hal_DAC_set_gain_code_uni の関数プロトタイプは次のとおりです。

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN);

アドバイスをいただければ幸いです。

ありがとう。

4

2 に答える 2

3

このコードの実際の使用法はハードウェア レジスタへの書き込みであるため、フィールドのパディングやアラインメント/順序付けなどの問題は重要です。

コンパイラは 32 ビットの int を使用しており、この構造体は 32 ビットにパディングされていると思われますが、実際にデバッグされているコードでは GAIN_X はローカル変数ではなく、0xNNNNNNN (または同等のもの) を渡しています - そしてアドレス「右」境界上にありません (24 ビット レジスタであるため、可能性は十分にあります)。コンパイラーは、タイプがパニングされたアドレスではなく、実際の G​​AIN_REG_st へのポインターを渡していると想定するため、アラインメントについて想定している可能性があります。

C/C++ からハードウェアに直接アクセスするには、コンパイラがこのような処理をどのように処理するかを理解し、コンパイラに注意して嘘をつくようにする必要があります。

于 2011-04-25T19:01:16.023 に答える
0

アライメントの問題でしょうか?

コンパイラのアラインメント オプションをいじってみてはいかがでしょうか。uint8それとも、構造体の最後にダミーを詰め込んでみますか?

于 2011-04-15T12:06:33.603 に答える