3

我正在开发 16 位 PIC 的固件并用 C(Microchip C30 编译器)编写。我的设备从外部设备接收到一长串字节,然后我试图将这些字节复制到一个结构中。结构定义如下:

typedef struct __attribute__((__packed__)) {
    char    F1Nickname[17];
    char    F2Nickname[17];
    DWORD   F1CurrentPos;
    DWORD   F2CurrentPos;
    WORD    F1CurrentTemp;
    WORD    F2CurrentTemp;
    DWORD   F1MaxPos;
    DWORD   F2MaxPos;
    BYTE    F1TempCompOn;
    BYTE    F2TempCompOn;
    BYTE    CheckSum;
} deviceStatus;

我遇到了一个奇怪的问题,每当结构中的字节总数为奇数时,我的程序就会冻结并陷入 AddressError 服务例程。我可以通过简单地向结构添加一个额外的字节来解决这个问题,但这似乎是一个创可贴的修复。

我将打包属性放在结构上,因为我想确保编译器没有在我的变量之间插入任何填充字节。如果发生这种情况,从接收到的字符数组复制时,我的结构中的值将不正确。

我知道还有一个属性叫做对齐。对齐只是将结构的开头对齐到偶数字节还是将结构中的每个项目对齐到偶数字节?你认为这里需要对齐属性吗?如果我将对齐属​​性添加到此结构中,我也应该将其添加到发送数据的设备上的结构中,对吗?到目前为止,它们的定义方式与上图完全相同。

如果我添加对齐的属性,我应该删除打包的属性吗?他们基本上不做相反的事情吗?

4

2 回答 2

2

某些微处理器架构只能在与字边界对齐的地址上进行数据提取,如果它们不是字对齐的,则会抛出异常。通常,编译器会提供帮助并生成执行必要杂技的代码,以确保提取是字对齐的,但您的编译器似乎并非如此,这就是您看到异常的原因。

在您的情况下,您正在使用 astruct来序列化数据,因此必须对其进行打包。在这种情况下,您必须重新排列struct以确保没有跨字边界的读取,或者您将需要使用和解压缩结构并手动序列化数据。

于 2011-08-11T13:12:07.777 回答
2

__attribute____packed__不是 C 标准的一部分,是编译器提供的扩展。确定它们的含义的唯一方法是在编译器文档中查找它。

于 2011-08-11T12:55:15.927 回答