【发布时间】:2016-12-22 09:36:32
【问题描述】:
我想创建一个由不同大小的不同结构组成的数组。
生成的数组必须紧密打包,结构之间没有空值。
整个东西必须在编译时初始化,所以它可以驻留在嵌入式系统的闪存中。
结果是一棵 USB 配置描述符树,每个描述符紧跟在最后一个之后打包,以生成单个配置 blob。欢迎提出解决问题的不同方法的建议。 http://www.beyondlogic.org/usbnutshell/usb5.shtml#ConfigurationDescriptors
struct a {
uint16_t some_field;
};
struct b {
uint32_t another_field;
};
union detail {
struct a a;
struct b b;
};
const union detail configuration[] = {
{ .a = { .some_field = 23 } },
{ .b = { .another_field = 12 } }
};
上面的例子是我当前失败的尝试的一个显着简化的版本。数组的每个元素都是最大联合成员的大小。所以每个数组成员都是 32 位的,第一个条目用零填充。
电流输出1700 0000 0c00 0000
期望的输出1700 0c00 0000
生成此打包输出的现有方法使用带有宏的巨型 uint8 数组来插入更复杂的值,例如 16 位数字。 结构数组更准确地表示数据并提供类型安全(如果可以的话)。
我不需要能够索引或访问数组中的数据,blob 被推入低级 USB 例程。使用 gcc 打包属性并没有改变标准联合数组的行为。
【问题讨论】:
-
这个问题是不应该使用结构/联合进行序列化的原因之一。
-
工会不是这样工作的。
-
感谢有关拥有单个大型结构的想法。不幸的是,完整的结构取决于配置,一个配置可能有 1 个端点,另一个可能有三个,其中每个端点是另一个结构。 GCC 不支持使用可变长度数组嵌套结构,并且将它们设置为固定大小会破坏可重用性。
-
数组的所有元素必须是相同的大小。这是因为用于访问第 N 个元素的代码将一个元素的 N x 大小添加到数组的基地址中。如果元素的大小不同,那根本行不通。这是您不能拥有具有灵活数组成员的结构类型数组的原因之一。
-
union修饰符意味着结构占用相同的内存,因此在一个结构中设置一个字段会影响另一个结构中的一个或多个字段。更好的数据表示是每个结构都是一个单独的实例,然后有一个指针数组,其中每个指针指向一个结构实例
标签: c arrays linker usb unions