【问题标题】:Copying serialized struct from an 8-bit system to a 32-bit system将序列化结构从 8 位系统复制到 32 位系统
【发布时间】:2016-12-06 22:26:15
【问题描述】:

我有一块带有 32 位 ARM CPU 作为主处理器和一个 8 位 AVR 微控制器作为连接到它的从设备的板。

我正在复制一个结构体(slave 将其转换为字节流,master 接收并将其存储在具有相同定义的结构体的内存位置)。

master 和 slave 都在各自的控制台上打印结构成员的值。但是值不匹配。

我发现问题正在发生,因为主结构中的实际内存分配发生了一些变化,以与 16 位边界对齐。即小于 16 位的数据类型升级为 16 位。

结构中有一些 8 位整数 (u8) 实际上在主设备的内存中分配了 2 个字节,而在从设备中它们按预期只分配了 1 个字节。

不出所料,sizeof(STRUCT_NAME) 在每个系统中产生不同的结果。

我已经找到了一种解决方法,方法是在必要时在传入数据中插入填充字节。

在这种情况下,是否有任何标准方法来处理结构序列化?

我在 ARM 部分使用 GCC。

【问题讨论】:

  • 在不同架构之间传输二进制数据的三个最大问题是 a) 字长,b) 字节顺序,c) 对齐。您可以通过使用u8 之类的定义来缓解a),您可以使用ntohs 之类的功能来缓解b)。大多数编译器都为您提供了一种处理 c) 的方法,例如 #pragma pack: cplusplus.com/forum/general/14659
  • 这个问题已经被问过很多次了。结构是不可移植的,就这么简单。有很多变通方法,在 SO 上搜索重复的问题。

标签: c struct microcontroller 32-bit 8-bit


【解决方案1】:
struct _str
{
    ...
} __attribute__((packed, aligned(1))) struct_name;

对齐到 1 个字节。

【讨论】:

  • 注意:仅限 GCC/clang!
  • 不同的字节序仍然会导致可移植性问题。
  • @starblue“会”还是“可能”?因为问题是针对 ARM 和 AVR mcu,而不是针对抽象案例。我认为 ARM 和 AVR 都是小端。
【解决方案2】:

明确定义数据在传输过程中的表示方式,然后明确编程与字节流的转换。

您可以通过使用 shift 和 mask 操作来做到这一点。使用一些常见数字类型的辅助函数,这很容易管理。

通过这种方式,您可以避免因不同字节序和结构打包而导致的所有可移植性问题。

【讨论】:

    猜你喜欢
    • 2013-09-17
    • 2018-12-24
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2013-08-29
    • 2015-09-26
    相关资源
    最近更新 更多