|
LPC2888, Data Abort exception, при выполнении кода из Flash |
|
|
|
Jan 10 2011, 07:27
|

Участник

Группа: Участник
Сообщений: 66
Регистрация: 6-11-09
Из: г. Омск
Пользователь №: 53 464

|
Прежде всего позлорадствую. Я не удивлен подобного рода проблемой, потому как мне и моим коллегам эта модель сразу дико не понравилась. Она особенная в семействе LPC2000, эдакий уродец. Все его отличия только отрицательные (они в полной мере описаны в этом аппноуте), единственный плюс это энергопотребление, по которому он и был выбран (не нами, естественно). Проблема возникла, когда размер проекта достиг порядка 2000 строк кода. Причем "охват" использования ресурсов МК небольшой: прерывания не используются, код линейный, из периферии используется только GPIO, LCD контроллер, ну и CGU для тактирования последнего. Компилятор GCC (Yagarto). Оптимизация кода отключена. Отлаживаю J-Link'ом (через GDB Server), драйвера и прошивка последние. Cache и memory remap не используются, в j-linke также отключено всяческое кеширование. Из RAM код выполняется замечательно, но из Flash вдруг где-то посередине (на дисплее половина интерфейса уже отрисовалась) процессор вываливается в Data Abort. Причем происходит это даже не в какой то ответсвенный момент работы с регистрами периферии или еще чего-то там, а в в процессе выполнения безобидной функции. Вот она: Код 10401878 <_Z14get_menu_childP18menu_item_header_th>: menu_item_header_t* get_menu_child(menu_item_header_t* menu, uint8_t i) { 10401878: e52db004 push {fp}; (str fp, [sp, #-4]!) 1040187c: e28db000 add fp, sp, #0 10401880: e24dd00c sub sp, sp, #12 10401884: e50b0008 str r0, [fp, #-8] 10401888: e1a03001 mov r3, r1 1040188c: e54b3009 strb r3, [fp, #-9] return (menu_item_header_t *)((uint8_t *)(menu) + *((uint16_t *)((uint8_t *)(menu) + sizeof(menu_item_header_t) + 2*(i)))); 10401890: e51b2008 ldr r2, [fp, #-8] 10401894: e55b3009 ldrb r3, [fp, #-9] 10401898: e2833001 add r3, r3, #1 1040189c: e1a03083 lsl r3, r3, #1 104018a0: e0823003 add r3, r2, r3 104018a4: e1d330b0 ldrh r3, [r3] <--- выполнение этой инструкции приводит к возникновению data abort exception 104018a8: e51b2008 ldr r2, [fp, #-8] 104018ac: e0823003 add r3, r2, r3 } 104018b0: e1a00003 mov r0, r3 104018b4: e28bd000 add sp, fp, #0 104018b8: e8bd0800 pop {fp} 104018bc: e12fff1e bx lr Я поставил брикпойнт на эту инструкцию. В регистре R3 на этот момент находится вполне валидный адрес из области flash. Просматриваю память по этому адресу, все шикарно читается, значение показывает то самое, которое и должно быть там (это значение я узнал, выполнив до этого код в RAM'е). Ну что делать ? Наверно, надо как-то вмешаться, возможно я сброшу какой-нить там кеш или конвейр комманд своим действием. Беру и меняю адрес в R3 на другой произвольно взятый из области flash. Делаю шаг, все равно вываливается, ну и ладно, чуда не произошло. Начинаю все сначала, и на этот раз меняю его на адрес из RAM. Вуаля, инструкция выполняется успешно ! Но мне то надо, чтобы код выполнялся так, как он написан. И пришлось мне оказать помощь процу, взяв выполнение инструкции "ldrh r3, [r3]" на себя, раз уж он не справляется, благо это меня не сильно обременило, потому как эта функция всего два раза вызывается. Итак, что я сделал. Проц останавливается про брикпоинту на этой инструкции. Я ручками беру адрес из R3, по этому адресу из памяти запрашиваю значение, запихиваю это значение в R3, в регистр PC запихиваю значение 0x104018a8 (перепрыгиваю через злосчастную инструкцию), говорю отладчику продолжить выполнять код дальше. Остановка происходит на втором вызове, я повторяю те же действия. В результате код выполняется до конца, на дисплее тот же результат, какой был при выполнении из RAM. Какие есть соображения по этому поводу ? P.S. За startup-код и линкер-скрипты ручаюсь. P.S.2. Я портировал код на IAR, и то же самое повторилось в этой же функции, но уже при выполнении из RAM.
Сообщение отредактировал artymen - Jan 10 2011, 07:32
--------------------
"Сознание своего несовершенства приближает к совершенству" Гёте
|
|
|
|
|
 |
Ответов
|
Jan 11 2011, 07:40
|

Участник

Группа: Участник
Сообщений: 66
Регистрация: 6-11-09
Из: г. Омск
Пользователь №: 53 464

|
Эх... Значит проблема у меня на уровне системного проектирвоания. Хорошо, а как бы вы разрулили эту ситуацию, когда надо сразу с данными работать, не перекидывая из памяти в память, чтобы подвести выравнивание (а также, опционально, эндианность и т.п.) под общий знаменатель ? Цитата А другой программист может возразить: "Нафига мне такая инициатива компилятора? Чего это он умничает? Мне не нужно никакого разбиения на побайтовый доступ, а нужна максимальная производительность!" И тоже будет прав. На всех не угодишь. Я предусмотрел такой ответ  Поясню свою позицию. Эта инициатива очень и очень скромная, как невинное деяние монашки, по сравнению с многочисленными другими инициативами, которые компилятор творит в процессе оптимизации: режет переменные, рубит функции, раскидывает операции и прочий ужас, против которого даже грозный volatile не всегда спасает. Так что если "другие программисты" предпочитают производительность неработоспособности, то я склонен рассматривать это как извращение, а извращение это меньшинство, следовательно следует предусмотреть явную опцию, которая отключает инициативу, а по умолчанию (тобишь для большинства) инициатива должна быть. P.S. Структуры я запаковал затем, чтобы "унифицировать" тем самым выравнивание (большинство компиляторов, я думаю, умеет упаковывывать до 1 байта, а до произвольного числа - не факт), ну и размер сократить заодно. Цитата Собственно говоря компилятор так и делает когда необходимо, например при пакованных структурах. А если структура обыкновенная, то компилятор СПРАВЕДЛИВО считает, что всё находится по выровненным адресам и делает чтение\запись с максимальной возможной разрядностью. Я понимаю, но у меня компилятор все знает. Я не подсовываю ему непакованную структуру вместо пакованной, или наоборот. Ошибка возникла в том месте, где арифметика указателей. Цитата То что код работал из RAM, судя по всему простая случайность. Там тоже был невыровненный доступ  Но мне кажется, это недоработка со стороны аппаратной поддержки невыравниваемого доступа. Полагаю, она есть несмотря на директиву в архитектуре. По всей видимости, контроллер памяти успел провернуть трюк с двойным доступом и ротацией в RAM, а вот с флешем этот трюк уже не уложился во флешевые wait-таймы, и потому провалился по таймауту, вызвав аборт. Это всего лишь предположение, точнее очередное мое злорадство в сторону LPC2888
Сообщение отредактировал artymen - Jan 11 2011, 08:25
--------------------
"Сознание своего несовершенства приближает к совершенству" Гёте
|
|
|
|
Сообщений в этой теме
artymen LPC2888, Data Abort exception Jan 10 2011, 07:27 Chameleon Выравнивание? Чему равен младший бит регистра R3 в... Jan 10 2011, 09:52 artymen Ну точно ! Сейчас прочитал, что архитектура тр... Jan 11 2011, 01:27 aaarrr Цитата(artymen @ Jan 11 2011, 07:27) Он д... Jan 11 2011, 02:00 artymen А чей же ? Неужто это я должен заботиться об архит... Jan 11 2011, 02:45 aaarrr Цитата(artymen @ Jan 11 2011, 08:45) Неуж... Jan 11 2011, 03:30 artymen Нет, не должен ! Вот хотя бы одна объективная ... Jan 11 2011, 05:07 xelax Цитата(artymen @ Jan 11 2011, 11:07) Нет,... Jan 11 2011, 06:44 IgorKossak artymen, не кипятитесь. Послушайте ещё раз и внима... Jan 11 2011, 05:40 artymen Я прекрасно это понимаю. И, как я сейчас выяснил, ... Jan 11 2011, 06:20 IgorKossak QUOTE (artymen @ Jan 11 2011, 11:20) ... ... Jan 11 2011, 06:34  sonycman Цитата(IgorKossak @ Jan 11 2011, 12:34) Т... Jan 11 2011, 07:22 GetSmart Цитата(artymen @ Jan 11 2011, 15:40) Хоро... Jan 11 2011, 08:04 xelax Цитата(artymen @ Jan 11 2011, 13:40) Там ... Jan 11 2011, 11:24 artymen Вот я уже и начал менять. Походу ничего другого мн... Jan 11 2011, 08:28 GetSmart Цитата(artymen @ Jan 11 2011, 16:28) А по... Jan 11 2011, 08:33 artymen Ну тогда я не понимаю, что вы имеете в виду под ... Jan 11 2011, 10:15 GetSmart Цитата(artymen @ Jan 11 2011, 18:15) Ну т... Jan 11 2011, 15:06  xelax Цитата(GetSmart @ Jan 11 2011, 21:06) А е... Jan 12 2011, 04:29 artymen Хм, классно. Выходит, IAR рулит И все же во мне т... Jan 12 2011, 00:54 artymen Ну елки палки ! Выровнял я свои данные. Теперь... Jan 12 2011, 05:03 GetSmart Цитата(artymen @ Jan 12 2011, 13:03) Ну е... Jan 12 2011, 05:41  sergeeff Цитата(GetSmart @ Jan 12 2011, 12:41) В у... Jan 12 2011, 06:43   xelax Цитата(sergeeff @ Jan 12 2011, 12:43) Вов... Jan 12 2011, 09:34 artymen Все, победил ! Всем спасибо. Теперь буду зн... Jan 12 2011, 06:07
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|