Имеется отладочная плата 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
Буду благодарен любым соображениям! Подскажите хоть что нибудь. Может кто натолкнет на мысль.