|
|
  |
Прошу помощи с STM32F051, Периодическое сваливание в HardFault |
|
|
|
Aug 8 2014, 18:41
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Отлаживаю дивайс на STM32F051. интенсивно используется DMA - все каналы. Периодически (1 раз в 1- 4 часа) происходит HardFault.Ввел обработчик ХардФаулт из Definitive Guide, получил листинг регистров. Не могу полноценно осознать результаты. Судя по содержимому PC, инструкция, вызвавшая HardFault была расположена в RAM. Непонятно. Указатели на функции не использую. Во вложении кусочек скриншота с регистрами.
Эскизы прикрепленных изображений
|
|
|
|
|
Aug 8 2014, 19:25
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Цитата(adnega @ Aug 9 2014, 01:22)  Стека точно хватает? Вопрос интересный... Яровские установки = default
|
|
|
|
|
Aug 9 2014, 10:18
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Цитата(ViKo @ Aug 9 2014, 16:06)  Причина HardFault описана в Fault регистрах. В той же книге они описаны. Я всегда сначала там роюсь, а потом адрес, с которого улетел, смотрю. Если Вы имеете в виду регистры CFSR и HFSR то в M0 их нет, только в M3/M4. А адрес с которого улетело, есть адрес в области RAM. Программа же расположена во FLASH, и не использует никаких трюков с выполнением из RAM и указателей на функции. Отсюда мой ступор.
|
|
|
|
|
Aug 9 2014, 11:17
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(nanorobot @ Aug 8 2014, 20:41)  Отлаживаю дивайс на STM32F051. интенсивно используется DMA - все каналы. Периодически (1 раз в 1- 4 часа) происходит HardFault.Ввел обработчик ХардФаулт из Definitive Guide, получил листинг регистров. Не могу полноценно осознать результаты. Судя по содержимому PC, инструкция, вызвавшая HardFault была расположена в RAM. Непонятно. Указатели на функции не использую. Во вложении кусочек скриншота с регистрами. Явно в какой-то процедуре затирается стек (LR странный), и при возврате из нее процессор попадает в никуда. Стек затирается видимо ввиду нарушения границ какой-то локальной переменной (массива), объявленной в процедуре. Почему так редко? Ну может наступает некое условие раз в час, например, особое время суток в часах реального времени. А может происходит неверная инициализация DMA, который влазит на чужую область памяти. Например, принимается пакет извне (через UART и т.п.), пакет содержит поле длины, эта длина оказывается изредка неправильной, проверка границ не происходит, DMA грузится слишком "длинно" и влазит в чужой огород. Если глянуть на регистры R1 и R2, можно также увидеть, что они указывают в RAM. Возможно по их значениям и карте памяти для секции RAM можно определить, какие переменные там есть, и, таким образом, по имени переменных и по тексту кода "вычислить" процедуру, которая ломает стек. Да и R3 содержит 0x4B0 = 1200 - больно круглое число, чтобы быть случайным. Это указывает на какой-то счетчик (например, из for ()). Вот гляньте, нет ли в коде процедуры, которая чего-то там прописывает с этой длиной. Если используется динамическое размещение памяти, то в результате длительной работы может возникнуть сильная фрагментация кучи, с которой менеджер не справляется (кто сказал, что не бывает ошибок в библиотеках?) и выделяет память ошибочно. Попробуйте кучу увеличить. Кстати, если куча в собственном коде явно и не используется, возможно она используется библиотеками. Например, для стандарта --C99 локальная переменная-массив может быть переменной длины, зависимой от параметра функции. Это реализуется, к сожалению, не смещением указателя стека, чтобы разместить такой массив в нем, а вызовом malloc/free.
Сообщение отредактировал KnightIgor - Aug 9 2014, 11:21
|
|
|
|
|
Aug 9 2014, 11:23
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Цитата(KnightIgor @ Aug 9 2014, 17:17)  ... Благодарю за развернутый ответ. Буду копать в указанных направлениях.
Сообщение отредактировал IgorKossak - Aug 9 2014, 18:29
Причина редактирования: избыточное цитирование
|
|
|
|
|
Aug 9 2014, 15:25
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(nanorobot @ Aug 9 2014, 16:18)  Если Вы имеете в виду регистры CFSR и HFSR то в M0 их нет, только в M3/M4. А адрес с которого улетело, есть адрес в области RAM. Программа же расположена во FLASH, и не использует никаких трюков с выполнением из RAM и указателей на функции. Отсюда мой ступор. Это и не обязательно. Cortex может сохранять адреса возврата из функций на стеке. Если Вы его каким-либо образом разрушаете, то при попытке возврата выполнение может улететь куда угодно (или сразу в fault). Цитата(KnightIgor @ Aug 9 2014, 17:17)  Явно в какой-то процедуре затирается стек (LR странный) Там не только LR странный, но и PSR к примеру. Сдаётся мне, что это никакое не содержимое регистров в момент fault-a, а просто ТС привёл нам мусор.  Вот например, что выдаёт мой обработчик критических ошибок при возникновении BUS FAULT: неточная ошибка при обращении к данным (imprecise data bus error) (ловушка 123):
Всё чётко видно где произошло, при каких регистрах и стеке.
|
|
|
|
|
Aug 9 2014, 16:44
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Цитата(jcxz @ Aug 9 2014, 21:25)  ... Если быть точным, это не регистры, а их копии лежащие в верхушке стека, т.е. их состояния на момент HardFault. Если я намеренно привожу ситуацию к HardFault - все регистры (их копии в стеке) выглядят вполне пристойно.
Сообщение отредактировал IgorKossak - Aug 9 2014, 18:30
Причина редактирования: избыточное цитирование
|
|
|
|
|
Aug 9 2014, 18:35
|
Местный
  
Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503

|
Цитата(jcxz @ Aug 10 2014, 00:22)  Пристойно? И 24й бит PSR тоже? То что Вы приводите не имеет никакого отношения к регистрам либо "их копиям в верхушке стека". Извините, если что не так. Вы меня неправильно поняли. "Пристойно" они выглядят не в приведенном случае, а в том, когда я программно создаю ситуацию HardFault от кнопки. а текущий случай не укладывается ни в какие рамки. Возможно ситуация осложнена модификацией стека, или чем либо еще, но она именно такова.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|