如何将位域(通过引用)传递给函数?
我的问题是如何通过引用函数来传递位字段实例。我已经执行了如下所示的操作,但是当我进入函数 DAC_set_gain_code 时,处理器会抛出中断故障。就传递位域而言,我所做的是否正确?
我创建了一个位字段(见下文),它代表 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; //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);
感谢任何建议。
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于此代码的真正用途是写入硬件寄存器,因此字段的填充和对齐/排序等问题确实很重要。
我怀疑编译器正在使用 32 位整数,并且该结构正在填充为 32 位,但在实际调试的代码中 GAIN_X 不是本地变量,您传递的是 0xNNNNNNN (或等效值) - 以及地址不在“右”边界上(很有可能,因为它是一个 24 位寄存器)。编译器会假设您传递的是指向真实 GAIN_REG_st 的指针,而不是类型双关地址,因此可能对对齐做出了假设。
要直接从 C/C++ 访问硬件,您需要知道编译器如何处理此类内容,并确保小心地对编译器撒谎。
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.
会不会是一些对齐问题?
也许您可以使用编译器的对齐选项?
或者尝试在最后用一个虚拟的
uint8
填充你的结构?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?