首页 文章

对齐与已打包属性

提问于
浏览
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服务程序捕获 . 我可以通过简单地向结构添加一个额外的字节来解决这个问题,但这似乎是一个创可贴修复 .

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

我知道还有一个名为aligned的属性 . 对齐只是将结构的开头与偶数字节对齐,还是将结构中的每个项目与偶数字节对齐?你认为这里需要对齐的属性吗?如果我将aligned属性添加到此结构,我还应该将它添加到发送数据的设备上的结构,对吗?截至目前,它们的定义与上面所示的完全相同 .

如果我添加了aligned属性,我应该删除packed属性吗?他们基本上没有相反的做法吗?

2 回答

  • 2

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

  • 2

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

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

相关问题