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

 
 
> 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 12 2010, 13:37
Сообщение #2


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

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



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


Стеки организованы так: по 0х2200 0000 лежит стек FIQ, ниже стек IRQ, ниже стек Supervisor. "Полно" - это неск Мб, судя по мэпу. Программа все время сидит в SVC, обработчик прерываний организован так: сохраняем в стек IRQ, потом переключаемся в SVC и выполняем прерывание в нем, по завершении обратно в IRQ, подтверждаем и выходим в SVC. Соответственно стек IRQ небольшой, а стека SVC большой, его должно хватить.
Нормально ли, что стек у меня в середине памяти, а над ним и до конца памяти еще отдельная секция под буферы? Просто мне показалось так удобней сделать для некэшируемых буферов.

Цитата
что значат всякие приведенные Вами цифири


Это результат выданный мне командой backtrace. В нормальном состоянии программы я по этим строчкам вижу цепочку вызовов, то есть это вроде как значения LR? Когда возникает глюк, backtrace выдает не знаю что, может он как то неправильно разбивает стек на фреймы и не может понять откуда был вызов? Но в любом случае видно что 0xe24ee004 - адрес из которого код не мог быть исполнен и не мог оттуда вызов быть.
Как от gdb получить подробную распечатку, как у Вас приведено? Не пинайте, я с gdb знаком недавно smile.gif

Цитата
Проверьте, правильно ли заполнена таблица векторов прерываний с адреса 0х00000000.


Правильно.

Вот типичный случай как выглядит:

"$cpsr" = 0x2000009b - Undefined instruction
sp 0x00000000 - sp для Undef не инициализирован, вместо обработчика беск цикл
"$lr" = 0x200020f8
"$pc" = 0x00000004


backtrace дает вот что:

#0 0x00000004 in ?? ()
#1 0x200020f8 in ISR_SPI1 () at main.c:1069
#2 0xe24ee004 in ?? ()
Backtrace stopped: frame did not save the PC

То есть из main.c:1069 как то попали в exceiption...
Как непонятно..
Dump of assembler code from 0x200020f0 to 0x20002100:
0x200020f0 <ISR_SPI1+272>: add lr, r12, #1 ; 0x1
0x200020f4 <ISR_SPI1+276>: add r2, lr, #1 ; 0x1
0x200020f8 <ISR_SPI1+280>: ldr r3, [pc, #1424] ; 0x20002690 <ISR_SPI1+1712>
0x200020fc <ISR_SPI1+284>: str r2, [r6]
End of assembler dump.

Глюк происходит редко, поэтому поставил в main.c:1069 брейкпоинт и посмотрел как оно в норме, вот так:
bt
#0 ISR_SPI1 () at main.c:1069
#1 0x00000088 in ?? ()
#2 0x20003b24 in AIC_ConfigureIT (source=<value optimized out>, mode=8, handler=0xffff) at at91lib/peripherals/aic/aic.c:61
#3 0x000007fe in ?? ()
#4 0xcc33cc32 in ?? ()
Backtrace stopped: frame did not save the PC

Тут похоже backtrace путается из-за обработчика прерываний, поэтому строчки #1-4 какие то бессмысленные. AIC_ConfigureIT из второй строки здесь вообще не вызывается, проверял, брейкпойнт на ней ставил.

Это наиболее частый случай я тут привел, а вообще то глюки возникают иногда еще до разрешения прерываний.

Цитата
1. Перетирание стека...


Смотрю по мар-файлу, неск Мб от последней переменной до начала стека

Цитата
2. Перетирание стека по причине выхода за границу массива, если есть массивы объявленные в стеке самое время посмотреть а все ли с ними в порядке.


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

Цитата
3. NULL pointer в результате которого перетирается таблица векторов, тут имеет смысл анализировать дампы только с Data/Prefetch Abort'ами - их анализ будет самым эффективным.


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

Цитата
4. Непроинициализированные поля / переменные. - очень сложная ситуация...


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

Цитата
5. сбоит SDRAM


Ситуация слабоповторяемая, то сбоит, то не сбоит. То есть запускаю определенную функцию в программе, может на 3-й раз посыпаться, может на 10-й... Плата - отладка Атмеловская. Могут на такой плате быть проблемы из-за плохой разводки? Или это больше относится к своим платам?
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
- - Атмег   Стартап я в первом посте привел, уже много раз все...   Aug 11 2010, 15:36
|- - zltigo   QUOTE Но под стек места полно и непонятно Вопрос н...   Aug 11 2010, 16:12
|- - defunct   Цитата(zltigo @ Aug 11 2010, 19:12) Вот, ...   Aug 12 2010, 01:16
|- - zltigo   QUOTE (defunct @ Aug 12 2010, 04:16) но п...   Aug 12 2010, 05:33
|- - defunct   Цитата(zltigo @ Aug 12 2010, 08:33) Это т...   Aug 16 2010, 02:34
|- - 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
|- - 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 - 12:32
Рейтинг@Mail.ru


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