обработка исключений микрочипа
-
27-10-2019 - |
Вопрос
При запуске моей программы на устройстве microchip ICD3 обработка исключений выглядит странно.Программа остановит ответ при возникновении исключения.Проверяя код, я заметил, что default-general-exception-handler.c создаст бесконечный цикл.Это действительно сбивает с толку, потому что я не могу знать, где возникает ошибка и в чем причина.Означает ли это, что Microchip не поддерживает обработку исключений?Или есть способ прочитать сообщение об ошибке?
бесконечный цикл:
--- \home\c11067\work\C32\builds\pic32-microchip-release-1.12-20101221-rc2-20101221\pic32-libs\libc\stubs\default-general-exception-handler.c
9D00DD28 1000FFFF beq zero,zero,0x9d00dd28
9D00DD2C 00000000 nop
Определяя _general_exception_handler, это работает!
// declared static in case exception condition would prevent
// auto variable being created
static enum {
EXCEP_IRQ = 0, // interrupt
EXCEP_AdEL = 4, // address error exception (load or ifetch)
EXCEP_AdES, // address error exception (store)
EXCEP_IBE, // bus error (ifetch)
EXCEP_DBE, // bus error (load/store)
EXCEP_Sys, // syscall
EXCEP_Bp, // breakpoint
EXCEP_RI, // reserved instruction
EXCEP_CpU, // coprocessor unusable
EXCEP_Overflow, // arithmetic overflow
EXCEP_Trap, // trap (possible divide by zero)
EXCEP_IS1 = 16, // implementation specfic 1
EXCEP_CEU, // CorExtend Unuseable
EXCEP_C2E // coprocessor 2
} _excep_code;
static unsigned int _epc_code;
static unsigned int _excep_addr;
// this function overrides the normal _weak_ generic handler
void _general_exception_handler(void)
{
asm volatile("mfc0 %0,$13" : "=r" (_excep_code));
asm volatile("mfc0 %0,$14" : "=r" (_excep_addr));
_excep_code = (_excep_code & 0x0000007C) >> 2;
while (1) {
// Examine _excep_code to identify the type of exception
// Examine _excep_addr to find the address that caused the exception
}
}
Решение
На большинстве микроконтроллеров нет никакого кода, кроме того, что вы туда вложили.В большинстве случаев, если возникает исключение, а вы не определили для него обработчик, процессор понятия не будет иметь, как создать диалоговое окно "Извините, произошла системная ошибка".Использования двух байтов для инструкции "переход к себе" достаточно, чтобы получить предсказуемый ответ на исключение;без особых знаний о каком-либо лучшем способе действий переход на себя или принудительный сброс, вероятно, будет таким же хорошим ответом, как и все остальное.
PS-Некоторые компиляторы для различных платформ будут опускать векторы для неиспользуемых прерываний или исключений;если такие исключения возникают неожиданно, могут произойти странные вещи.Некоторые компиляторы создадут код, который вызовет немедленный сброс (обратите внимание, что если включен сторожевой таймер, переход к себе в конечном итоге приведет к сбросу).Некоторые компиляторы генерируют немедленный возврат из прерывания (который на некоторых процессорах может быть бесполезен, а на других может вызвать плохое поведение).Моим любимым шаблоном было бы заставить все неиспользуемые прерывания вызывать (не ветвление) метку UnexpectedInterrupt , которая в отсутствие какого-либо явного определения будет указывать на инструкцию перехода к себе.Если кто-то это сделает, обработчик UnexpectedInterrupt может открыть стек и записать, какой тип неожиданного прерывания произошел.Однако я не видел такого шаблона за пределами моих собственных таблиц векторов прерываний, созданных вручную.
Другие советы
Просто в качестве предупреждения для дальнейшей отладки исключений PIC32 коды исключений и все биты в регистре 'CAUSE' (значение, которое вы считываете в свою переменную _excep_code перед удалением всех остальных битов) определены в:
Справочное руководство по семейству PIC32, Раздел 2.12.9 Регистр ПРИЧИН http://ww1.microchip.com/downloads/en/DeviceDoc/61113C.pdf