创建一个包含结构体数组的缓冲区,其中的字段大小与字节不对齐

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

我正在用 C 语言编写 TLC6C5724 的驱动程序。该驱动程序使用公共移位寄存器,除其他字段外,还使用包含 3 个字段的结构数组。以下是此类结构的两个示例:

typedef struct
{
    uint8_t outb : 7;
    uint8_t outg : 7;
    uint8_t outr : 7;
} dcdata_field_t;

typedef struct
{
    uint16_t outb : 12;
    uint16_t outg : 12;
    uint16_t outr : 12;
} gs_field_t;

然后我们将创建一个数组,如下所示:

dcdata_field_t dcdata[8];
gs_field_t gsdata[8];

预期的结果将是一个像这样的缓冲区:

uint8_t dcdata_output[21];

其中将包含以下方式的数据:

Bits 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
     |  outb[0]  |     oubg[0]      | ...

您是否知道一种将这些结构之一的数组打包/解析到缓冲区中的好方法,该缓冲区可用于使用例如 SPI 将此配置传输到设备。输出缓冲区中的结构或字段之间不得有填充。

c embedded
1个回答
0
投票

在 C 中,实际的结构对象需要能够拥有地址 - 这意味着它们需要字节对齐。

解决这个问题的唯一方法是创建“超级结构”,例如一个包含 8 个

dcdata_field_t
的字段;例如,

typedef struct
{
    uint8_t outb_1 : 7;
    uint8_t outg_1 : 7;
    uint8_t outr_1 : 7;
    uint8_t outb_2 : 7;
    uint8_t outg_2 : 7;
/* … */
    uint8_t outg_7 : 7;
    uint8_t outb_8 : 7;
    uint8_t outg_8 : 7;
    uint8_t outr_8 : 7;
} dcdata_field_t;

因为它的长度是八位字节的倍数。 (即便如此,可能还有其他因素限制对齐,从而使您无法打包。)

(对于您的其他结构,其中两个就足够了。)

坦率地说,这是一个糟糕的想法,您应该编写一对函数,通过移位和掩码操作从较大的整数类型中提取位域。

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