fk0, легенда (30.10.2019 02:28 - 02:56, просмотров: 1335) ответил Evgeny_CD на [ГОСТ Р МЭК 61508-7-2012] -> --> Интересные вещи там написаны...Раздел С.2.6.6 Ограниченное использование указателей
Спасибо, вообще в документе многие пункты достаточно разумны, я особо подчерку для некоторых здешних читателей: "Выполнение функции безопасности при выключении или отсутствии питания" -- вообще неплохо думать, что происходит при недостаточном напряжении, при перенапряжении, при ограничении тока источником питания, при кратковременном перебое в питании. Много приборов сбоят и не запускаются потом нормально при недостаточном питании (пример: севшая АКБ автомобиля). Вообще и некоторые микросхемы стартовать нормально-то могут только при скорости нарастания фронта питания не менее чем (иначе внутренние схемы сброса не срабатывают). По-хорошему источник питания должен иметь нижний порог отключения и гистерезис или таймаут до повторного включения.
"Обнаружение статических отказов путем динамической обработки сигналов" -- пример сегодня приводил, концевик который проверяется на несрабатывание только трупом (при нормальной работе нет возможности узнать об отказе концевика) и отказавший вход контроллера, транзистора, реле, пережатый кабель пульта с перетертой изоляцией и к.з. отдельных проводников внутри... использование переменного тока отчасти решает проблему (при КЗ с землей или питанием, пробое транзисторов -- будет заметно отсутствие сигнала).
"Обнаружение отказов путем создания нескольких функциональных модулей, контроля поведения каждого из них для обнаружения отказов и последующего инициирования перехода в безопасное состояние при обнаружении какого-либо несоответствия в поведении" -- обычно почему-то везде пишут про дублирование, мажоритарный выбор из трёх и т.п. Но почему-то упускается простая идея (хотя отсылку к ней можно увидеть ближе к концу документа, где про моделирование программы -- на сахаре уже писали про Promela/SPIN например). Идея заключающаяся в создании не равноценных модулей. Одного основного, управляющего, и второго, куда более простого, контрольного. Контрольный модуль не обладает всей полнотой логики управления, но имеет лишь весьма небольшой набор проверочных правил заданных в терминах допустимых или недопустимых последовательностей событий, например (временная или темпоральная логика). И в случае нарушения правил проверочный модуль может вызывать аварийную ситуацию и иметь какую-то процедуру обработки аварии (например может быть способен безопасно остановить процесс).
"Обнаружение отказов путем периодической проверки способности выполнения функции безопасности" -- те же концевики, например, в лифте, могут проверяться на срабатывание, например, при каждом открытии дверей (а не только выполнять функцию запрета движения при несрабатывании). И таким образом вставить перемычку вместо концевика никак не получится.
"Повышение достоверности результатов измерений аналоговых сигналов Описание. Везде, где возможно, используются аналоговые приборы, а не цифровые. В аналоговых приборах отключение или безопасные состояния представляются уровнями аналоговых сигналов обычно с контролем устойчивости уровня этого сигнала. Это обеспечивает непрерывный контроль и высокую степень достоверности передачи сигнала, снижает частоту необходимого гарантийного тестирования... -- это именно тот случай, когда концевик однозначно *хуже* непрерывного мониторинга какой-либо другой величины. Потому, что отсутствия отклика непрерывно наблюдаемой величины -- это моментальное обнаружение аварии. А отсутствие срабатывания концевика может быть замечено когда уже образовался труп.
"Выявление модификаций информации в постоянной памяти" -- любой embedded прибор на старте должен считать контрольную сумму ПЗУ... Сознайтесь, кто так делает? Увы... А ведь недопрограммированный контроллер своими глюками может кому-то неплохо попортить жизнь, причём и в буквальном смысле.
"Обнаружение или устойчивость к отказам, обусловленным источником питания", "Контроль вторичных напряжений и инициализация безопасного состояния, если значение напряжения не находится в заданном диапазоне" -- как минимум неплохо быть иметь монитор питания формирующий сброс контроллера (если он сам не имеет такой функции) при нахождении напряжений по крайней мере ниже рабочего порога. А в идеале -- провал напряжения во вторичной цепи должен кратковременно отключать и перезапускать источник питания. И должна быть цепь обеспечивающая разряд конденсаторов за время отключения (потому, что 1 вольта может быть достаточно, чтоб кто-то не сбросился и не перезапустился). Провал может быть вызван защёлкиванием какой-либо микросхемы. И разумеется ток должен ограничиваться самим источником на разумном уровне, чтоб микросхемы не испарялись (большую схему следует сегментировать, а не питать от одного источника токами в 20А).
"В.2.3.2 Конечные автоматы/диаграммы переходов" -- без комментариев, автоматы для красноглазиков, настоящие профессионалы пишут запутанный спагетти-код и он сразу работает. Формальные методы -- ни к чему. Утрирую.
"В.4.8 Защита от модификаций" -- Модификации или манипуляции обнаруживаются автоматически, например, проверками достоверности сигналов датчиков, обнаружением техническим процессом и автоматическим запуском тестирования. При обнаружении модификации выдается аварийный сигнал...
программирование с проверкой ошибок -- без комментариев опять же... в редкой программе вообще ошибки предусматриваются и хоть как-то обрабатываются. Как минимум все ошибки должны логгироваться (логгер это вообще отдельная сложная тема) или "всплывать" наверх, для обработки на более высоком уровне.
"Документировать и по возможности автоматизировать создание исполняемого кода (make-файлы)" -- собирается же всё, традиционно, только и исключительно у автора на компьютере. На другом компьютере либо не собирается, либо собирается но что-то работающее не так. Потому, что в свойствах проекта IDE затесалась опция поиска include-файлов в директорр C:\Users\Вася\, и там у автора какие-то свои версии файлов. Или вариант, в переменных окружения какой-то свой особенный CPPFLAGS в котором волшебная -Dчего-нибудь=что-нибудь. Или в subversion кладут не только исходники, а бинарники, ну для удобства. Только те бинарники собраны не совсем из тех исходников. Или вот вообще номер, Make до какой-то версии учитывал локаль при сортировке списка файлов. А в самом Makefile вместо тупого списка файлов масса $(wildcard *.cpp). Только все *.cpp перечисляются на разных компах в разном порядке. В частности в "C" локали в одном, а в "ru" или в "en_US" -- в другом порядке. А компилятор, верней линкер, когда линкует он берёт нужный символ из первого попавшегося (в порядке перечисления в командной строке) файла. Т.е. если мы функцию с одним именем определили в двух файлах -- в разных локалях будем получать функции из разных файлов, ошибки (что функция определена два раза) -- не будет, если из *.cpp сначала сделали библиотеку (статическую), а потом с ней линкуют весь проект. В итоге на билд-сервере всё собирается, тащим на другой комп, а там собирается совсем не то и работает совсем не так. Ну я ещё разные диверсии знаю, но это долго рассказывать. Например в C++ декларация функции мало отличима от вызова конструктора. Или вон на хабре недавно про hidden friends и argument dependent lookup.
"С.3.1 Обнаружение и диагностика сбоев" -- обычно этим никто не занимается... имеется ввиду -- программных сбоев. Должны быть предусмотрены сценарии обработки сбоев, должны сами сбои обнаруживаться (в ARM-контроллерах, например, установлены вектора прерываний для исключительных ситуаций).
"C.3.6 Восстановление предыдущего состояния" -- для embedded как минимум актуально периодическое сохранение информации в flash-память, для восстановления после включения питания. И разумеется запись должна быть транзакционной: либо произошла полностью, либо считается не произошедшей и доступно для чтения предыдущее состояние. Без надежды на мифический конденсатор, которого может (не)хватить для записи состояния в момент отключения питания (а сбросы и перезапуски могут быть обусловлены не только отключениями питания).
"C.3.8 Постепенное отключение функций" -- на самом деле это *очень* *важная* тема. Ракете падать некуда, например. Да и не только ракете. И из-за мелкой ошибки, ассерта в трижды второстепенной функции, обрушивать абсолютно всё -- дурная идея. Даже не в ракете, но например в телевизоре. Потому, что это будет отказ прибора, гарантийный ремонт и т.п. Поэтому оправдано использование многозадачных ОС с изоляцией процессов. Один рухнувший процесс не нарушает работоспособность всей системы. В рамках монолитной программы можно по крайней мере пытаться остановить какую-то одну функцию или задачу, и продолжать остальные. Можно перезапустить систему, но не запускать проблемную функцию в следующий раз. Пользователь, например, не сможет посмотреть расписание телепередач, но базовые функции у него будут работать, например.
Сюда же следовало бы отнести другую важную тему: циклические перезагрузки. Очевидно, что если какая-то последовательность действий выполняется на старте и вызывает перезагрузку, то на третий раз неплохо бы уменьшить набор исполняемых функций, вплоть до абсолютного минимума. Особенно если предусматривается удалённое обновление ПО. Иначе оно просто станет невозможно из-за перезагрузок.
И ещё одну важную тему: введение недетерменированности в алгоритм для обхода ошибочной ситуации. Допустим, ошибочная ситуация вызывается определённой последовательностью действий. И если все приборы всегда работают одинаково, вся "циклограмма" абсолютно детерминирована, то тогда возможно, что в цикле работы прибора, особенно в момент загрузки, может найтись такая последовательность действий, которая всегда вызывает сбой и перезагрузку. Ничего хорошего -- массовый отказ у всех пользователей. Гораздо лучше, если есть какой-то элемент случайности и последовательности событий всегда немного разные, временные характеристики тоже разные. Да сбой возможен, и можно даже сказать, что его сложней обнаружить. Но с другой стороны в среднем готовность прибора к работе -- выше. Потому, например, что смогут не стартовать однажды не абсолютно все, а например только несколько процентов приборов, и в циклическую перезагрузку впадёт ещё меньший процент, потому, что ввиду недетерминированности ожидать повторения сценария после перезагрузки не приходится.
"C.5.18 Моделирование процесса" Тестирование функции программной системы вместе с ее интерфейсами во внешнем окружении, не допуская модификации реального окружения. Создание системы только для целей тестирования, имитирующей поведение управляемого оборудования (УО). Имитация может осуществляться только программными средствами либо сочетанием программных и аппаратных средств... -- про понятие "синтетического порта" на сахаре уже много раз писалось, наверное нет смысла повторять. Синтетический порт исключительно важен для качественной отладки ПО, т.к. средства отладки для МК обычно весьма ограничены. Кроме того, смена аппаратной платформы позволяет "всплыть" большому числу ошибок.
Сторожевой таймер -- про это как-то не сказано, но очень хочется от себя добавить. Сторожевой таймер должен присутствовать в любой embedded системе и быть включен в самый главный, самый верхний, основной, цикл обработки событий. Он не должен запускаться в отдельном потоке, в прерывании, ещё как-то независимо. В основной цикл обработки событий периодически (по факту истечения определённого периода внутреннего времени системы) должно включаться специальное событие, которое должно обрабатываться и сбрасывать таймер. Таким образом контролируется два факта: то, что система в состоянии обрабатывать события, и что внутреннее время системы идёт. Нельзя просто в цикле сбрасывать сторожевой таймер без проверки времени, потому, что возможны ошибки, когда цикл выполняется, а время не идёт или отсчитывается неправильно.
[ZX]