How to pass a bitfield (by reference) to a function?

扶醉桌前 提交于 2019-12-23 02:45:38

问题


My question is how to pass a bitfield instance by reference to a function. I have performed this as shown below, but when i eneter the function DAC_set_gain_code, the processor throws an interupt fault. Is what i am doing correct as far as passing the bitfield goes?

I have created a bitfield (see below) which represents a 24bit register on an DAC chip, which i want to write into and lives in the .h file.

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;

I have a function which initialises the bitfield like so:

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;
 }

The function which actually populates the bitfield is shown below:

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;
}

The function prototype for hal_DAC_set_gain_code_uni is:

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

Any advise appreciated.

Thanks.


回答1:


Since the real usage of this code is to write to a hardware register, issues like padding and alignment/ordering of fields DOES matter.

I suspect the compiler is using 32-bit ints, and this structure is getting padded to 32-bits, but in the actual code being debugged GAIN_X isn't a local var, you're passing 0xNNNNNNN (or equivalent) - and the address isn't on the "right" boundary (quite possible as it's a 24-bit register). The compiler will assume you're passing a pointer to a real GAIN_REG_st, not a type-punned address, and so may have made assumptions about alignment.

To access hardware directly from C/C++, you need to know how the compiler handles stuff like this, and make sure you lie to the compiler carefully.




回答2:


Could it be some alignment problem?

Maybe you can play with your compiler's alignment options? Or try stuffing your structure with a dummy uint8 at the end?



来源:https://stackoverflow.com/questions/5675299/how-to-pass-a-bitfield-by-reference-to-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!