algorithm fault recovery

master
Clyne 4 years ago
parent f84b4b119d
commit 0350992141

@ -446,20 +446,27 @@ void conversion_unprivileged_main()
if (elf_entry) { if (elf_entry) {
if (!MSG_FOR_MEASURE(message)) { if (!MSG_FOR_MEASURE(message)) {
// Remember the stack pointer in case the algorithm messes things up.
uint32_t sp;
asm("mov %0, sp" : "=r" (sp));
samples = elf_entry(samples, size); samples = elf_entry(samples, size);
asm("mov sp, %0" :: "r" (sp));
} else { } else {
asm("eor r0, r0; svc 2"); // start measurement uint32_t sp;
asm("mov %0, sp; eor r0, r0; svc 2" : "=r" (sp)); // start measurement
samples = elf_entry(samples, size); samples = elf_entry(samples, size);
asm("mov r0, #1; svc 2"); // stop measurement asm("mov r0, #1; svc 2; mov sp, %0" :: "r" (sp)); // stop measurement
} }
} }
if (samples != nullptr) {
if (MSG_FOR_FIRST(message)) if (MSG_FOR_FIRST(message))
samplesOut.modify(samples, size); samplesOut.modify(samples, size);
else else
samplesOut.midmodify(samples, size); samplesOut.midmodify(samples, size);
} }
} }
}
} }
void mpu_setup() void mpu_setup()
@ -509,12 +516,8 @@ void mpu_setup()
void conversion_abort() void conversion_abort()
{ {
elf_entry = nullptr; elf_entry = nullptr;
DAC::stop(0);
ADC::stop();
EM.add(Error::ConversionAborted); EM.add(Error::ConversionAborted);
run_status = RunStatus::Recovering;
chMBReset(&conversionMB);
run_status = RunStatus::Idle;
} }
void signal_operate(adcsample_t *buffer, size_t) void signal_operate(adcsample_t *buffer, size_t)
@ -524,6 +527,7 @@ void signal_operate(adcsample_t *buffer, size_t)
if (chMBGetUsedCountI(&conversionMB) > 1) { if (chMBGetUsedCountI(&conversionMB) > 1) {
chSysUnlockFromISR(); chSysUnlockFromISR();
conversion_abort(); conversion_abort();
chMBReset(&conversionMB);
} else { } else {
if (buffer == samplesIn.data()) { if (buffer == samplesIn.data()) {
samplesIn.setModified(); samplesIn.setModified();
@ -622,16 +626,31 @@ void port_syscall(struct port_extctx *ctxp, uint32_t n)
__attribute__((naked)) __attribute__((naked))
void MemManage_Handler() void MemManage_Handler()
{ {
while (1); // 1. Get the stack pointer.
uint32_t *stack;
uint32_t lr;
asm("\
tst lr, #4; \
ite eq; \
mrseq %0, msp; \
mrsne %0, psp; \
mov %1, lr; \
" : "=r" (stack), "=r" (lr));
// 2. Recover from the fault:
conversion_abort(); // Unload algorithm and indicate error.
stack[0] = 0; // Force algo. to return nullptr (DAC buffer will not update).
stack[6] = stack[5]; // Skip remainder of algo. code.
stack[7] |= (1 << 24); // Ensure Thumb mode stays enabled.
// 3. Return.
asm("mov lr, %0; bx lr" :: "r" (lr));
} }
__attribute__((naked)) __attribute__((naked))
void HardFault_Handler() void HardFault_Handler()
{ {
// Below not working (yet) // Get the stack pointer.
while (1);
// 1. Get the stack pointer
uint32_t *stack; uint32_t *stack;
uint32_t lr; uint32_t lr;
asm("\ asm("\
@ -642,20 +661,11 @@ void HardFault_Handler()
mov %1, lr; \ mov %1, lr; \
" : "=r" (stack), "=r" (lr)); " : "=r" (stack), "=r" (lr));
// 2. Only attempt to recover from failed algorithm code // If coming from the algorithm, attempt to recover; otherwise, give up.
if ((lr & 4) == 0 || run_status != RunStatus::Running) if (run_status != RunStatus::Running && (lr & 4) != 0)
while (1); MemManage_Handler();
// 3. Post the failure and unload algorithm while (1);
elf_entry = nullptr;
EM.add(Error::ConversionAborted);
run_status = RunStatus::Recovering;
// 4. Make this exception return to point after algorithm exec.
stack[6] = stack[5];
stack[7] |= (1 << 24); // Ensure Thumb mode stays enabled
asm("mov lr, %0; bx lr" :: "r" (lr));
} }
} // extern "C" } // extern "C"

Loading…
Cancel
Save