2

有一个 ATMEL 库不适用于我的工具链(用于 ARM 的 GNU 工具),我知道为什么,但我不知道为什么它适用于旧的 YAGARTO,我想这也适用于 KEIL 和 IAR

我正在使用不支持对整数(4 字节)的非对齐访问的 ARMV5 处理器(AT91SAM9)。

有一个全局缓冲区定义为:

static unsigned char pPageBuffer[AT91C_IFLASH_PAGE_SIZE];

缓冲区获取一些数据,然后将数据写入闪存,但数据必须一次写入 4 个字节,因此有一个名为 pAlignedSource 的 int 指针可以一次读取 4 个字节的数据。

pAlignedSource = (unsigned int*)pPageBuffer;

但是 pPAgeBuffer 不一定是 4 字节对齐的,因为它是一个 char 数组,并且 pAlignedSource 并不指向对齐的地址。这段代码怎么可能总是在另一个工具链中工作,但不在我的工具链中?,我已经为编译器定义了正确的 CPU,除了两个编译器都获得相同的代码标志。

我的问题是当数据从缓冲区复制到闪存时

*pAlignedDestination++ = *pAlignedSource++;

我以数据的加扰版本结束:/,但是我通过将缓冲区定义为来解决这个问题

static unsigned int pPageBuffer[AT91C_IFLASH_PAGE_SIZE/4];

它成功了,但我仍然对此很好奇。为什么它在其他工具链中起作用?

4

1 回答 1

2

在 ARMv5 上定义了写入未对齐地址。您可能有 CP15 行为来改变它。例如,它可能会为拇指模式捕获或做一些不可预测的事情。在 ARM 模式下,STR低位被丢弃而没有陷阱。使用LDR时,低位被屏蔽以形成地址,但数据随后根据低位旋转。

编辑:此外,一个编译器/工具集完全有可能对字符缓冲区的开头使用不同的对齐方式。一种工具可能会对齐所有内容,而另一种可能不会。使用,您可以使用或类似gcc的方式注释缓冲区。attribute((aligned,4))

无论您在做什么,它都是不可移植的(对于“C”是未定义的),您不应该这样做;这似乎是你得出的结论。

于 2015-01-30T15:05:08.863 回答