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

 
 
> Undefined instruction, Data Abort, SWI - помогите локализовать проблему!
Атмег
сообщение Aug 10 2010, 18:23
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Тупой вопрос, но уже месяц не могу найти концов. Спецы, помогите!

Имеется отладочная плата at91sam9263-ek (то есть железо как мне кажется рабочее). Приложение работает, вроде бы все нормально. Но. Периодически возникают прерывания Undefined instruction, Prefetch abort, Data abort и Software interrupt. Возникают в произвольный момент времени. То есть иногда программа идет по одной и той же ветке нормально, иногда в какой то момент возникает прерывание.
Я могу понять причины Undefined instruction, ну скажем не туда что то записал (код из SDRAM исполняется), но SWI почему тогда возникает?
Смотрю отладчиком:

backtrace
#0 0x0000000c in ?? () // исключение по prefetch abort
#1 0xdfff9f36 in ?? () // предыдущее значение PC - из неиспользуемого диапазона, такое обращение и должно вызвать abort

Притом что никакой динамической памяти, передачи функции в качестве параметра и т.п. у меня не используется, все структуры статические.

Проект слинкован под SDRAM, собирается gcc-4.2.2, newlib-1.16.0.

Более конкретно вопросы:

1. SWI (software, не spurious), случайно возникает, хотя нигде в коде не используется - непонятно, как?

2. В gcc был (есть?) баг, касающийся генерации прологов/эпилогов в прерываниях, но у меня обработчики взяты из атмеловских примеров, ниже приведу их. Там и вложенность поддерживается и общий стек используется, переполнения быть не должно.
Тут вроде как все норм должно быть? Или я еще какой то тонкости не понимаю?

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

Вот мой стартап, обработчик FIQ скопирован с IRQ, выкидывать лишнее не стал для уверенности что не в нем проблема.
CODE

#define FIQ_STACK_SIZE 8*3*4
#define IRQ_STACK_SIZE 8*3*4

#define ARM_MODE_ABT 0x17
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13

#define I_BIT 0x80
#define F_BIT 0x40

//------------------------------------------------------------------------------
// Startup routine
//------------------------------------------------------------------------------

.align 4
.arm

/* Exception vectors
*******************/
.section .vectors, "a", %progbits

resetVector:
ldr pc, =resetHandler /* Reset */
undefVector:
b undefVector /* Undefined instruction */
swiVector:
b swiVector /* Software interrupt */
prefetchAbortVector:
b prefetchAbortVector /* Prefetch abort */
dataAbortVector:
b dataAbortVector /* Data abort */
reservedVector:
b reservedVector /* Reserved for future use */
irqVector:
b irqHandler /* Interrupt */
fiqVector:
// b fiqHandler /* Fast interrupt */
//------------------------------------------------------------------------------
/// Handles a fast interrupt request by branching to the address defined in the
/// AIC.
//------------------------------------------------------------------------------
fiqHandler:

/* Save interrupt context on the stack to allow nesting */
sub lr, lr, #4
stmfd sp!, {lr}
mrs lr, SPSR
stmfd sp!, {r0, lr}

/* Write in the FVR to support Protect Mode */
ldr lr, =AT91C_BASE_AIC
ldr r0, [lr, #AIC_FVR]
str lr, [lr, #AIC_FVR]

/* Branch to interrupt handler in Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC | F_BIT | I_BIT
stmfd sp!, {r1-r3, r4, r12, lr}
blx r0

/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in FIQ mode */
ldmia sp!, {r1-r3, r4, r12, lr}
msr CPSR_c, #ARM_MODE_FIQ | F_BIT | I_BIT

/* Acknowledge interrupt */
ldr lr, =AT91C_BASE_AIC
str lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
ldmia sp!, {r0, lr}
msr SPSR_cxsf, lr
ldmia sp!, {pc}^

//------------------------------------------------------------------------------
/// Handles incoming interrupt requests by branching to the corresponding
/// handler, as defined in the AIC. Supports interrupt nesting.
//------------------------------------------------------------------------------
irqHandler:

/* Save interrupt context on the stack to allow nesting */
sub lr, lr, #4
stmfd sp!, {lr}
mrs lr, SPSR
stmfd sp!, {r0, lr}

/* Write in the IVR to support Protect Mode */
ldr lr, =AT91C_BASE_AIC
ldr r0, [lr, #AIC_IVR]
str lr, [lr, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC
stmfd sp!, {r1-r3, r4, r12, lr}
blx r0

/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in IRQ mode */
ldmia sp!, {r1-r3, r4, r12, lr}
msr CPSR_c, #ARM_MODE_IRQ | F_BIT | I_BIT

/* Acknowledge interrupt */
ldr lr, =AT91C_BASE_AIC
str lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
ldmia sp!, {r0, lr}
msr SPSR_cxsf, lr
ldmia sp!, {pc}^

//------------------------------------------------------------------------------
/// Initializes the chip and branches to the main() function.
//------------------------------------------------------------------------------
.section .text
.global entry

entry:
resetHandler:

/* Useless instruction for referencing the .vectors section */
ldr r0, =resetVector

/* Set pc to actual code location (i.e. not in remap zone) */
ldr pc, =1f

/* Initialize the prerelocate segment */
1:
ldr r0, =_efixed
ldr r1, =_sprerelocate
ldr r2, =_eprerelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Perform low-level initialization of the chip using LowLevelInit() */
ldr sp, =_sstack
stmfd sp!, {r0}
ldr r0, =LowLevelInit
blx r0

/* Initialize the postrelocate segment */

ldmfd sp!, {r0}
ldr r1, =_spostrelocate
ldr r2, =_epostrelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Clear the zero segment */
ldr r0, =_szero
ldr r1, =_ezero
mov r2, #0
1:
cmp r0, r1
strcc r2, [r0], #4
bcc 1b

/* Setup stacks
**************/
/* FIQ mode */
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
ldr sp, =_sstack
sub r4, sp, #FIQ_STACK_SIZE

/* IRQ mode */
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov sp, r4
sub r4, sp, #IRQ_STACK_SIZE

/* Supervisor mode (interrupts enabled) */
msr CPSR_c, #ARM_MODE_SVC
mov sp, r4

/* Branch to main()
******************/
ldr r0, =main
blx r0

/* Loop indefinitely when program is finished */
1:
b 1b



Буду благодарен любым соображениям! Подскажите хоть что нибудь. Может кто натолкнет на мысль.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Атмег
сообщение Aug 11 2010, 15:36
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Стартап я в первом посте привел, уже много раз все пересмотрел - не пойму что не так.

Объясните, как может получиться такая ситуация
Цитата
backtrace
#0 0x0000 0004
#1 0x2000 20A4 at main.c....
#2 0xE24E E004


Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 11 2010, 16:12
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE
Но под стек места полно и непонятно

Вопрос на засыпку, сколько стеков у Вашего ARM? В каком режиме работаете? Из какого режима вылетели в Аборт? А "полно", это достаточно для работы?

QUOTE (Атмег @ Aug 11 2010, 18:36) *
Объясните, как может получиться такая ситуация

Без понятия, что значат всякие приведенные Вами цифири и как Вы их получали, посему ответа не будет.
Вот, например, распечатка вылета на Data Abort, по которой видно текущее состояние:
CODE
Abort:[D] PC:00016AF0 Op:E5D00020 CPSR:6000001F
   LR:00014BF4 SP:400059C0
SP[0]:00000022->00014BF4->00000016->0001381C->
SP[4]:40000EBC->40000E70->00000004->40002D4C
R0:00430001 R1:00000000 R2:00027190 R3:00000000  R4:40002D4C  R5:00026D40
R6:00000000 R7:40001698 R8:00000001 R9:00000004 R10:00000FFF R11:400034D4
R12:00000000

И можно о чем-то рассуждать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 12 2010, 01:16
Сообщение #4


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zltigo @ Aug 11 2010, 19:12) *
Вот, например, распечатка вылета на Data Abort, по которой видно текущее состояние:

Data Abort это наиболее простая проблема, но по вашей распечатке не ясно содержание какого SP выведено. Тот что "DAbt SP" - смотреть бессмыслено, надо смотреть SP и стек контекст предыдущего режима, из которого ввалились в Abort. Prefetch Abort тоже относительно прост, LR SYS/SVSR режима будет содержать то место откуда прыгнули в недоступную область памяти.

В случае же Undef / Swi найти тот LR, что нужно очень не просто т.к. проц выполняет уже совсем не код программы, а просто какой-то мусор со случайного адреса.
если вдобавок еще и SYS / SVSR SP подпорчен, то практически нереально будет найти то место из которого осуществлен прыжек... Здесь нужен более глубойкий анализ дампа нежели только значения регистров.

как причина вышеописанного поведения из наиболее часто встечающихся в порядке убывания такие:

1. Перетирание стека упомянутое выше, по причине нехватки стека - решение: не жлобитесь, на железках с 32/64MB памяти отведите 1-2MB под стек (напр 64KB под задачу) и забудьте что такое проблемы со стеком навсегда.
2. Перетирание стека по причине выхода за границу массива, если есть массивы объявленные в стеке самое время посмотреть а все ли с ними в порядке.
3. NULL pointer в результате которого перетирается таблица векторов, тут имеет смысл анализировать дампы только с Data/Prefetch Abort'ами - их анализ будет самым эффективным.
4. Непроинициализированные поля / переменные. - очень сложная ситуация...
5. сбоит SDRAM - портится значение бита ячейки содержащей какой-нить callback. или что еще хуже - corruption непосредственно в секции кода. Здесь главное убедиться что в некой ячейке изменяется строго один бит, ну а дальше выявить регулярность и найти соотв. проблемную линию / попробовать изменить параметры SDRAM контроллера, если не поможет, - фиксить аппартный баг, вплоть до замены м/c памяти.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2010, 05:33
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (defunct @ Aug 12 2010, 04:16) *
но по вашей распечатке не ясно содержание какого SP выведено.

Поскольку SP, Abort режима, как Вы правильно заметили, бессмысленен с точки зрения локализации проблемы, то выводить его мне было-бы ОЧЕНЬ странно. Посему совершено очевидно какой стек распечатан. Это точно так-же очевидно по содержимому CPSR, он ведь не Exception Mode показывает, а вполне себе System Mode не правда-ли smile.gif? Кстати, по нему-же видно, что вывалились не из обработчика прерывания или секции с закрытыми прерываниями - тоже информация.
И для именно для того, что-бы понять куда (чего как-раз не видно по распечатке) попали, и есть специальный индикатор Abort:[D] - значение которого я специально в посте и расшифровал - "Data Abort". Так-что никаких непоняток в распечатке нет.
QUOTE
В случае же Undef / Swi найти тот LR, что нужно очень не просто т.к. проц выполняет уже совсем не код программы, а просто какой-то мусор со случайного адреса.

Тем не менее, он далеко не обязательно попал туда через МНОЖЕСТВЕНЫЕ call. Ну в моем случае, распечатка состояния производится уже в отладочной консоли загрузчика - гипотетически можно и мусор по которому бежали порасшифровывать, благо PC есть (замечу, что тоже "тот" smile.gif ). В свое время для некоторых процессоров в консоли у меня и дизассемблер был. Ну в случае НЕ мусора, несколько вызовов обычно уже видны в стеке и вычисляются по листингу.
P.S.
Приведенная распечатка вылета, кстати, была прислана из-за границы за несколько часов до этого заказчиком ведущими проверку софта с добавленной функциональностью на железе которого у меня вообще нет smile.gif. Проблема с различием структур данных была по этой распечатке решена минут за 20. Случай был практически (в структурах было совсем не то) такой:
QUOTE
4. Непроинициализированные поля / переменные. - очень сложная ситуация...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 16 2010, 02:34
Сообщение #6


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zltigo @ Aug 12 2010, 08:33) *
Это точно так-же очевидно по содержимому CPSR, он ведь не Exception Mode показывает, а вполне себе System Mode не правда-ли smile.gif?

CPSR проглядел когда смотрел. Таки да, показывает Sys.
Правда тогда такой вывод для DAbt тоже не совсем понятный. Для DABT - SYS LR - неактуален, там нужен Abort LR т.к именно он указывает точное место где произошел краш. Только не говорите, что оно у Вас само собой так и есть и это ясно из распечатки smile.gif
(то что там PC нарисован я вижу, только мне было бы намного понятней если бы его там не было, а вместо него был Abort LR)

Цитата(Атмег @ Aug 12 2010, 16:37) *
Смотрю по мар-файлу, неск Мб от последней переменной до начала стека

ОК.

Цитата
Структуры объявлены, но обращаюсь к полям стандартным образом, без особых хитростей...

Стуктуры могут быть с массивами в конце.
Например:

Код
{
    U8 Id;
    U8 Type;
    ...
    U32 Payload[ 64 ];
}


И в каком-нибудь обработчике может делаться совсем без хитростей:

Код
U32 *p = pCmd->Payload;

*p++ = xxx;
*p++ = xxx;
...
*p++ = xxx;


Без проверки на размер.


Цитата
malloc/calloc не использую, вроде не должно...

А партишины? Хоть какой-то намек на динамическую память в программе есть? Если используется сетевой стек неповерю, что нет динамического пула пакетов ;>

Цитата
Можете подробнее, что имеется в виду? Кроме обращения по указателю который равен 0.

Имеется в виду что некоторые поля структур не проинициализированы до того как начинают использоваться.
Например, есть тип пакета:

Код
typedef struct tagPACKET
{
     struct tagPACKET *pNext;
     ....
} TPACKET, *PPACKET;



Скажем вы создали пакет, а pNext не проинициализировали в NULL, и там будет какой-то мусор.
Затем вы этот пакет пропускаете через функцию которая обслуживает список пакетов связанный по pNext и получаете краш, т.к. pNext созданного пакета указывает черт знает куда...

Цитата
Ситуация слабоповторяемая, то сбоит, то не сбоит. То есть запускаю определенную функцию в программе, может на 3-й раз посыпаться, может на 10-й... Плата - отладка Атмеловская. Могут на такой плате быть проблемы из-за плохой разводки? Или это больше относится к своим платам?

Могут быть на любой плате (made in USA еще не гарантирует что с железом все ОК).
И даже если в железом все ОК, могут возникнуть проблемы из-за настроек SDRAM контроллера, несовместимых с реально впаянными чипами памяти в конкртеной ситуации.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Атмег   Undefined instruction, Data Abort, SWI - помогите локализовать проблему!   Aug 10 2010, 18:23
- - aaarrr   Цитата(Атмег @ Aug 10 2010, 22:23) 1. SWI...   Aug 10 2010, 18:49
- - zltigo   QUOTE (Атмег @ Aug 10 2010, 21:23) 3. Про...   Aug 10 2010, 19:22
- - Атмег   Вот смотрю LR: #0 0x0000 0004 #1 0x2000 20A4 at ...   Aug 11 2010, 11:36
|- - sergeeff   Обычно места под стеки резервируются в startup...   Aug 11 2010, 13:11
|- - zltigo   QUOTE (defunct @ Aug 16 2010, 04:34) Прав...   Aug 16 2010, 06:49
|- - defunct   Цитата(zltigo @ Aug 16 2010, 09:49) Именн...   Aug 16 2010, 11:45
|- - zltigo   QUOTE (defunct @ Aug 16 2010, 13:45) Удоб...   Aug 16 2010, 11:50
|- - defunct   Цитата(zltigo @ Aug 16 2010, 14:50) Что ...   Aug 16 2010, 11:55
|- - zltigo   QUOTE (defunct @ Aug 16 2010, 13:55) смот...   Aug 16 2010, 11:59
- - sergeeff   Проверьте, правильно ли заполнена таблица векторов...   Aug 11 2010, 16:34
- - Атмег   ЦитатаВопрос на засыпку, сколько стеков у Вашего A...   Aug 12 2010, 13:37
|- - zltigo   QUOTE (Атмег @ Aug 12 2010, 16:37) backtr...   Aug 12 2010, 13:58
- - sergeeff   Вы бы взяли и прислали свой проект, если он не сов...   Aug 12 2010, 14:08
- - Атмег   Цитата(zltigo @ Aug 12 2010, 17:58) Какие...   Aug 12 2010, 14:19
|- - zltigo   QUOTE (Атмег @ Aug 12 2010, 17:19) Посему...   Aug 12 2010, 14:23
- - DpInRock   Если начинаются неожиданные вещи, первым делом при...   Aug 12 2010, 14:49


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

 


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


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