|
Undefined instruction, Data Abort, SWI - помогите локализовать проблему! |
|
|
|
Aug 10 2010, 18:23
|
Частый гость
 
Группа: Участник
Сообщений: 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
Буду благодарен любым соображениям! Подскажите хоть что нибудь. Может кто натолкнет на мысль.
|
|
|
|
|
 |
Ответов
|
Aug 12 2010, 13:37
|
Частый гость
 
Группа: Участник
Сообщений: 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 знаком недавно  Цитата Проверьте, правильно ли заполнена таблица векторов прерываний с адреса 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-й... Плата - отладка Атмеловская. Могут на такой плате быть проблемы из-за плохой разводки? Или это больше относится к своим платам?
|
|
|
|
|
Aug 12 2010, 13:58
|

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

|
QUOTE (Атмег @ Aug 12 2010, 16:37)  backtrace выдает не знаю что.. Я тоже не знаю  QUOTE Как от gdb получить подробную распечатку, как у Вас приведено? Не пинайте, я с gdb знаком недавно  Не знаю, эта моя собственная распечатка при вылете, как уже писал, в аварийную консоль. Отладчиками пользуюсь крайне редко, ибо самое интересное случается за тысячи километров на объектах, а там никаких подключенных JTAG адаптеров, отладчиков, компиляторов и т.д. просто нет не было и не будет. QUOTE (Атмег @ Aug 12 2010, 16:37)  Стеки организованы так: по 0х2200 0000 лежит стек FIQ, ниже стек IRQ, ниже стек Supervisor. "Полно" - это неск Мб, судя по мэпу. Какие такие "Mб", если стеки FIQ и IRQ черным по белому записаны у Вас по 24 слова!!! Да и инициализированы только три стека.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
Сообщений в этой теме
Атмег 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 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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|