Arduino (ESP32) - 结构大小和输出混淆

问题描述 投票:0回答:2

我尝试将结构转换为 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 <== ???
struct arduino esp32 sizeof arduino-c++
2个回答
0
投票

我期望数组的大小为 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;

进一步阅读

数据结构对齐C++结构大小和数据对齐


0
投票

我期望数组的大小为 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;

进一步阅读

数据结构对齐C++结构大小和数据对齐

© www.soinside.com 2019 - 2024. All rights reserved.