我正在尝试提取消息的特定区域并将其解释为结构。
void app_main(void)
{
esp_err_t err;
uint8_t injected_input[]={0xCE,0x33,0xE1,0x00,0x11,0x22,0x33,0x44,0x55,0x66};
model_sensor_data_t stuff = {0};
model_sensor_data_t* sensor_buf = &stuff;
if (extract_sensor_data_msgA(injected_input, sensor_buf) == -1)
{
ESP_LOGE(TAG, "Error in extract_sensor_data_msgA");
}
ESP_LOGI(TAG, "extracted sensor data is 0x%12x", *sensor_buf);
}
typedef struct __attribute__((packed))
{
uint8_t byte0;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
uint8_t byte4;
} model_sensor_data_t;
int32_t extract_sensor_data_msgA(uint8_t *buf, model_sensor_data_t *sensor_buf)
{
if (buf == NULL || sensor_buf == NULL)
{
return -1;
}
//do other checks, blah blah
memcpy(sensor_buf, buf + 5, sizeof(model_sensor_data_t)); //problem lies here
return 0;
}
我希望得到
CLIENT: extracted sensor data is 0x2233445566
但我得到CLIENT: extracted sensor data is 0x 55443322
在我看来,我需要解决两个问题。第一个是字节顺序问题,因为提取的值都被翻转了。第二个问题是带有填充(?)问题的 memcpy。我认为如果我使用 attribute((packed)) 第二个问题会得到解决,但它似乎并没有解决第二个问题。有哪位好心人可以提供一个替代方法让我解决这个问题吗?我已经提到了https://electronics.stackexchange.com/questions/617711/problems-casting-a-uint8-t-array-to-a-struct和C memcpy复制字节的字节序很少但我是仍然不确定如何解决这个问题。
ESP_LOGI(TAG, "extracted sensor data is 0x%12x", *sensor_buf)
假设这是一个 printf-family 函数(似乎很可能),它将期待一个
unsigned int
作为参数,但是你传递了一个 model_sensor_data_t
,所以你会得到未定义的行为。
可能发生的情况是,
unsigned int
是一个 32 位小端值,在寄存器的底部 32 位中被访问,而您的调用约定将传递 64 位寄存器中的 model_sensor_data_t
,所以您将前 4 个字节视为无符号小端字节序。或者,printf 期望堆栈上有一个 32 位值,而您正在传递一个 40 位值(可能填充到 8 个字节以进行对齐)。无论哪种方式,似乎几乎可以肯定您使用的是小端机器,例如某种风格的 x86。
要正确打印,您需要打印每个字节。有点像
ESP_LOGI(TAG, "extracted sensor data is 0x%02x%02x%02x%02x%02x", sensor_buf->byte0,
sensor_buf->byte1, sensor_buf->byte2, sensor_buf->byte3, sensor_buf->byte4);
将提取的数据打印为 40 位大端十六进制值。