如何将bitfield(通过引用)传递给函数? [英] How to pass a bitfield (by reference) to a function?

查看:240
本文介绍了如何将bitfield(通过引用)传递给函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是如何通过引用函数传递一个位域实例。我已经执行了如下所示,但是当我启用DAC_set_gain_code的功能时,处理器会引发中断故障。我正在做的正确,只要通过bitfield去吗?



我已经创建了一个位域(见下文),它代表DAC芯片上的一个24位寄存器,我想要写入并生活在.h文件中。

  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; //创建bitfield的实例

//其他代码在这里...

DAC_set_gain_code(channel_u8,gain_code_i8,& GAIN_x); //通过bitfield的地址

return;
}

实际填充位域的函数如下所示:

  void DAC_set_gain_code(uint8_t channel_u8,int8_t gain_code_i8,GAIN_REG_st * GAIN)
{
/ *填充ZERO_REG_st位字段* /
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); 

任何建议赞赏。



谢谢。

解决方案

由于这个代码的真实使用是写入硬件注册表,像填充以及字段的对齐/排序 DOES



我怀疑编译器正在使用32位int,而这个结构被填充到32位,但在实际的代码中被调试GAIN_X不是本地的var,你正在通过0xNNNNNNNN(或等效的) - 并且地址不在右边界(非常可能,因为它是一个24位寄存器)。编译器会假设你传递一个指向一个真正的GAIN_REG_st的指针,而不是一个打字类型的地址,所以可能已经做出了一致的假设。



直接访问硬件从C / C ++开始,您需要知道编译器如何处理这样的东西,并确保您仔细向编译器说谎。


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.

解决方案

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.

这篇关于如何将bitfield(通过引用)传递给函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆