реклама на сайте
подробности

 
 
> LPC2888, Data Abort exception, при выполнении кода из Flash
artymen
сообщение Jan 10 2011, 07:27
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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


--------------------
"Сознание своего несовершенства приближает к совершенству"
Гёте
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
artymen
сообщение Jan 11 2011, 07:40
Сообщение #2


Участник
*

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



Эх... Значит проблема у меня на уровне системного проектирвоания. Хорошо, а как бы вы разрулили эту ситуацию, когда надо сразу с данными работать, не перекидывая из памяти в память, чтобы подвести выравнивание (а также, опционально, эндианность и т.п.) под общий знаменатель ?

Цитата
А другой программист может возразить: "Нафига мне такая инициатива компилятора? Чего это он умничает? Мне не нужно никакого разбиения на побайтовый доступ, а нужна максимальная производительность!" И тоже будет прав. На всех не угодишь.
Я предусмотрел такой ответ sm.gif Поясню свою позицию. Эта инициатива очень и очень скромная, как невинное деяние монашки, по сравнению с многочисленными другими инициативами, которые компилятор творит в процессе оптимизации: режет переменные, рубит функции, раскидывает операции и прочий ужас, против которого даже грозный volatile не всегда спасает. Так что если "другие программисты" предпочитают производительность неработоспособности, то я склонен рассматривать это как извращение, а извращение это меньшинство, следовательно следует предусмотреть явную опцию, которая отключает инициативу, а по умолчанию (тобишь для большинства) инициатива должна быть.

P.S. Структуры я запаковал затем, чтобы "унифицировать" тем самым выравнивание (большинство компиляторов, я думаю, умеет упаковывывать до 1 байта, а до произвольного числа - не факт), ну и размер сократить заодно.

Цитата
Собственно говоря компилятор так и делает когда необходимо, например при пакованных структурах. А если структура обыкновенная, то компилятор СПРАВЕДЛИВО считает, что всё находится по выровненным адресам и делает чтение\запись с максимальной возможной разрядностью.
Я понимаю, но у меня компилятор все знает. Я не подсовываю ему непакованную структуру вместо пакованной, или наоборот. Ошибка возникла в том месте, где арифметика указателей.

Цитата
То что код работал из RAM, судя по всему простая случайность.
Там тоже был невыровненный доступ sm.gif Но мне кажется, это недоработка со стороны аппаратной поддержки невыравниваемого доступа. Полагаю, она есть несмотря на директиву в архитектуре. По всей видимости, контроллер памяти успел провернуть трюк с двойным доступом и ротацией в RAM, а вот с флешем этот трюк уже не уложился во флешевые wait-таймы, и потому провалился по таймауту, вызвав аборт. Это всего лишь предположение, точнее очередное мое злорадство в сторону LPC2888 sm.gif

Сообщение отредактировал artymen - Jan 11 2011, 08:25


--------------------
"Сознание своего несовершенства приближает к совершенству"
Гёте
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jan 11 2011, 08:17
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(artymen @ Jan 11 2011, 14:40) *
Ошибка возникла в том месте, где арифметика указателей.


Ошибка возникла, когда вы заставляете процессор читать данные, размерностью больше 1 байта с нечетных адресов. А он этого делать не может. Поэтому вам надо, с учетом этой процессорной специфики, поменять свою концепцию хранения данных.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 23:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01422 секунд с 7
ELECTRONIX ©2004-2016