英文:
Do I need to handle endianess over an 8 bits bit-fields struct on a 32 bit architecture?
问题
我正在进行一些嵌入式软件开发,针对32位架构(精确地说是AVR32)。
在这个软件中,我从通过I2C连接的外部外设中检索一个以一个字节编码的标志。
这个字节的每个位都是一个布尔变量。
结构如下:
typedef union __attribute__((packed)){
struct __attribute__((packed)) {
uint8_t flag_a : 1;
uint8_t flag_b : 1;
uint8_t flag_c : 1;
uint8_t flag_d : 1;
uint8_t flag_e : 1;
uint8_t __unused : 3;
}
uint8_t raw;
}Flag_t;
我的问题是,如果我想要使这段代码可移植,是否需要为另一种字节序重新定义联合内部的结构?
或者,这种情况下是否不存在字节序问题?
英文:
I am doing some embedded software on a 32 bits architecture (precisely AVR32).
On this software I am retrieving a flag, coded on one byte, from an external peripheral connected via I2C.
Each bits of this byte are a boolean variable.
The struct is the following:
typedef union __attribute__((packed)){
struct __attribute__((packed)) {
uint8_t flag_a : 1;
uint8_t flag_b : 1;
uint8_t flag_c : 1;
uint8_t flag_d : 1;
uint8_t flag_e : 1;
uint8_t __unused : 3;
}
uint8_t raw;
}Flag_t;
My question is, if I want to make this code portable, do I need to redefine the struct inside the union in the reverse order for the other endianness ?
Or, is the endianness issues not present in this situation ?
答案1
得分: 3
大小端只对多字节变量有影响,所以在您的情况下不是问题。
然而,位域的使用可能会影响可移植性。C标准将其实现方式留给了编译器实现来决定。因此,不能期望它们在不同环境中表现相同。
一个更好的选择是简单地使用一个字节并定义不同位的含义。例如:
typedef uint8_t Flag_t;
typedef enum
{
flag_a = 1u << 0,
flag_b = 1u << 1,
flag_c = 1u << 2,
flag_d = 1u << 3,
flag_e = 1u << 4,
} Flag_Bits_t;
英文:
Endianness is only an issue for multi-byte variables, so it is not an issue in your case.
However, the use of bit-fields is potentially an issue for portability. The C Standard leaves it up to the compiler implementation to decide how they are implemented. Thus they cannot be expected to behave identically across different environments.
A better option is simply to use a single byte and define the meaning of the different bits. E.g.:
typedef uint8_t Flag_t;
typedef enum
{
flag_a = 1u << 0,
flag_b = 1u << 1,
flag_c = 1u << 2,
flag d = 1u << 3,
flag e = 1u << 4,
} Flag_Bits_t;
答案2
得分: 3
Then do not use bit-fields. Use bit operations.
Yes, but this is compiler specific, i.e. not portable. On gcc you can use https://stackoverflow.com/questions/47600584/bitfield-endianness-in-gcc .
Yes, but not only - compiler may insert any padding between structure members, uint8_t
may not be supported for a bitfield, and it is "endianness" of bits within a byte that compiler chooses to make.
英文:
> if I want to make this code portable
Then do not use bit-fields. Use bit operations.
> in the reverse order for the other endianness ?
Yes, but this is compiler specific, i.e. not portable. On gcc you can use https://stackoverflow.com/questions/47600584/bitfield-endianness-in-gcc .
> is the endianness issues not present in this situation ?
Yes, but not only - compiler may insert any padding between structure members, uint8_t
may not be supported for a bitfield, and it is "endianness" of bits within a byte that compiler chooses to make.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论