Исключение AVR32: ошибка данных шины

Недавно я столкнулся со странным поведением во встроенном программном обеспечении.

Что я получил: Запуск 32-битного контроллера AVR32, запуск программы с внешней SDRAM, так как размер файла слишком велик, чтобы запускать его непосредственно со флэш-памяти микроконтроллера. Из-за карты физической памяти области памяти разделены между:

стек (начало 0x1000, длина 0xF000) ( < 0x1000 защищено MPU)

EBI SDRAM (начало 0xD0000000, длина 0x00400000).


Что происходит: К сожалению, я получил исключение, которое невозможно воспроизвести. Глядя на мою заданную трассировку стека, происходит следующее нерегулярное событие:

Имя: извлечение данных об ошибке шины - Источник события: Шина данных - Сохраненный адрес возврата: Первая незавершенная инструкция

Кроме того, указатель стека имеет допустимое значение, в то время как адрес, где происходит исключение (последняя точка входа для извлечения инструкций), указывает на нирвану памяти (например, 0x496e6372, что-то около 0x5..., 0x6....). Я предполагаю, что это должна быть "Первая незавершенная инструкция", о которой идет речь в руководстве. Однако строка в моем исходном коде всегда одна и та же: доступ к функции-члену из массива данных через указатель.

      if(mSomeArray[i])
      {
         mSomeArray[i]->someFunction(); <-- Crash
      }

Дело в том, что при добавлении или удалении другого исходного кода событие исчезает и возвращается снова.


О чем я думал: что-то портит мою память (отображение). Какие ошибки возможны для этого?

  • Переполнение буфера?
  • Контроллер SDRAM может быть отключен, поэтому он теряет некоторые данные. Это не невозможно, а скорее невероятно
  • Стек достаточно большой, я уже проверил это с водяным знаком
  • Скорость шины данных и часы AVR установлены правильно

Как решить это: Больше утверждать? К сожалению, я не могу отладить это с помощью AVRStudio. Кто-нибудь намек или идея? Или я что-то упускаю очевидное?


Редактировать:

Упомянутые подходы от пользователей:

  • Проверьте адреса указателя функции и записи массива
  • Перезапись стекового массива
  • Не правильно написанные прерывания
  • Неинициализированные указатели
  • Проверьте доступ к массиву через i на случай аварии
  • использовать адрес обработчика исключений для несанкционированного доступа к памяти
  • использование snprintf вместо sprintf

Позднее приложение к ветке: проблема заключалась в неправильном доступе к массиву (был задан неправильный индекс) в старом программном модуле, который не имел ничего общего с моими модулями. Я обнаружил это случайно, это было любопытно, что это не появилось раньше, и мне потребовалось много времени, чтобы найти строку кода. Я отмечаю единственный ответ как правильное решение.

Спасибо всем за ваш вклад.

Берегите себя (своего программного обеспечения;))

1 ответ

Решение

Вот несколько идей:

  1. Проверьте 'i', чтобы убедиться, что оно находится в пределах массива.
  2. Проверьте адрес указателя функции, который должен быть вызван. У него должен быть адрес в SDRAM.
  3. Посмотрите, есть ли у чипа адрес обработчика исключений, к которому он перейдет, когда получит доступ к недопустимой памяти. Как только вы там, выведите некоторые отладочные данные
  4. Если ваш отладчик позволяет, установите точку останова на someFunction(), когда она написана. Это перехватит какую-то другую функцию, когда перезапишет указатель на функцию.
Другие вопросы по тегам