如何将bitfield(通过引用)传递给函数? [英] How to pass a bitfield (by reference) to a function?
问题描述
我已经创建了一个位域(见下文),它代表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屋!