Различия в инструментальной цепочке с выравниванием (почему это даже работает)

Есть библиотека ATMEL, которая не работает с моей цепочкой инструментов (инструменты GNU для ARM), и я знаю почему, но я не знаю, почему она работает для старого YAGARTO, и я думаю, что это также для KEIL и IAR

Я работаю в процессоре ARMV5 (AT91SAM9), который не поддерживает выравниваемый доступ к целым числам (4 байта).

есть глобальный буфер, определенный как:

static unsigned char pPageBuffer[AT91C_IFLASH_PAGE_SIZE];

Буфер получает некоторые данные, после чего данные записываются во флэш-память, но данные должны быть перенесены во флэш-память по 4 байта за раз, поэтому существует указатель int, называемый pAlignedSource, который принимает данные по 4 байта за раз.

pAlignedSource = (unsigned int*)pPageBuffer;

Но pPAgeBuffer не обязательно выровнен на 4 байта, так как это массив символов, а pAlignedSource не указывает на выровненный адрес. Как это возможно, что этот код всегда работает в другой цепочке инструментов, но не в моей? Я уже определил соответствующий процессор для компилятора, за исключением того, что оба компилятора получают одинаковые флаги кода.

Моя проблема в том, что когда данные копируются из буфера во флэш

*pAlignedDestination++ = *pAlignedSource++;

Я заканчиваю зашифрованной версией данных:/, однако я исправил это, определив буфер как

static unsigned int pPageBuffer[AT91C_IFLASH_PAGE_SIZE/4];

И это сработало, но мне все еще очень любопытно по этому поводу. Почему это работает в другой цепочке инструментов?

1 ответ

Запись по невыровненным адресам определяется на ARMv5. У вас может быть поведение CP15, чтобы изменить это. Например, он может перехватить или сделать что-то непредсказуемое для режима большого пальца. В режиме ARM, с STR младшие биты сбрасываются без захвата. С LDRмладшие биты маскируются для формирования адреса, но затем данные поворачиваются в зависимости от младших битов.

Редактировать: Кроме того, для одного компилятора / набора инструментов вполне возможно использовать другое выравнивание для начала символьного буфера. Один инструмент может выровнять все, а другой нет. С gccВы можете аннотировать буфер attribute((aligned,4)) или что-то типа того.

Что бы вы ни делали, это непереносимо (и не определено для 'C'), и вы просто не должны этого делать; который, кажется, является выводом, к которому вы пришли.

Другие вопросы по тегам