2

我正在为 arm7tdmi 目标开发应用程序。我以前用 IAR 编译代码,但现在我切换到 arm-none-eabi-gcc,我遇到了以下问题。

typedef struct
{
    uint32 nNumber;
    uint32 nPara1;
    uint32 nPara2;
    uint32 nPara3;
    uint32 nPara4;
    uint32 nPara5;
    uint32 nParax[122];
} TTXSpecial_t;

static uint8 cTelBuf[TTX_TEL_LENGTH];

例如何时cTelBuf放置@0x4000000A

&(((TTXSpecial_t *)cTelBuf)->nNumber)

返回相同的地址,到目前为止一切正常。


cTelBuf填满,所以((TTXSpecial_t *)cTelBuf)->nNumber应该是0x87654321

内存转储显示:

0x40000000: 00 00 04 00 00 02 0C 00 00 02 21 43 65 87 00 00 
0x40000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


问题是每当我读取(TTXSpecial_t *)cTelBuf)->nNumber该值时0x2004321。所以你可以看到读取是在 address0x40000008而不是0x4000000A.
我的标志是:-mcpu=arm7tdmi -Os -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wpadded -Wstrict-prototypes -fstrict-aliasing -fverbose-asm -Wa
问题 1:如何使用 arm-none-eabi-gcc 设置默认数据对齐方式,
我知道这static uint8 cTelBuf[TTX_TEL_LENGTH] __attribute__((aligned(4)));将解决这种情况下的问题,但我想设置一般对齐方式。IAR 编译器是如何做到的?

问题2:有没有办法在一般情况下避免这个问题(不复制)? 我的意思是:如果我想让TTXSpecial_tstruct 从cTelBuf+1. 一种解决方案可能是将 memcpycTelBuf+1分配给分配的TTXSpecial_t结构,但如何在不分配额外内存的情况下做到这一点?

4

1 回答 1

3

您的问题是您有类型并且不使用它们。编译器知道TTXSpecial_t包含需要 4 字节对齐的 32 位值。问题是您将 cTelBuf 声明为字节数组,编译器只能说字节访问不需要对齐。

因此,我建议您将字节数组声明为您的实际类型TTXSpecial_t(并将其转换为对 uint8 的字节访问),或者通过将其声明为联合(即作为您的TTXSpecial_tunit8重叠的数组)使其成为组合数据类型。

Afaik 在 gcc 中没有通用选项来更改变量的默认对齐方式(某些架构具有特殊的 -malign 开关,但我对 arm 的看法不可用),并且快速浏览 IAR 文档说,IAR 编译器的行为同样的方法。这意味着他将在 4 字节边界对齐您的结构类型的变量,但声明的字节数组将仅对齐 1 字节 - 似乎您很幸运,您使用 IAR 编译器的代码从未出现问题 - 您应该修复尽快,因为它也可能发生在那里。

于 2013-07-26T13:05:52.177 回答