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

 
 
> 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, 01:27
Сообщение #2


Участник
*

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



Ну точно ! Сейчас прочитал, что архитектура требует: "Halfwords must be aligned to 2-byte boundaries". В обоих случаях у меня невыровненный адрес ! Я так понимаю, поведение процессора тут зависит от реализации. Видимо, в других МК самое худшее к чему это приводит, это к усложеннной процедуре доступа к памяти и уменьшению производительности, однако здесь это обрубили абортом.
Выходит, я выявил весьма скрытый баг компилятора. Он должен был оценить, что не может узнать заранее, какое выравнивание получится в этом сложном выражении, а потому использовать побайтовый доступ (LDRB), даже несмотря на политику оптимизации (которая, вобщем-то, отключена, но я склонен полагать, что он все равно на каком то минимальном уровне оптимизирует).

И что можно сделать в такой ситуации ? sm.gif

P.S. Об этом, оказывается, уже написали здесь: http://gcc.gnu.org/ml/gcc/2000-05/msg00683.html Еще в 2000 году. Видимо, вопрос либо остался без внимания разработчиков, либо они его победили, но спустя много лет баг вернулся sm.gif

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


--------------------
"Сознание своего несовершенства приближает к совершенству"
Гёте
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
|- - 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
- - artymen   Эх... Значит проблема у меня на уровне системного ...   Jan 11 2011, 07:40
|- - GetSmart   Цитата(artymen @ Jan 11 2011, 15:40) Хоро...   Jan 11 2011, 08:04
|- - sergeeff   Цитата(artymen @ Jan 11 2011, 14:40) Ошиб...   Jan 11 2011, 08:17
|- - 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 - 19:52
Рейтинг@Mail.ru


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