Различия в инструментальной цепочке с выравниванием (почему это даже работает)
Есть библиотека 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'), и вы просто не должны этого делать; который, кажется, является выводом, к которому вы пришли.