Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обработка Faults на Cortex-Mx
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
Arlleex
Интересует, как коллеги обрабатывают все Faults на микроконтроллерах Cortex-Mx.
Я про NMI, Hard, MemManage, Bus, Usage, SVCall, Debug Monitor, PendSV, Systick.
С SVCall, Debug Monitor, Systick все понятно, с PendSV в принципе тоже.

А что делаете с тяжелыми отказами, отказами шины и прочими? Сейчас я просто вывожу состояние нужных регистров и стек. Как правило, если где-то программа падает, я узнаю об этом на этапе отладки. Но ведь может быть такое, что устройство уже стоит у заказчика и частично подлежит отладке на объектах. И оно должно продолжить функционирование. Как обрабатывать тогда ошибки? Перезагрузка по WDT? Или все-таки грамотный обработчик исключения должен понять природу ошибки и попытаться исправить ее? Если да, то каким образом? Сейчас мне видится вариант с сохранением лога событий в памяти (допустим, SD карты) и перезагрузкой МК. Пока что больше хорошего развития событий не знаю. Отсюда и предположения для обсуждения:
1. Должны ли существовать обработчики исключения CPU, связанные с аварийным событием (промах по памяти, тяжелый отказ, например, и т.д.) только на момент разработки и отладки ПО и выявлять все проблемы именно на этапе разработки, а при этом в боевой работе устройство ни коим образом не должно ловить такие Fault-ы?
2. Пункт 1 влечет за собой следующий вопрос: если в боевом коде обработчики должны быть предусмотрены (я подразумеваю, что все-таки это именно так) - как правильно строить архитектуру обработки ошибок? Что должен делать код в обработчике, кроме как сообщать программисту (каким-то образом) о состоянии регистров?
3. Вопрос больше из разряда "как больше нравится" - код обработчика на ассемблере или на Си?
То есть, как вы поняли, вопрос в грамотном управлении ходом событий для обеспечения надежности и безотказности устройства.

Я задаю себе вслух вопрос: "причину отказа я установлю, но что мне с этим делать дальше?".
Вопрос не философский и хотелось бы узнать, как коллеги на реальной практике применяют обработчики исключений CPU для обеспечения надежности ПО и устройства в целом от сбоев. Только прошу, не хотелось бы услышать ответ "на столе отлаживать надо". Мы отлаживаем. И работает годами. Но бывают (уверен, у всех) непредвиденные случаи, когда устройство может "выстрелить себе в колено", не важно по вашей вине или вине заказчика, и нужно с этим разбираться.
Также был бы благодарен, если на эту тему существуют мануалы, но я об этом не знаю - будьте добры, поделитесь информацией rolleyes.gif
aaarrr
По-моему, так:
1. Должны быть и в релизе.
2. Регистры процессора, Fault Status'ы, содержимое стека сохранить в памяти, перезапустить процессор и
записать/отправить оповещение в штатном режиме.
3. Можно обойтись без ассемблера, это уже дело вкуса.
ViKo
А вот, скажем, выйти из той функции, которая сбойнула, и продолжить работу дальше. И зафиксировать сбой, по возможности, и передать.
aaarrr
Цитата(ViKo @ Jul 7 2018, 21:28) *
А вот, скажем, выйти из той функции, которая сбойнула, и продолжить работу дальше. И зафиксировать сбой, по возможности, и передать.

1. Каким образом выйти?
2. А если дальше все пойдет еще хуже?

Безопаснее рестартовать, сохранив информацию о сбое.
ViKo
Цитата(aaarrr @ Jul 7 2018, 21:32) *
2. А если дальше все пойдет еще хуже?
Безопаснее рестартовать, сохранив информацию о сбое.

Надо думать, все, что выполнялось до функции, работало исправно. А после - как повезет. Так же и сброс не всегда можно допустить, мало ли, какой процесс обслуживается.
jcxz
Цитата(Arlleex @ Jul 7 2018, 18:39) *
А что делаете с тяжелыми отказами, отказами шины и прочими?

Определил для себя понятие "критическая ошибка". Это такая ошибка, возникновение которой не предусмотрено при создании программы, неизвестно "что делать?" при её возникновении и невозможно продолжать штатное функционирование устройства.
Такие ошибки у меня могут возбуждаться как аппаратными событиями (исключение от MPU при попытке недопустимого доступа к памяти, всяческие прочие HF (и Bus fault-ы и user fault-ы - для всех у меня делается эскалация до Hard Fault с общим обработчиком HF)); так могут вызываться и программно (набор функций trap(...)) если какая-то часть программы обнаружила недопустимое состояние (для каждого программного модуля/драйвера - свой класс возбуждаемых trap-ов). Обработчик trap() у меня висит на SVC.
При возникновении любого типа критической ошибки я делаю:
Защёлкиваю тип и ID критической ошибки состояние выполнения (регистры CPU, N слов от вершины стека), для программного trap() также защёлкиваю аргументы вызова. Для некоторых типов критических ошибок (например: неожиданное прерывание (которого не должно быть)) защёлкиваю состояние выполнения (регистры/стек) не текущего контекста, а прерванного. Далее - делаю базовый инит (выкл. всей периферии, останов DMA, инит базовой периферии - MPU и пр.) и дальше - в зависимости от состояния соответствующего ключа компиляции:
1) компиляция DEBUG: переход устройства в спец.режим "TRAP" - инит тактирования (PLL и пр.) для этого режима (минимальные частоты), инит отладочного UART, и циклический, раз в секунду, вывод "синего экрана смерти" - периодический дамп всех защёлкнутых данных в UART в текстовом виде; устройство находится в режиме TRAP до внешнего сброса/выкл. питания, обеспечивая фиксацию состояния ошибки.
2) компиляция RELEASE: аппаратный reset устройства.
И для того и для другого случая, копирую защёлкнутую инфу в спец. область памяти, которая не будет стёрта при reset-е, снабжаю её флагом и CRC. И, если устройство имеет non-volatile память, то после штатного рестарта, после начального инита периферии, эта инфа переписывается в журнал критических сбоев в этой non-volatile памяти.

Цитата(Arlleex @ Jul 7 2018, 18:39) *
Но ведь может быть такое, что устройство уже стоит у заказчика и частично подлежит отладке на объектах. И оно должно продолжить функционирование. Как обрабатывать тогда ошибки?

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

Цитата(Arlleex @ Jul 7 2018, 18:39) *
Сейчас мне видится вариант с сохранением лога событий в памяти (допустим, SD карты) и перезагрузкой МК.

В момент ошибки у Вас устройство уже работает, куча разной периферии/DMA работают, и если при этом произошла ошибка, то в этом окружении уже опасно дальше что-то делать, иначе можно получить каскад таких сбоев. Лучше просто защёлкнуть как можно быстрее инфу об ошибке в ОЗУ и сделать начальный инит периферии к минимальному функциональному состоянию - минимуму работающей периферии необходимой для записи события ошибки в какую-то энергонезависимую память, и записать эту инфу. А уж после рестартовать опять систему к полной функциональности.

Цитата(Arlleex @ Jul 7 2018, 18:39) *
в боевой работе устройство ни коим образом не должно ловить такие Fault-ы?

Фиксация и отработка сбоев должна быть и в боевом режиме.

Цитата(Arlleex @ Jul 7 2018, 18:39) *
2. Пункт 1 влечет за собой следующий вопрос: если в боевом коде обработчики должны быть предусмотрены (я подразумеваю, что все-таки это именно так) - как правильно строить архитектуру обработки ошибок?

У меня у обработчик общий, но имеет два входа: для программного возбуждения сбоя (trap()) и для аппаратного возбуждения сбоя (все типы fault-ов).

Цитата(Arlleex @ Jul 7 2018, 18:39) *
3. Вопрос больше из разряда "как больше нравится" - код обработчика на ассемблере или на Си?

Защёлкивание всей инфы (регистры, стек, состояние CPU и пр.) у меня на асме, а "синий экран смерти" (режим работы TRAP) - на си.

Цитата(Arlleex @ Jul 7 2018, 18:39) *
Вопрос не философский и хотелось бы узнать, как коллеги на реальной практике применяют обработчики исключений CPU для обеспечения надежности ПО и устройства в целом от сбоев.

Если есть инфа, что где-то на объекте что-то сбоит, смотрим журнал критических ошибок устройства на объекте - их частота, кол-во, периодичность, какие типы и в каких местах программы и пр. Дальше смотрим листинги этой версии ПО, пытаемся воспроизвести ситуацию у себя на столе. Если не получается - снимаем сбоящее устройство и везём к себе.
Как-то так.

Цитата(ViKo @ Jul 7 2018, 21:28) *
А вот, скажем, выйти из той функции, которая сбойнула, и продолжить работу дальше. И зафиксировать сбой, по возможности, и передать.

Если причина сбоя неизвестна (а она неизвестна по определению, иначе - почему тогда Вы его не исправили ещё на этапе написания ПО? wink.gif то не то что продолжать работу дальше нельзя, можно даже просто не успеть и выйти и получить тут же следующий сбой. А может сбой уже разрушил память или нарушил взаимодействие с какой-то периферией и устройство уже не функционирует, а глючит?
aaarrr
Цитата(ViKo @ Jul 7 2018, 23:08) *
Так же и сброс не всегда можно допустить, мало ли, какой процесс обслуживается.

Вы так и не рассказали, как собираетесь выбираться из fault'а.
"Мало ли какие процессы" должны контролироваться аппаратно и/или безболезненно переживать сброс.
jcxz
Цитата(aaarrr @ Jul 7 2018, 23:48) *
Вы так и не рассказали, как собираетесь выбираться из fault'а.

Типа как известный персонаж:
Нажмите для просмотра прикрепленного файла
biggrin.gif biggrin.gif biggrin.gif
aaarrr
Цитата(jcxz @ Jul 7 2018, 23:56) *
Типа как известный персонаж...

Так оно в ряде случаев вполне возможно - вон, на ARM7 так предлагали виртуальную память строить. Но прозвучало предложение "выйти из той функции", что уже действительно на грани фантастики.
jcxz
Цитата(aaarrr @ Jul 8 2018, 00:04) *
Так оно в ряде случаев вполне возможно - вон, на ARM7 так предлагали виртуальную память строить.

Ну так fault при доступе в несуществующую память, по которому соответствующий драйвер делает переназначение страниц памяти (или ещё каким образом делает подкачку из внешнего пула) - это штатная работа диспетчера виртуальной памяти, коли таковой есть. А ТС спрашивает о критических ошибках, т.е. - событиях не предусмотренных заранее при разработке ПО.
Это может даже на одном векторе висеть, а далее эти случаи должны разделяться программно.
Arlleex
Спасибо участникам обсуждения!
Примерно так я себе это и представлял, на самом-то деле. Однако предполагал, что существует некий сводный "мануал-ритуал", в котором жесткими канонами высечены такие правила rolleyes.gif

Цитата
2) компиляция RELEASE: аппаратный reset устройства.
И для того и для другого случая, копирую защёлкнутую инфу в спец. область памяти, которая не будет стёрта при reset-е, снабжаю её флагом и CRC. И, если устройство имеет non-volatile память, то после штатного рестарта, после начального инита периферии, эта инфа переписывается в журнал критических сбоев в этой non-volatile памяти.

Ну то есть по сути в начале main()-а у Вас можно увидеть что-то наподобие:
Код
int main(void)
{
    if(GetCriticalErrorStatus() == ERROR_OCCURRED)
        WriteInfoAboutError();

    ...
}

где GetCriticalErrorStatus() - функция, которая читает флаг в ОЗУ, установленный trap()-ом или обработчиком HF. Верно?

P.S. И еще один вопрос. Если необходимо логгирование на SD-карту памяти, например. Есть ли предпочтение наличию файловой системы или безразлично? Сейчас использую с файловой системой, однако приходится держать файл открытым и через некоторое время сохранять. Но питание могут выключить в произвольное время. Так может потеряться информация о файле, поэтому я делаю дублирование файлов, и это выглядит костылем. Какие изящные программные способы логгирования вы применяете?
jcxz
Цитата(Arlleex @ Jul 10 2018, 08:14) *
где GetCriticalErrorStatus() - функция, которая читает флаг в ОЗУ, установленный trap()-ом или обработчиком HF. Верно?

Да. Читает и очищает.

Цитата(Arlleex @ Jul 10 2018, 08:14) *
Какие изящные программные способы логгирования вы применяете?

Лучше логи писать в журналы (без ФС) - оно как бы органически под это дело и подходит. Я так и делаю. Журнал у меня - это некая FIFO-структура во FLASH/FRAM, с размером элементов обычно кратным целому числу блоков записи (хотя это не обязательно). Каждый такой элемент - одна запись журнала (на одно событие). При старте ПО выполняется монтирование каждого журнала: поиск "головы", определение числа записей, проверка их валидности и т.п.
Хотя можно сделать устойчивую к сбоям свою ФС. Но это избыточно, так как ФС нужна для возможности произвольного доступа к файлам, что налагает значительные сложности в реализации. Но произвольный доступ не нужен для журналов, а значит - избыточен.

Цитата(Arlleex @ Jul 10 2018, 08:14) *
Так может потеряться информация о файле, поэтому я делаю дублирование файлов, и это выглядит костылем.

Так даже с дублированием инфа может потеряться. Ведь обычно в файловой системе при обновлении файла происходит неатомарная модификация разных областей на носителе. Вследствие чего могут возникнуть ошибки в FAT или записи каталога, которые приведут не только к порче записываемого в данный момент файла, но и других файлов (всякие cross-links and etc.).
Arlleex
Цитата(jcxz @ Jul 10 2018, 10:08) *
Лучше логи писать в журналы (без ФС) - оно как бы органически под это дело и подходит. Я так и делаю. Журнал у меня - это некая FIFO-структура во FLASH/FRAM, с размером элементов обычно кратным целому числу блоков записи (хотя это не обязательно). Каждый такой элемент - одна запись журнала (на одно событие). При старте ПО выполняется монтирование каждого журнала: поиск "головы", определение числа записей, проверка их валидности и т.п.
...

Обобщая, я пришел к выводу, что двигаюсь в правильном направлении. Думаю, больше вопросов в этом плане не возникнет не должно возникнуть, спасибо большое sm.gif
aaarrr
Цитата(Arlleex @ Jul 10 2018, 08:14) *
Если необходимо логгирование на SD-карту памяти, например. Есть ли предпочтение наличию файловой системы или безразлично? ...Но питание могут выключить в произвольное время.

Если используется SD-карта, то логично использовать файловую систему и текстовые логи - скопировать текст из файла в письмо условная "баба Нюра" сможет, а вот всякие утилиты ей совершенно ни к чему. Дублировать ничего не нужно - вероятность совпадения двух аварийных событий ничтожна.
jcxz
Цитата(aaarrr @ Jul 10 2018, 09:42) *
скопировать текст из файла в письмо условная "баба Нюра" сможет, а вот всякие утилиты ей совершенно ни к чему. Дублировать ничего не нужно - вероятность совпадения двух аварийных событий ничтожна.

Вообще-то вероятность зависит от условий эксплуатации устройства автора. Вы откуда знаете какова у него вероятность?
А если у него при подаче питания на устройство, возможен дребезг контактов? При таком включении устройство может многократно включиться/выключиться.
Или например: пришла помеха - пачка импульсов (даже испытания на помехоустойчивость проводят пачкой импульсов) - тогда устройство многократно перезагрузится.
А теперь представьте, что у него в устройстве есть журнал включений/выключений, в который устройство должно писать инфу о включениях (сразу после вкл. питания). Какова будет вероятность попадания такого рестарта на момент записи? А если таких устройств у заказчика работает тысячи и работают они режиме 24/7? Как часто в такой системе будут происходить сбои ФС с потерями данных?

ФС нужна только если эту SD должны вынимать вставлять ещё куда-то (комп, etc.). Если нет и работа с SD производится только самим устройством, то ничто не мешает ему представить некий объект на SD (FIFO-журнал из секторов) как файл через свой внешний интерфейс. Даже хранить в таком журнале записи в бинарном виде (как удобнее для работы с ними), а выдавать пользователю через внешний интерфейс в текстовом виде (printf никто не отменял).
Я именно так и делал. Хранить удобнее бинарные записи (размер меньше, размер фиксированный), а при выдаче вовне переводить их в текст на лету.
ViKo
Цитата(aaarrr @ Jul 8 2018, 00:04) *
Так оно в ряде случаев вполне возможно - вон, на ARM7 так предлагали виртуальную память строить. Но прозвучало предложение "выйти из той функции", что уже действительно на грани фантастики.

Так PC и LR во время падения в HF сохраняются в стеке. Вот за них и потянуть. Можно просто выйти из HF и продолжить, как ни в чем не бывало.
Я не настаиваю. Предлагаю подумать.
Можно задачу удалить в РТОС, а потом снова создать.
А сбросить МК любой умеет.
aaarrr
Цитата(ViKo @ Jul 10 2018, 10:04) *
Так PC и LR во время падения в HF сохраняются в стеке. Вот за них и потянуть.

А где сохраняется SP? sm.gif

Цитата(ViKo @ Jul 10 2018, 10:04) *
Можно просто выйти из HF и продолжить, как ни в чем не бывало.

Можно, но нужно или устранить причину fault'а, или привести ПО в безопасное состояние.

Цитата(jcxz @ Jul 10 2018, 09:57) *
Вообще-то вероятность зависит...

Вообще-то я говорил о вероятности совпадения двух событий разной природы.

Цитата(jcxz @ Jul 10 2018, 09:57) *
ФС нужна только если эту SD должны вынимать вставлять ещё куда-то (комп, etc.).

Если карту не предполагается вынимать, то и сама карта вроде бы ни к чему, нет?

Цитата(jcxz @ Jul 10 2018, 09:57) *
Хранить удобнее бинарные записи (размер меньше, размер фиксированный)

Размер смущать в наше время не должен, а вот возможность непосредственного чтения человеком и гибкость формата являются преимуществом.
Arlleex
Цитата(aaarrr @ Jul 10 2018, 10:42) *
Если используется SD-карта, то логично использовать файловую систему и текстовые логи - скопировать текст из файла в письмо условная "баба Нюра" сможет, а вот всякие утилиты ей совершенно ни к чему. Дублировать ничего не нужно - вероятность совпадения двух аварийных событий ничтожна.

В этом, безусловно, огромный плюс... И это имеет смысл (в моем случае) для устройств, которые стоят на объектах и которые имеют возможность эту карту вытащить. Но есть и устройства, из которых SD-карта не вынимается, а стоит на плате жестко (припаяна или в слоте). В таком случае файлы .info выкачиваются по доступному интерфейсу и могут расшифровываться "налету". Сейчас же все-таки все равно сделано в текстовом виде и с файловой системой, гоню по Ethernet при выкачке на комп (кстати, вот как раз jcxz об этом и говорит как раз).
Кстати а можно ли каким-то образом сказать файловой системе (FatFS), что я часть карты использую для сырых данных (с такого-то по такой-то адрес), а остальную область она может использовать для себя? Грубо говоря, организовать ФС на карте и, одновременно, иметь возможность писать сырые данные в отведенную область (скажем, некая аналогия с разлиновкой памяти для МК)?

Цитата(jcxz @ Jul 10 2018, 10:57) *
Вообще-то вероятность зависит от условий эксплуатации устройства автора. Вы откуда знаете какова у него вероятность?

Да вот конкретно сейчас бытовой пример - у меня устройство настольное, не серийное, а некий макет для людей. Им пользуются в течение дня и вечером выключат питание. И так каждый рабочий день. И хочу каждому юзеру обрубить его претензии, а то бывает не доказательное давление со стороны пользователей laughing.gif А когда показываешь лог событий и говоришь - "вот все что ты делал" - сразу невинные глазки и ответ - "ну да, признаю"... crying.gif В общем, перекладывание вины на других мне надоело и уже решил всегда все логгировать чтобы небезосновательно снять с разработчиков ответственность (или наоборот ее доказать).

ViKo, из Fault-обработчика то Вы выберетесь, элементарно ж. Но вот из функции, вызвавшей ошибку, находясь в прерывании, Вы не выйдете. Иначе надо знать размер каждой функции в памяти и состояние стека. Это не представляется возможным. Ваш подход насчет подумать "налету", не перезагружая процессор, был описан jcxz как некритическая ошибка, которую можно разрулить. Однако, если ПО довольно сложное и в нем крутится салат из многопоточных DMA, пересылок, обменов и т.д., выкрутиться из такой ситуации очень сложно (если не возможно вовсе) не затронув последствия такого разруливания. Ведь действительно, все может стать еще хуже: в реал-тайме полетит времянка из-за вовремя не остановленных процессов и т.д. Проще сбросить и начать сначала, с белого листа, указав разработчику на ошибку записью в какой-нибудь энергонезависимый накопитель rolleyes.gif Со временем такие ошибки минимизируются к 0, останутся только некритические ошибки, которые, как раз, как и Вы предлагаете, исправляются "on fly".
ViKo
Цитата(aaarrr @ Jul 10 2018, 10:24) *
А где сохраняется SP? sm.gif

А он (они) не портится. Нужно только определить, который из них использовался перед улетом, и далее из стека извлекается всё нужное и ненужное. Если, конечно, не напортачить с выделением стека изначально.
aaarrr
Цитата(Arlleex @ Jul 10 2018, 10:36) *
Кстати а можно ли каким-то образом сказать файловой системе (FatFS), что я часть карты использую для сырых данных (с такого-то по такой-то адрес), а остальную область она может использовать для себя?

Если FatFS умеет работать с разделами, то почему бы и нет?

Цитата(Arlleex @ Jul 10 2018, 10:36) *
Да вот конкретно сейчас бытовой пример - у меня устройство настольное, не серийное, а некий макет для людей. Им пользуются в течение дня и вечером выключат питание. И так каждый рабочий день.

На макете можно и sync после каждой записи делать.

Цитата(ViKo @ Jul 10 2018, 10:47) *
А он (они) не портится.

Да ну? То есть в произвольной точке функции Вы ожидаете увидеть то же значение SP, что и на входе?
jcxz
Цитата(aaarrr @ Jul 10 2018, 10:24) *
Размер смущать в наше время не должен, а вот возможность непосредственного чтения человеком и гибкость формата являются преимуществом.

Пока не изобрели МК с бесконечной памятью, он будет смущать.
Да и: скорость_записи=f(размер_записи).
ViKo
Цитата(aaarrr @ Jul 10 2018, 11:01) *
Да ну? То есть в произвольной точке функции Вы ожидаете увидеть то же значение SP, что и на входе?

Заваливаясь в HF, я всегда буду на вершине стека, относительно которой и находятся регистры PC, LR. То есть, я могу сохранить состояние ошибки, задать некий флаг ошибки и выйти из функции, используя сохраненный LR. Если внутри функции используется стек, тогда не знаю.
aaarrr
Цитата(jcxz @ Jul 10 2018, 11:05) *
Пока не изобрела МК с бесконечной памятью, он будет смущать.
Да и: скорость_записи=f(размера_записи).

Размер типичной записи в лог - десятки байт-килобайты. Это явно не тот случай, когда экономия имеет смысл.
Вот если нужно в 24C04 лог писать - тогда другое дело sm.gif
jcxz
Цитата(Arlleex @ Jul 10 2018, 10:36) *
В этом, безусловно, огромный плюс... И это имеет смысл (в моем случае) для устройств, которые стоят на объектах и которые имеют возможность эту карту вытащить.

Даже в этом случае имхо - надёжнее организовать журналы как я описывал. Просто дублировать их ещё и в ФС. Основное место хранения при этом - FIFO, а при старте ПО и при каждом обновлении FIFO-журнала ПО просто должно синхронизировать файлы по содержимому FIFO-журнала: удалять ненужные, или создавать отсутствующие (удалённые как сбойные при старте ПО и ремонте ФС).

Цитата(Arlleex @ Jul 10 2018, 10:36) *
Грубо говоря, организовать ФС на карте и, одновременно, иметь возможность писать сырые данные в отведенную область (скажем, некая аналогия с разлиновкой памяти для МК)?

Ну никто-ж Вам не мешает на этой SD ограничить размер раздела каким-то объёмом, а остальное место использовать для посекторного доступа. Фэйковые флешки с али, на которых написано 512 гиг, а по факту они - 8 гиг именно так и ремонтируются: раздел урезается до реальной ёмкости и всё. У меня несколько таких халявных флешек, работающих уже не один год rolleyes.gif
aaarrr
Цитата(ViKo @ Jul 10 2018, 11:09) *
Если внутри функции используется стек, тогда не знаю.

Так о том и речь.
ViKo
Цитата(aaarrr @ Jul 10 2018, 11:18) *
Так о том и речь.

По моему, регистры в стек заносятся непосредственно при улете в HF. То есть, определить PC и LR и еще кучу регистров можно точно.
jcxz
Цитата(ViKo @ Jul 10 2018, 11:09) *
То есть, я могу сохранить состояние ошибки, задать некий флаг ошибки и выйти из функции, используя сохраненный LR. Если внутри функции используется стек, тогда не знаю.

А какой толк-то? Вот у Вас произошло переполнение стека к примеру, в результате - разрушился счётчик цикла там хранившийся, потом по этому счётчику цикла производится цикл записи в память. В результате счётчик вместо скажем 10, стал равен 0xFFFFFFF и запись в память будет идти пока не дойдёт до границ региона, разрешённого для записи в MPU и не вызовется fault. И что - сохраните Вы ошибку и вернётесь куда - в полностью разрушенную программу (вся ОЗУ стёрта)? И что получите? Что устройство вылетит в следующий fault, и следующий и т.д.? И в результате потом даже неясно будет первоначальная точка fault-а? А может в очередной раз не вылетит в fault, а просто тупо повиснет - так лучше?
А в это время скажем какая-то нагрузка (которая в штатном режиме работы ПО устройства управляется ШИМ-ом) начинает поджариваться, так как силовой ключ остался во вкл. положении надолго, вместо перезапуска ПО и перевода всего и вся в безопасное положение. smile3009.gif
ViKo
Цитата(jcxz @ Jul 10 2018, 11:26) *
А какой толк-то? Вот у Вас произошло переполнение стека к примеру
...
вместо перезапуска ПО и перевода всего и вся в безопасное положение. smile3009.gif

А вы контролируйте стек периодически, чтобы не переполнялся. rolleyes.gif
А если у вас манипулятор переместился в крайнее положение и произошел сбой, то вам непременно нужно махнуть им в исходное положение в непредсказуемый момент времени (сброс), а не замереть?
aaarrr
Цитата(ViKo @ Jul 10 2018, 11:23) *
По моему, регистры в стек заносятся непосредственно при улете в HF. То есть, определить PC и LR и еще кучу регистров можно точно.

Можно. Но восстановить историю использования SP в функции - нет. Соответственно, и выйти из функции не получится, только вернуться к точке сбоя.

Цитата(ViKo @ Jul 10 2018, 11:35) *
А если у вас манипулятор переместился в крайнее положение и произошел сбой, то вам непременно нужно махнуть им в исходное положение в непредсказуемый момент времени (сброс), а не замереть?

А не нужно дергать манипуляторами по аварийному сбросу.
ViKo
Цитата(aaarrr @ Jul 10 2018, 11:39) *
Можно. Но восстановить историю использования SP в функции - нет. Соответственно, и выйти из функции не получится, только вернуться к точке сбоя.

И к выходу из функции. LR
aaarrr
Цитата(ViKo @ Jul 10 2018, 11:44) *
И к выходу из функции. LR

Ну, вышли с испорченными регистрами и SP - сильно легче стало?
ViKo
Цитата(aaarrr @ Jul 10 2018, 11:47) *
Ну, вышли с испорченными регистрами и SP - сильно легче стало?

Не знаю. Можно по функции пройтись до конца. Допустим, просмотреть в обработчике, как меняется указатель стека в функции, откуда улетели, и попробовать его восстановить.
aaarrr
Цитата(ViKo @ Jul 10 2018, 11:57) *
Допустим, просмотреть в обработчике, как меняется указатель стека в функции, откуда улетели, и попробовать его восстановить.

Еще проанализировать, куда сохранили испорченные регистры, тоже восстановить... Главное ведь, не перезагружаться - то каждый может biggrin.gif
ViKo
Цитата(aaarrr @ Jul 10 2018, 12:13) *
Главное ведь, не перезагружаться - то каждый может biggrin.gif

У меня сброс прибора не пройдет незамеченным для пользователя. Так зачем напрягаться? Сам и передернет питание, если увидит, что прибор завис.
У меня комп на работе по некой причине каждое утро перезагружается с голубым экраном. А после этого трудится весь день без сбоев. В чем причина, не знаю. То ли питания мало, то ли ломалка так работает. Но очень неприятно. Сидишь, мышой водишь, и вдруг бац!
Arlleex
Цитата(ViKo @ Jul 10 2018, 13:38) *
У меня сброс прибора не пройдет незамеченным для пользователя. Так зачем напрягаться? Сам и передернет питание, если увидит, что прибор завис.

На объектах прибор никто не передернет biggrin.gif Поверьте, лететь за тысячи километров для того, чтобы отлаживать устройство в ангаре или поле под мат орущих техников - далеко не изящный выход. Тем более UART там уже не подключишь.
jcxz
Цитата(ViKo @ Jul 10 2018, 11:35) *
А вы контролируйте стек периодически, чтобы не переполнялся. rolleyes.gif

Спасибо, что разъяснили! И правда - зачем ПО отлаживать? Ведь надо просто не делать багов! cranky.gif

Цитата(ViKo @ Jul 10 2018, 11:44) *
И к выходу из функции. LR

Попробуйте как нить запустить отладчик, запустить программу, а потом в произвольной функции остановить выполнение и переместить PC на команду BX LR и продолжить выполнение кода. Увидите что будет, теоретик Вы наш. biggrin.gif

Цитата(ViKo @ Jul 10 2018, 12:38) *
У меня сброс прибора не пройдет незамеченным для пользователя. Так зачем напрягаться? Сам и передернет питание, если увидит, что прибор завис.

Да ужжж.... больше нет слов. Остаётся только посочувствовать пользователям ваших девайсов..... crying.gif
ViKo
Цитата(jcxz @ Jul 10 2018, 14:47) *
Да ужжж.... больше нет слов. Остаётся только посочувствовать пользователям ваших девайсов..... crying.gif

У меня не виснет, можете не сочувствовать. Раньше висло, бывало. В последний раз в попытке усовершенствовать выскочила потенциальная вероятность деления на ноль. Исправил. Теперь никто не жалуется. А если что - прошивку можно обновить через загрузчик. Но никто не обращался.

Цитата(jcxz @ Jul 10 2018, 14:47) *
а потом в произвольной функции остановить выполнение и переместить PC на команду BX LR и продолжить выполнение кода. Увидите что будет, теоретик Вы наш. biggrin.gif

А вы на флаг поглядывайте, был HF или нет. И в зависимости от меняйте поведение функций. biggrin.gif
jcxz
Цитата(ViKo @ Jul 10 2018, 14:57) *
А вы на флаг поглядывайте, был HF или нет. И в зависимости от меняйте поведение функций. biggrin.gif

Что за флаг? И как менять поведение?
ViKo
Цитата(jcxz @ Jul 10 2018, 14:59) *
Что за флаг? И как менять поведение?

В обработчике задайте флаг, один или десяток разных на каждый случай и т.д. Меняйте так, чтобы функция делала как можно меньше вреда и как можно больше пользы. Чтобы манипулятор не полетел стремительным домкратом в исходное состояние. biggrin.gif
jcxz
Цитата(ViKo @ Jul 10 2018, 15:04) *
В обработчике задайте флаг, один или десяток разных на каждый случай и т.д. Меняйте так, чтобы функция делала как можно меньше вреда и как можно больше пользы.

Вы что-ж предлагаете в memcpy() перед копированием каждого байта этот десяток флагов проверять??? 01.gif
Ааа!... Понял - это просто троллинг! biggrin.gif
ViKo
Цитата(jcxz @ Jul 10 2018, 15:13) *
Ааа!... Понял - это просто троллинг! biggrin.gif

Я же писал, предлагаю подумать над. А то всё сброс да сброс. Скучно.
Мой HardFault обработчик состоит из двух ассемблерных команд. И ничего, прибор работает не хуже других. laughing.gif
serglg
Цитата(jcxz @ Jul 10 2018, 17:47) *
Да ужжж.... больше нет слов. Остаётся только посочувствовать пользователям ваших девайсов..... crying.gif


Первый совет у любой техподдержки - выключите устройство и опять включите. :-)
Pavia
Цитата(aaarrr @ Jul 10 2018, 11:39) *
Можно. Но восстановить историю использования SP в функции - нет. Соответственно, и выйти из функции не получится, только вернуться к точке сбоя.

Ребят, а что try except finally - запрещены?

В try сохраняете SP в SEH-стек при Faults SP восстанавливается из этого стека.

Переполнение стека вообще неплохо отлавливается статическим анализатором. А для редких случаев как уже говорили надо контролировать периодической проверкой.

Цитата(jcxz)
Вы что-ж предлагаете в memcpy() перед копированием каждого байта этот десяток флагов проверять???

Где-то я видел требование считать memcpy() - безопасной функцией. Просто иначе не получается доказать безопасность кода(доказательная безопасность). Но как по мне она небезопасна, но ведь достаточно перед ней поставить проверку и все дела. А если у вас есть вероятность отказа памяти, то как тут верно заметили есть дублирующий код который другим методом делает.

Частичный отказ памяти маловероятен. А если он произойдёт то тут только дублирование железа поможет.
Вероятность того, что память закончится отметается нагрузочным тестированием. А если при работе произойдёт, то используем стек прерывания/ядра сохраняем код ошибки в SD и перезагружаем устройство. При загрузки анализируем предыдущий отказ.
haker_fox
Мой обработчик HardFault состоит из диагностического вывода в консоль содержимого регистров. Взят на просторах инета. Плюс к этому блокируются все прерывания, и через некоторое время прибор перезагружается по собаке. Событие пишется в журнал, но лишь как HARDFAULT_EVENT". В журнал уже не кладу никакой другой полезной информации. Полагаю, что на этапе отладки нужно минимизировать вероятность этого события. А если на объекте появится, то... ну что поделать) Попробовать воспроизвести у себя. Поэтому расчёт на пса, и собственные силы в отладке.

Продолжать работу после hard faulta не считаю разумным, т.к. причин этого явления может быть несколько разных. Например, невыровнный доступ к памяти. И что с этим делать? Если это правится в исходниках, там и нужно поправить. Если это "случайная" ситуация, зависиящая от внешней среды... то тоже исходники править, только больше алгоритмически. Или улетели с нулевого указателя? И вот что с этим делать? Прибор не может работать, не обратившись к нужной функции. Значит его нужно перзапускать, что и делает собака.

Как правило, приборы, особенно построенные на МК без MMU - не компы. Операционных систем, которые берут на себя весь процесс восстановления и защиты экосистемы, там нет. Писать это и тестировать самому - не одного ежа можно родить) А если только MPU? Или у нас Cortex-M0 без оного? Считаю, что лог + перезапуск самое то)
aaarrr
Цитата(haker_fox @ Jul 11 2018, 12:53) *
Событие пишется в журнал, но лишь как HARDFAULT_EVENT". В журнал уже не кладу никакой другой полезной информации. Полагаю, что на этапе отладки нужно минимизировать вероятность этого события. А если на объекте появится, то... ну что поделать) Попробовать воспроизвести у себя.

Не факт, что будет легко воспроизвести на столе. Лучше добавить в лог хотя бы содержимое регистров и адрес события.
ViKo
Цитата(haker_fox @ Jul 11 2018, 12:53) *
Значит его нужно перзапускать, что и делает собака.

Есть не один способ сбросить МК без собаки. Зачем ждать, пока собака проснется?
Arlleex
Цитата(haker_fox @ Jul 11 2018, 13:53) *
А если на объекте появится, то... ну что поделать) Попробовать воспроизвести у себя.

Я еще понимаю, если устройство является технологическим (вспомогательным) и его отказ не оказывает влияния на всю систему.
А если этот ваш МК стоит на приводе управления тормозами поезда? А если в самолете? А если в дозаторе рентген-излучателя в медицине? Вам же хотелось бы быть уверенным, что не получите 100-кратную дозу при снятии рентгена грудной клетки? Вот и мне хотелось бы. Да куча примеров, в общем-то - думаю понимаете, к чему я веду. И даже из каждого недопустимого поведения устройства нужно делать выводы. И чем больше исходных данных - тем вкуснее пища для размышлений.
Насчет сторожевой собаки в данном конкретном случае - мне кажется это лишнее. Хотя кому как. Мне проще NVIC попросить сбросить МК сразу laughing.gif
haker_fox
QUOTE (Arlleex @ Jul 11 2018, 19:52) *
А если в самолете?

Не переживайте так, я тоже озаботился этим вопросом rolleyes.gif Именно поэтому я развил тему авионики начиная отсюда, и тут.
AlexandrY
Цитата(Arlleex @ Jul 7 2018, 18:39) *
Интересует, как коллеги обрабатывают все Faults на микроконтроллерах Cortex-Mx.
Я про NMI, Hard, MemManage, Bus, Usage, SVCall, Debug Monitor, PendSV, Systick.
С SVCall, Debug Monitor, Systick все понятно, с PendSV в принципе тоже.

Ловить HardFault-ы в релизе во время эксплуатации нет особого смысла.
Слишком много информации надо зафиксировать о контексте события, слишком обременительно хранить историю версий и парсить многомегабайтные логи.
Лучше их выловить отладочным адаптером заранее.
Поскольку такие проблемы чаще всего из-за специфичной периферии SoC-а и происходят во время ее исследований.
Либо по причине некачественного интерфейса к внешней памяти.
Но тут надо не HardFault-ы ловить, а гонять разнообразные тесты.
Помню случай когда ошибка c DDR вылезала у меня только когда компилер генерил STM инструкцию с сохранением более 7 им регистров в определенной последовательности и никак иначе.
Это вызывало самые причудливые Hard Fault-ы всех сортов.
Никакие логи и дампы регистров и стека не помогали. После каждой смены опций компиляции картина ошибок менялась.

Если устройство действительно критичное для безопасности, то никто не даст вам полагаться на обработку HardFault, а потребуют полный пакет самотестирования всего и вся в чипе перед каждой ответственной операцией.
Насчет как писать надежный софт есть специальные стандарты.
Вот тут доступно написано
Что интересно, допускается восстановление после HardFault-ов, если они были ожидаемы и произошли во время штатного тестирования.
Т.е. перед тестированием переопределяем обработчик на специальный для данного теста, по завершению тестирования ставим на место стандартный обработчик RTOS.
haker_fox
QUOTE (Arlleex @ Jul 11 2018, 19:52) *
Я еще понимаю, если устройство является технологическим (вспомогательным) и его отказ не оказывает влияния на всю систему.
А если этот ваш МК стоит на приводе управления тормозами поезда? А если в самолете? А если в дозаторе рентген-излучателя в медицине?


И я вас уверяю, что если даже ваш контроллер протестирован ни на один раз, у вас небыло зависаний и выпадений в hf, никто в единственном экземпляре не поставит его на тормоза поезда, или в дозатор. Как минимум сдублируют. Хотя, может быть исключения и есть.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.