Сен 072023
 

esp32 Решение ошибки медитации гуру

Guru Meditation

  • Этот раздел будет напечатан наGuru Meditation Error: Core panic'edПричины ошибок в скобках будут объяснены одна за другой.

IllegalInstruction

Это исключение ЦП означает, что текущая выполняемая инструкция не является допустимой. Распространенные причины этой ошибки:

  • Функция задачи в FreeRTOS вернулась. В FreeRTOS, если вы хотите завершить функцию задачи, вам нужно вызватьvTaskDelete()Функция освобождает ресурсы текущей задачи вместо прямого возврата.
  • Не удается загрузить следующую инструкцию из SPI Flash, обычно это происходит:
    1. Прикладная программа перенастраивает контакты SPI Flash на другие функции (такие как GPIO, UART и т. Д.). Для получения подробной информации о выводах SPI Flash, пожалуйста, обратитесь к руководству по проектированию оборудования и спецификации микросхемы / модуля.
    2. Некоторые внешние устройства случайно подключаются к контактам SPI Flash, что мешает обмену данными между ESP32 и SPI Flash.

InstrFetchProhibited

Это исключение ЦП означает, что ЦП не может загрузить инструкцию, потому что адрес инструкции не находится в допустимой области IRAM или IROM.

Обычно это означает, что в коде вызывается указатель функции, который не указывает на действительный блок кода. В этом случае вы можете проверитьPC(Программный счетчик) значение регистра и сделайте дальнейшее суждение: если это 0 или другое недопустимое значение (то есть, если оно не0x4xxxxxxx Обстоятельства) подтверждается, что это действительно причина.

Если указатель ПК указывает на недопустимую область в большом масштабе, возможная причина дамп памятиПлохой контакт на булавкеИ другие причины.

Для получения подробной информации вы можете проверить карту esp32 ниже, чтобы определить положение указателя компьютера (не ограничиваясь этим разделом).

LoadProhibited, StoreProhibited

Этот тип исключения ЦП возникает, когда приложение пытается прочитать или записать в недопустимую область памяти. Такие недопустимые адреса памяти могут быть сброшены в регистрEXCVADDR Нашел в. Если адрес равен нулю, это обычно означает, что приложение пытается разыменоватьNULLуказатель. Если адрес близок к нулю, это обычно означает, что приложение пытается получить доступ к члену структуры, но указатель структурыNULL, Если адрес является другим недопустимым значением (не в0x3fxxxxxx0x6xxxxxxx В пределах диапазона) это может означать, что указатель, используемый для доступа к данным, не инициализирован или поврежден.

IntegerDivideByZero

Приложение пыталось разделить целое число на ноль.

LoadStoreAlignment

Ячейка памяти, которую приложение пытается читать / писать, не соответствует требованиям к размеру с выравниванием по байтам для инструкций загрузки / сохранения. Например, 32-разрядная инструкция загрузки может обращаться только к 4-разрядным адресам памяти, в то время как 16-разрядная инструкция загрузки может обращаться только к 2-байтовый адрес памяти с выравниванием.

LoadStoreError

Приложение пытается выполнить 8-битные или 16-битные операции загрузки / сохранения из области памяти, которая поддерживает только 32-битную загрузку / сохранение, например, разыменование области памяти команд.char* Указатель вызовет такую ​​ошибку.

Unhandled debug exception

Обычно за этим следует сообщение:

Debug exception reason: Stack canary watchpoint triggered (task_name)

Эта ошибка указывает на то, что позиция, записанная приложением, находится за концом стека задач имя_задачи. Обратите внимание, что эта ошибка не запускается каждый раз при переполнении стека. Задача может обойти канарейку стека (stack canary) для доступа к стеку, в этом случае точка мониторинга не будет запущена.

Interrupt wdt timeout on CPU0 / CPU1

Это указывает на то, что истекло время ожидания сторожевого таймера прерывания.

Cache disabled but cached memory region accessed

@ С этой проблемой сталкивались многие люди, особенно здесь, чтобы подвести итог, эта часть контента благодарна Чжану, которому неудобно раскрывать свое имя, за его помощь

Причина этой проблемы в том, что во время отключения кеша (например, при использовании spi_flash API для чтения / записи / стирания / отображения SPI Flash) возникает прерывание IRAM-Safe, и программа прерывания обращается к ресурсам флэш-памяти. Обычно это происходит, когда обработчик прерывания вызывает программу во флэш-памяти и ссылается на константы во флэш-памяти. Стоит отметить, что при использовании в обработчике прерыванияdouble Переменная типа из-заdouble Реализация операции переменной типаПрограммная реализацияДа, поэтому часть реализации также хранится во флэш-памяти (например, операции приведения).
Решение:

  1. Добавить к функции, доступ к которой осуществляется в прерыванииIRAM_ATTRМодификатор
  2. Добавить к константе, доступ к которой осуществляется в прерыванииDRAM_ATTR Модификатор
  3. Не используется в обработчике прерыванияdouble Тип операция
  • нужно знать:
    1. Это исключение возникает только в прерывании IRAM-Safe, то есть при использованииESP_INTR_FLAG_IRAMЗарегистрированный обработчик прерывания.
    2. Это исключение будет возникать только при отключении кеша, поэтому оно не произойдет, если кеш не отключен, другими словами, исключение является случайным.
    3. Компилятор может поместить некоторые переменные, которые не будут изменены, в раздел .rodata, даже если программист не добавит модификатор const. Для приложений ESP32 .rodata означает, что деталь находится во флэш-памяти. Для строковых переменных эту ситуацию легко обнаружить, но для некоторых констант обнаружить не так просто. Например, следующая ситуация
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; 
  • 1

Здесь определяется массив указателей TG.Элемент массива является первым адресом регистра двух аппаратных таймеров 0 и 1. Элемент массива указателей не будет изменен, поэтому он будет помещен в .rodata компилятором. В это время TG работает в прерывании от таймера, и это прерывание происходит во время запретного периода кеширования, тогда ЦП генерирует исключение.

  • Навыки отладки проблемы
  1. Когда ЦП выдает этот тип исключения, обычно местоположение исключения является местоположением ошибки, и вам нужно внимательно изучить
 Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed) Core 1 register dump: PC : 0x4011b808 PS : 0x00060034 A0 : 0x8008c664 A1 : 0x3ffbeca0 0x4011b808: __fixunsdfdi at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libgcc/config/xtensa/ieee754-df.S:2041 A2 : 0x0099fd28 A3 : 0x00000000 A4 : 0x3ffbf6a0 A5 : 0x3f7909f1 A6 : 0x00000000 A7 : 0x00013ffc A8 : 0x80086136 A9 : 0x3ffbec80 A10 : 0xfffffffc A11 : 0x40ddd57f A12 : 0x000007fe A13 : 0x00000000 A14 : 0x65580000 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x00000007 EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000 Core 1 was running in ISR context: EPC1 : 0x40086914 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x4011b808 0x40086914: spi_flash_enable_interrupts_caches_and_other_cpu at /home/chenzhengwei/esp/esp-idf/components/spi_flash/cache_utils.c:147 0x4011b808: __fixunsdfdi at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libgcc/config/xtensa/ieee754-df.S:2041 Backtrace: 0x4011b808:0x3ffbeca0 0x4008c661:0x3ffbecd0 0x4008c69d:0x3ffbecf0 0x400857e5:0x3ffbed10 0x40086911:0x3ffd0970 0x40086cc9:0x3ffd0990 0x40117789:0x3ffd09e0 0x4011785e:0x3ffd0a10 0x401179ea:0x3ffd0a30 0x40116c51:0x3ffd0aa0 0x40117109:0x3ffd0b20 0x40116729:0x3ffd0b90 0x40105c36:0x3ffd0bd0 0x401057d7:0x3ffd0c10 0x401058ce:0x3ffd0c40 0x4008dfb5:0x3ffd0c90 0x4011b808: __fixunsdfdi at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libgcc/config/xtensa/ieee754-df.S:2041 0x4008c661: gpio_isr_loop at /home/chenzhengwei/esp/esp-idf/components/driver/gpio.c:433 0x4008c69d: gpio_intr_service at /home/chenzhengwei/esp/esp-idf/components/driver/gpio.c:433 0x400857e5: _xt_lowint1 at /home/chenzhengwei/esp/esp-idf/components/freertos/xtensa_vectors.S:1154 0x40086911: spi_flash_enable_interrupts_caches_and_other_cpu at /home/chenzhengwei/esp/esp-idf/components/spi_flash/cache_utils.c:147 ... 

В этом примере место возникновения исключения —0x4011b808, вот__fixunssfdiМесто хранения функции, и это место находится во внешней памяти (см. Раздел 1.3.3 esp32_technical_reference_manual). Эта функция используется для преобразования числа с плавающей запятой в 64-битное целое число без знака, что означает, что обработчик прерывания используетdouble Тип операции приведения данных. Эта операция не разрешена, когда кеш отключен.

  1. Если вы не знаете, находится ли переменная в разделе .data / .bss или .rodata, вы можете использовать команду readelf для просмотра сведений о символах в .elf
# Перезаписать таблицу символов в build / empty-project.elf в файл empty-project.out readelf -a build/empty-project.elf > empty-project.out ​​​​​​​

Используйте команду readelf для извлечения таблицы символов в файле elf. Чтобы узнать, как просмотреть таблицу символов, обратитесь к структуре хранения переменных языка C. С помощью таблицы символов вы можете точно увидеть место хранения и размер каждой переменной и функции. С помощью этой информации вы можете проверить, находятся ли переменные и функции, используемые в обработчике прерываний IRAM-Safe, во флэш-памяти.

Понравилось? Поделитесь:

:

Sorry, the comment form is closed at this time.