我尝试将结构转换为 EPS32 上的字节流。 在我的结构/联合下面。
#include <Arduino.h>
typedef struct {
uint16_t header;
float pi;
uint16_t crc;
} BlackBoxStruct;
typedef union {
BlackBoxStruct data;
uint8_t bytes [sizeof(BlackBoxStruct)];
} BBD;
BBD bbd;
uint8_t size, size2, size3;
char buf[100];
void setup() {
Serial.begin(115200);
bbd.data.header=0xFEEF;
bbd.data.pi = 1.234;
bbd.data.crc=0x1122;
size = sizeof(BlackBoxStruct);
size2 = sizeof(bbd);
size3 = sizeof(BBD);
sprintf(buf, "\n\nArraySize: %d, StructSize: %d, BBD: %d", size, size2, size3);
Serial.println(buf);
for (uint8_t i=0; i < size; i++) {
sprintf(buf, "byte %03d is %02x", i, bbd.bytes[i]);
Serial.println(buf);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
我仍然想知道
for-loop
产生的输出
ArraySize: 12, StructSize: 12, BBD: 12
byte 000 is ef <= header uint16_t 2 Bytes little endian 0xFEEF
byte 001 is fe
byte 002 is 00 <== ??? - seems to be a uint16_t or 2 uint8_t
byte 003 is 00
byte 004 is b6 <== float 4 bytes
byte 005 is f3
byte 006 is 9d
byte 007 is 3f
byte 008 is 22 <== CRC, uint16_t little endian 0x1122
byte 009 is 11
byte 010 is 00 <== ??? 2 bytes
byte 011 is 00
我无法解释这4个字节标记为???
有什么想法吗?
我期望数组的大小为 8 字节,其他 4 字节 - 我不知道。
这种行为更加令人困惑。 我更改了结构并包含两个数组。
typedef struct {
uint16_t header;
long ldata[2];
float pid[2];
uint16_t crc;
} BlackBoxStruct;
和输出
ArraySize: 24, StructSize: 24, BBD: 24
byte 000 is ef
byte 001 is fe
byte 002 is 00 <== long are 4 bytes - 1. LONG
byte 003 is 00
byte 004 is 44
byte 005 is 33 <== 0x3344
byte 006 is 00 <== long are 4 bytes - 2. LONG
byte 007 is 00
byte 008 is cd
byte 009 is ab <== 0xabcd
byte 010 is 00 <== ???
byte 011 is 00 <== ???
byte 012 is b6 <== 1. float
byte 013 is f3
byte 014 is 9d
byte 015 is 3f
byte 016 is 1b <== 2. float
byte 017 is 2f
byte 018 is 5d
byte 019 is 40
byte 020 is 22 <== crc 0x1122
byte 021 is 11
byte 022 is 00 <== ???
byte 023 is 00 <== ???
我期望数组的大小为 8 字节,其他 4 字节 - 我不知道。
ESP32 作为 32 位 MCU,具有 4 的数据结构对齐,编译器这样做是出于性能原因以及数据对齐目的(请参阅下面的链接以进一步阅读)。因此,即使您根据数据类型添加结构体中的所有元素,也支持 8 个字节,但向两个
uint16_t
元素添加了填充,使其长度为 4 字节,以便与 4- 内联字节float
。可以通过以下简单示例观察到这一点。
这将生成如下输出:
The size of uint16_t head 2 bytes
The size of float f 4 bytes
The size of uint16_t tail 2 bytes
The size of Foo 12
byte 0=34 // uint16_t 0x1234 stored in little endian
byte 1=12
byte 2=00 // padding for 0x1234
byte 3=00 // padding for 0x1234
byte 4=00 // float 1000.0 stored accoding to IEEE754 as 0x447a00000
byte 5=00
byte 6=7a
byte 7=44
byte 8=78 // uint16_t 0x5678 in little endian
byte 9=56
byte 10=00 // padding
byte 11=00 // padding
现在将数据结构更改为以下内容,看看你会得到什么?
typedef struct{
uint16_t head1{0x1234};
uint16_t head2{0x5678};
float f{1000.0};
uint16_t tail{0x9abc};
} Foo_t;
或
typedef struct{
uint8_t head1{0x12};
uint16_t head2{0x5678};
float f{1000.0};
uint16_t tail{0x9abc};
} Foo_t;
进一步阅读
我期望数组的大小为 8 字节,其他 4 字节 - 我不知道。
ESP32 作为 32 位 MCU,具有 4 的数据结构对齐,编译器这样做是出于性能原因以及数据对齐目的(请参阅下面的链接以进一步阅读)。因此,即使您根据数据类型添加结构体中的所有元素,也支持 8 个字节,但向两个
uint16_t
元素添加了填充,使其长度为 4 字节,以便与 4- 内联字节float
。可以通过以下简单示例观察到这一点。
#include <Arduino.h>
typedef struct{
uint16_t head{0x1234};
float f{1000.0};
uint16_t tail{0x5678};
} Foo_t;
Foo_t foo;
void setup() {
Serial.begin(115200);
// since you are using an esp32, so Serial.printf() is available
Serial.printf("The size of uint16_t head %d bytes\n", sizeof(foo.head));
Serial.printf("The size of float f %d bytes\n", sizeof(foo.f));
Serial.printf("The size of uint16_t tail %d bytes\n", sizeof(foo.tail));
Serial.printf("The size of Foo %d\n", sizeof(foo));
uint8_t *ptr = (uint8_t*) &foo;
for(int i=0; i<sizeof(foo); i++) {
Serial.printf("byte %d=%02x\n", i, *ptr++);
}
}
void loop() {
}
这将生成如下输出:
The size of uint16_t head 2 bytes
The size of float f 4 bytes
The size of uint16_t tail 2 bytes
The size of Foo 12
byte 0=34 // uint16_t 0x1234 stored in little endian
byte 1=12
byte 2=00 // padding for 0x1234
byte 3=00 // padding for 0x1234
byte 4=00 // float 1000.0 stored accoding to IEEE754 as 0x447a00000
byte 5=00
byte 6=7a
byte 7=44
byte 8=78 // uint16_t 0x5678 in little endian
byte 9=56
byte 10=00 // padding
byte 11=00 // padding
现在将数据结构更改为以下内容,看看你会得到什么?
typedef struct{
uint16_t head1{0x1234};
uint16_t head2{0x5678};
float f{1000.0};
uint16_t tail{0x9abc};
} Foo_t;
或
typedef struct{
uint8_t head1{0x12};
uint16_t head2{0x5678};
float f{1000.0};
uint16_t tail{0x9abc};
} Foo_t;
进一步阅读