Вначале пишешь (вообще по LR, дальше исключительно для одептов оссемблира): Вообще для AT91SAM7 всё, но переделать под другой ARM понятно как.
При сбое распечатывается в UART регистры и кусок стека (где видны адреса возвратов
при желании, локальные переменыне и т.п.), потом дцать раз мигает красной лампочкой
и перезапускается. Соответственно если какие проблемы: комп подоткнули и записали.
Разбирать прибор и с отладчиком ковыряться не нужно. Ну там же бутлоадер, чтоб через
уарт новую версию записать, если что.
.arm
.text
.global _exit
.section .vectors, "ax"
ldr pc, =_start /* 0x00 Reset */
ldr pc, =UNDEF /* 0x04 Undefined Instruction */
ldr pc, =(AT91C_IFLASH_PAGE_SIZE*START_PAGE +4) /* 0x08 Software Interrupt */
ldr pc, =ABORT /* 0x0C Prefetch Abort */
ldr pc, =DABORT /* 0x10 Data Abort */
nop /* 0x14 reserved */
ldr pc, =IRQ /* 0x18 IRQ */
/* 0x1c FIQ */
/* ldr pc, [r12, #AIC_FVR] */ /* подтверждение/снятие запроса, чтение вектора AIC */
ldr pc, [pc, #-0xf20] /* see datasheet! */
ldr pc, =bexit /* 0x20 _exit(code) */
b startboot /* 0x24 call bootloader */
/* unhandled interrupts -- call _exit(code), code must be defined in exits.h */
bexit:
stmfd sp!, {r0-r12} /* TODO... */
b rpush
ABORT:
stmfd sp!, {r0-r12}
mov r0, #EX_CODE_ABORT
b rpush
DABORT:
stmfd sp!, {r0-r12}
mov r0, #EX_DATA_ABORT
b rpush
UNDEF:
stmfd sp!, {r0-r12}
mov r0, #EX_UNDEF
/* stack: [trap, pc+4, SP, *] (flags, lr, r0-r12) */
rpush:
mov r7, SP
mov r1, lr
mrs r6, SPSR
msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT
mov r2, SP
mov SP, r7
stmfd sp!, {r6, lr}
mov r3, sp
.global dump
b dump
static void nhex(uint8_t v)
{
const char *dhex="0123456789abcdef";
putch(dhex[v&0x0f]);
}
static void bhex(uint8_t v)
{
nhex((v>>4)&0x0f), nhex(v&0xf);
}
static void whex(uint32_t v)
{
bhex(v>>24), bhex((v>>16)&0xff), bhex((v>>8)&0xff), bhex(v&0xff);
}
extern char _ram_top[];
void dump(unsigned trap, const unsigned *pc, const unsigned *sp, const unsigned *regs)
{
unsigned n;
uart_init();
puts("\n\r\n*** TRAP "); bhex(trap);
puts(" at "); whex((unsigned)pc);
puts(" CPSR:"); whex(*regs++);
puts(" lr:"); whex(*regs++);
puts("\nAASR:"); whex(AT91C_BASE_MC->MC_AASR);
puts(" ASR:"); whex(AT91C_BASE_MC->MC_ASR);
putch('\r'); putch('\n');
for (n=0; n<=12; n++) {
putch('r'); nhex(n); putch(':');
whex(*regs++);
if (n==3 || n==7) {
putch('\r'); putch('\n');
} else {
putch(' ');
}
}
puts("\nsp="); whex((unsigned)sp);
if (((unsigned)sp & 0x3) == 0) {
putch(':');
for (n=0; n<128; n++) {
if ((char*)sp > (char*)_ram_top-4) break;
putch(' '); whex(*sp++);
}
}
putch('\r'); putch('\n');
flush();
_exit(trap);
}