Перейти к содержанию
    

Поделитесь опытом - как делаете обработку ошибок

Привет всем!

В процессе инициализации железа могут возникать ошибки, далее при работе - при создании очередей, семафоров итп. так же могут возникать ошибки.

Поделитесь опытом кто как их обрабатывает и логирует?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 минуты назад, Mty сказал:

Поделитесь опытом кто как их обрабатывает и логирует?

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

Запоминается номер trap, его аргументы, состояние регистров CPU и вершины текущего стека (это контекст trap); делается сброс всей периферии (возможно - с переключением CPU на более низкую частоту; а возможно и со сбросом всего устройства), инициализируется только минимально необходимый набор периферии (система тактирования, GPIO, MPU, WDT, отладочный UART, ...) и в отладочный UART начинается периодический вывод состояния ловушки (запомненного контекста) с индикацией режима ловушки через доступные средства индикации (лампочки и т.п.).

Т.е. - реализую аналог "синего окна смерти" винды. Делаю примерно то же самое.

В устройствах, где имеется FRAM, у меня также события критических ошибок (с контекстом) сохраняются в журнал критических ошибок (расположенный во FRAM). Но после предварительного сброса/рестарта CPU.

В терминале вывод состояния ловушки выглядит так:

image.thumb.png.661c472437690235a3c3bae297b38d78.png

По логу виден номер trap (3) + набор аргументов данного номера (в квадратных скобках) + регистры + вершина стека.

 

PS: А почему вопрос в разделе "Операционные системы\FreeRTOS"? Обработка критических ошибок не имеет никакого отношения к ОС.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, очень интересная концепция.
Немного чайниковый вопрос - а как из стека и регистров потом получаете причину ошибки?

PS: Во freertos группе потому что я подумал что уже в ОС есть какой то функционал для обработки и трекинга ошибок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, jcxz said:

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

Запоминается номер trap, его аргументы, состояние регистров CPU и вершины текущего стека (это контекст trap); делается сброс всей периферии (возможно - с переключением CPU на более низкую частоту; а возможно и со сбросом всего устройства), инициализируется только минимально необходимый набор периферии (система тактирования, GPIO, MPU, WDT, отладочный UART, ...) и в отладочный UART начинается периодический вывод состояния ловушки (запомненного контекста) с индикацией режима ловушки через доступные средства индикации (лампочки и т.п.).

Т.е. - реализую аналог "синего окна смерти" винды. Делаю примерно то же самое.

В устройствах, где имеется FRAM, у меня также события критических ошибок (с контекстом) сохраняются в журнал критических ошибок (расположенный во FRAM). Но после предварительного сброса/рестарта CPU.

В терминале вывод состояния ловушки выглядит так:

image.thumb.png.661c472437690235a3c3bae297b38d78.png

По логу виден номер trap (3) + набор аргументов данного номера (в квадратных скобках) + регистры + вершина стека.

 

PS: А почему вопрос в разделе "Операционные системы\FreeRTOS"? Обработка критических ошибок не имеет никакого отношения к ОС.

а к чему же это имеет отношение? все ловушки в файле прерывания ,  туда и валится операционка.

47 minutes ago, x893 said:

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

в лучшем случае светодиодиком помигать. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Mty сказал:

Немного чайниковый вопрос - а как из стека и регистров потом получаете причину ошибки?

В смысле? Очевидно - при помощи отладчика. А как же ещё? Запускаю отладчик и смотрю что там происходит.

13 минут назад, firstvald сказал:

а к чему же это имеет отношение? все ловушки в файле прерывания ,  туда и валится операционка.

ни чего не понял... :wacko2: Что за "файл прерывания" и какое он имеет отношение к ошибкам инициализации железа, и почему "операционка валится" куда-то?

Из вопроса ТС видно, что речь не только о вызове сервисов ОС, но и об "инициализации железа". А значит - речь о всех критических ошибках вообще, а не только об ошибках использования сервисов РТОС.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

38 minutes ago, firstvald said:

в лучшем случае светодиодиком помигать. 

Тут каждый решает как удобнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ошибки разные бывают. При совсем критических, как правило, системе сносит крышу настолько, что уже никакие логи регистров особо не помогают. Чисто статистически случаев, когда по содержимому регистров я куда-то дошел в программе и увидел косяк - не так уж много. С другой стороны, критические ошибки (это я называю, например, неконтролируемые "ошибочные" уходы за пределы массивов и т.д.) чаще всего довольно быстро обнаруживаются еще до выхода девайса в свет - т.е. на столе. Снаружи у меня всегда стоит вачдог, да и внутренний тоже заведен. При сбросе CPU поздно делать дампы, т.к. содержимое самых интересных регистров теряется. А в рабочей прошивке что-то дампить нецелесообразно, ибо код, который дампит, может быть уже совершенно недосягаем при критическом эпик фэйле. В остальном - просто слежу за возвращаемыми значениями функций, допустимыми пределами принимаемых аргументов и т.д. и если обнаруживается "невозможное" событие - вот тут уже можно спокойно писать лог с содержимым регистров, стека и т.д. Все остальные ошибки - скорее, не ошибки уже вовсе, а некоторые исключительные ветки кода, которые должны быть корректно обработаны и все. Нет на 100% единожды правильного метода обработки того или иного участка "кривого" поведения программы - все весьма ситуативно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 minutes ago, Arlleex said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 минуту назад, aaarrr сказал:

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

Ну вот пример. Где-то в недрах исходников закрался баг. Пусть по вине кодописателя или по багу компилятора мы застряли в неком бесконечном цикле или вовсе улетели по адресу, который допустим для исполнения прошивки (MPU не увидит в этом проблем), но в конечном счете все равно улетит в какой-нибудь хэндлер или lockup. Или банально улетит по адресу куска памяти, где разблокируется Flash и что-то перепрограммирует (такой кусок кода имеется практически в любом проекте). Или сразу улетит по адресу NVIC_SysytemReset(). Это неотлавливаемые события. Дампер - ведь тоже кусок штатного кода, и чтобы передать ему управление, рассудок у CPU еще должен быть сохранен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, Arlleex сказал:

Ну вот пример. Где-то в недрах исходников закрался баг. Пусть по вине кодописателя или по багу компилятора мы застряли в неком бесконечном цикле или вовсе улетели по адресу, который допустим для исполнения прошивки (MPU не увидит в этом проблем), но в конечном счете все равно улетит в какой-нибудь хэндлер или lockup. Или банально улетит по адресу куска памяти, где разблокируется Flash и что-то перепрограммирует (такой кусок кода имеется практически в любом проекте). Или сразу улетит по адресу NVIC_SysytemReset(). Это неотлавливаемые события. Дампер - ведь тоже кусок штатного кода, и чтобы передать ему управление, рассудок у CPU еще должен быть сохранен.

Разве это не решается аналогом сторожевого таймера, обработчик прерывания которого выводит адрес останова (залипания) перед ресетом? Для отладки этого более чем достаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, makc сказал:

Разве это не решается аналогом сторожевого таймера, обработчик прерывания которого выводит адрес останова (залипания) перед ресетом? Для отладки этого более чем достаточно.

Аппаратный вачдог заводится напрямую на RESET МК. Да и внутренние вачдоги дергают ресет. Последний раз видел прерывание от вачдога в AVR, что еще 10 лет назад показалось мне не очень надежным 😃

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, Arlleex said:

в какой-нибудь хэндлер или lockup

где прекрасно сохранится дамп.

 

17 minutes ago, Arlleex said:

Или банально улетит по адресу куска памяти, где разблокируется Flash и что-то перепрограммирует (такой кусок кода имеется практически в любом проекте). Или сразу улетит по адресу NVIC_SysytemReset().

Вот ни разу в жизни такого не встречал. Думаю, много менее 1% случаев придется на подобные ситуации. Остальное замечательно отработает штатными средствами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, Arlleex сказал:

Аппаратный вачдог заводится напрямую на RESET МК. Да и внутренние вачдоги дергают ресет. Последний раз видел прерывание от вачдога в AVR, что еще 10 лет назад показалось мне не очень надежным 😃

Есть разные варианты, типа сначала прерывание, а потом ресет, если не отпустило. Зависит от модели МК, но в целом это по-моему есть приблизительно везде.

 

Надёжность понятие относительное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...