Введение в разработку ПО для систем критичных к безопасности

1. О чем эта статья?

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

2. Что такое Safety-Critical?

В современном мире существует класс систем, для которых вопросы безопасности являются критичными. Я не говорю только о кибербезопасности, которая, конечно, тоже важна, но для множества таких систем не является определяющей. Даже наоборот – такие системы, как правило, не имеют выхода Интернет и «варятся в собственном соку», хотя, в последнее время, стали предприниматься попытки обынтернетить все и вся.

Как правило, системы, критичные к безопасности исполняют какую-то важную функцию, которую еше называют Functional Safety. Например, тормозная система в автомобиле контролируется микропроцессором (а зачастую и не одним) и ее основная функция – остановить автомобиль максимально безопасным способом, если этого требует водитель.

3. Где применяются Safety-Critical системы?

Первое, о чем обычно вспоминают при упоминании Safety-Critical – это оборонка. На самом деле, оборонка это только одна из областей, причем, далеко не самая большая. Навскидку можно припомнить автомобилестроение (Automotive), медицину (Medical & Healthcare), авиапромышленность (Aerospace), нефтегазовую (Oil & Gas), атомную (Nuclear) и это еще не все.

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

4. Какие бывают Safety-Critical системы?

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

· Систему нельзя будет сертифицировать (то есть, компания потеряет деньги и время)

· При обнаружении неполадок, система будет снята с рынка через государственные органы регулирования.

· При летальном исходе, вызванном работой данной системы, возможно уголовное преследование со стороны государства, в том числе и с вынесением тюремных сроков виновным (что редко) и\или штрафов компании (что бывает намного чаще).

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

Эта таблица примерно объясняет уровни безопасности для некоторых областей промышленности. Уровни в таблице расположены от минимального до максимального, предусмотренного данным стандартом.

Чем выше класс безопасности, тем больше требований выдвигается к принципам разработки, написания и документирования ПО.

5. Как определяется класс безопасности?

В каждом стандарте он определяется по своему. Например, в медицине надо заполнить специальный опросник под названием «слок» (SLOC – Software Level of Concern, то есть, «уровень беспокойства», если переводить «в лоб») и, исходя из ответов, можно определить класс.

Класс безопасности зависит не только от того, что именно система делает, но и для кого она это делает и в какой обстановке.

Возьмем простой пример с медицинским термометром. Допустим, вы пошли в магазин и купили простой термометр, чтобы измерять температуру домочадцев. Скорее всего (я очень удивлюсь, если это будет не так), в инструкции к термометру будет написано что-то в стиле «показаниям прибора доверять нельзя и для точного диагноза надо обратиться к квалифицированному медработнику». Это значит, что ПО для этого термометра было разработано по классу А, с минимальным исполнением требований стандарта.

А теперь представим, что термометр заказывает медработник для вынесения диагноза. Скорее всего, такой термометр будет иметь в инструкции фразу «система предназначена для использования квалифицированным медработником для помощи последнему в вынесении диагноза». То есть, производитель говорит, что полностью полагаться на показания прибора нельзя и надо смотреть на все имеющиеся у медработника диагностические данные, что, в принципе, правильно, потому что повышенная температура далеко не всегда является признаком гриппа. В этом случае, термометр будет сертифицирован по классу B.

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

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

6. Принципы разработки ПО для Safety-Critical

6.1 Введение

Как я уже говорил, в каждой области существуют свои стандарты, которым ПО должно соответствовать. Причем, несмотря на то, что производитель может сертифицировать свое ПО самостоятельно, надзорные органы вполне могут учинить проверку, причем, иногда это выглядит примерно так: в дверь фирмы стучится симпатичная молодая девушка, лучезарно улыбается и вытаскивает удостоверение представителя организации надзора (например, FDA в Штатах или BSI в Англии), после чего объявляет: «Это незапланированный аудит и не могли бы все сотрудники быть настолько любезными и отойти от своих компьютеров? Большое спасибо и прошу прощения за беспокойство». Так что, как вы видите, лучше соблюдать все правила стандарта, а то себе дороже выйдет.

Стандарт-стандартом, но все надзорные органы понимают, что если при начале проекта все делать по букве закона, то ни одна система не будет сделана в срок. Поэтому, стандарты действуют только на ту фазу разработки, которая называется Development (то есть, собственно, разработка), но не на ту, которая называется Research (изыскания). То есть, фирма вполне может создавать сколько ей захочется прототипов на стадии R и никто ей слова не скажет, потому что стандартом регулируется только фаза D. Поэтому обычно каждый проект проходит следующие фазы:

1. Создание PoC (Proof of Concept, доказательство того, что устройство в принципе можно создать)

2. Первый прототип

3. Второй прототип, максимально приближенный к реальному устройству

4. Формальная разработка устройства

5. Формальное тестирование финального варианта устройства

6. Передача в производство

6.2 Модель разработки V-Model

Давайте возьмем процесс формальной разработки (слово «формальный» тут означает то, что все должно идти по стандарту, за чем будут наблюдать руководство фирмы, внутренние аудиторы из отдела контроля качества и внешние аудиторы, которые могут завалиться в компанию в любой удобный им момент и без предупреждения. Для удобства сосредоточимся на медицинском стандарте IEC62304, который, на мой взгляд, самый простой из всех. Наше устройство будет соответствовать классу B.

Итак, до начала формальной разработки надо будет написать несколько планов (разработки, управления рискам, установки и компилирования ПО, среде разработки и так далее). У тестеров в это же время тоже будет запарка – у них этих планов еще больше. Но, поскольку они находятся на правой стороне V, то об этом я говорить не буду.

Кстати, я совершенно забыл рассказать об основополагающем принципе разработки такого ПО – это V-Model. Вот так она выглядит:

Итак, с левой стороны располагаются программисты. Они изучают требования, разрабатывают дизайн ПО, архитектуру, пишут документацию и, собственно, сам софт. Параллельно им, отдел тестирования пишет тесты на системные требования, архитектуру, интеграционные тесты и на ПО. В этой модели существует принцип независимости: программисты (и их начальство!) не могут указывать тестерам как именно (и с каким результатом) надо писать тесты, а тестеры, соответственно, не указывают программистам как писать софт. То есть, задача тестеров – найти проблемы в ПО, причем, не исходя из того, как именно программист это самое ПО написал, а исходя их требований к ПО.

Каждый шаг в V-Model сопровождается написанием довольно большого количества документации (нет, автоматически сгенерированные в Doxygen документы не будут приняты аудиторами и, кстати, самодокументирующийся код тоже).Типичный проект по классу А будет иметь 25 документов, по классу B – 35, а по классу C – 40 и больше.

После того, как код написан и проверен программистами (кстати, написание unit test программистами абсолютно необязательно для классов А и B, обычного «работает-не работает» достаточно), код передается тестерам, который выполняют тестирование. Тестирование может быть формальным (под запись) и неформальным (например, когда тестер просит билд, чтобы проверить свой же собственный тест). Тесты, кстати, пишутся обычно в паре – один тестер пишет, а второй потом проверяет работоспособность написанного, причем, это должно делаться в какой-то системе, которая записывает все действия и комментарии всех пользователей. Это называется Audit Trail.

6.3 Agile или Waterfall?

Важно понимать, что стандарт не определяет как именно будет проходить процесс разработки. То есть, V-Model похожа на «водопад» (waterfall), но абсолютно никто не мешает представить процесс в виде нескольких мини-V, каждый из которых будет спринтом в терминологии Agile. Другое дело в том, что я, будучи сертифицированным специалистом по Agile (Safe4 Practitioner) еще ни разу не видел успешный проект в Safety-Critical, выполненый по этому процессу, но это просто мои личные впечатления.

6.4 Отличия от обычного ПО

Итак, отвлечемся от процесса разработки и поговорим о, собственно, ПО. Как правило, есть несколько основополагающих принципов, которые могут (в зависимости от класса ПО) применяться при разработке.

Сомневаться во всем!

Представьте себе, что ваше ПО должно перемещать какую-то механическую деталь из одного положения в другое. ПО дает команду мотору переместить ее, но насколько вы уверены, что она действитель переместилась? Ну да, мотор вроде бы совершил 10 оборотов, но он точно не застрял? А деталь точно ушла из стартовой позции туда, где она должна быть? А она точно не переместилась за эту позицию? Не застряла на полпути? Так вот, ваше ПО должно будет делать множество проверок, перед тем, как решить, что деталь действительно перемещена.

Применять стандарты кодирования

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

Fail-safe или Fault-tolerant?

Думаю, что многие знакомы с этими терминами, но, на всякий случай, я напишу, что они означают.

Fail-safe означает, что система сможет отследить неполадку в самой себе (неважно, в ПО, электронике или механике) и предпринять действия по безопасному отключению системы. Например, если ПО в панели приборов автомобиля определит, что датчик топлива, по какой-то причине, не функционирует, то загорится предупреждающая лампочка и вы будет знать, что топливомер не работает. То есть, это безопасный отказ системы, при которых функционал этой системы доступен не будет.

Fault-tolerant означает, что при обнаружении ошибки, какой-то функционал (как правило, минимально необходимый) будет все равно доступен. Например, при обнаружении проблем в тормозной системе автомобиля, тормоза не отключатся, а будут все равно доступны, пусть даже и без дополнительных наворотов типа ABS. Это делается потому, что функционал этот жизненно необходим и его утеря может привести к смерти человека. Как правило, системы Fault-Tolerant относятся к наиболее высоким классам ПО.

Будем рисковать?

Одним из основополагающим принципов разработки такого ПО является анализ рисков и управление ими. Грубо говоря, функционал системы раскладывается на составляющие и группа программистов анализирует каждый программный блок, пытаясь понять, к чему приведет ошибка в данном блоке. Не всегда можно устранить такие риски программно, иногда приходится идти на поклон к электронщикам или механикам. В особо запущенных случаях можно обращаться к отделу технического надзора, чтобы они прояснили как именно можно устранить возникновение рисков с помощью документации или обучающих материалов.

Читать стандарты!

Чтение (и понимание) отраслевых стандартов вовсе не прерогатива начальства или отдела качества. Программисты должны быть ознакомлены с такими стандартами (я опять про медицину) как IEC62366 (юзабилити при разработке интерфейсов пользователя) или IEC60601 (электромагнитное излучение и способы борьбы с ним).Я уж не говорю про ISO14971 (управление рисками)!

Один из классических примеров – использование цветовых маркеров в интерфейсе пользователя. Например, если произошла системная или пользовательская ошибка, нельзя использовать красный цвет, только оранжевый. Почему? Да потому что красный означает критическое состояние пациента или угрозу его жизни! Это все прописано в стандартах, так что читать их необходимо.

Минимизировать использование SOUP!

Я не думаю, что многие знакомы с этим термином, обозначающим Software Of Unknown Provenance (то есть, софт неизвестного происхождения). Для тех, кто занимается разработкой ПО стало нормой пользоваться open source или другими разработками, в том числе и коммерческими. Проблема в том, что любое такое ПО априори считается «плохим» и чтобы доказать, что оно «хорошее», надо его формально тестировать. Исключение есть только в том случае, если разработчик этого ПО предоставит сертификат на соответствие отраслевому стандарту (например, можно купить среду разработки IAR в варианте Functional Safety, со всей документацией и сертификатами на библиотеки, но обойдется такой вариант почти в два раза дороже, чем он же, но без сертификатов).

Для формального тестирования, программист должен будет написать список требований к SOUP, объяснить, почему он не может жить без вот именно этой библиотеки сортировки массивов и передать тестерам SOUP и документацию для формального тестирования, причем, не факт, что они не найдут в ней ошибок. В общем, это долго и дорого – иногда проще переписать чью-то библиотеку самостоятельно, чем заморачиваться со всем этим SOUP

Ограничить зоопарк средств разработки

Одной из вещей, на которую сразу будут обращать внимание аудиторы – это список используемых средств разработки. Им, в общем-то, плевать на такие вещи, как Office 365, но если версия Visual Studio у разработчиков Васи и Пети будет разной, то черная метка фирме обеспечена. Надо принять, как должное, что каждое средство разработки должно пройти формальную валидацию на предмет соответветствия заявленному качеству и функционалу, причем, процесс примерно такой же, как и с SOUP – требования, формальное тестирование и управление рисками. Поэтому проще всего ограничиться только минимально необходимыми средствами разработки и понимать, что если изготовитель сегодня выкатил новую версию, то надо сразу же проводить апгрейд. Вы, конечно, можете его провести, но не факт, что руководство фирмы не решит вслед за этим провести еще один апгрейд, сменив слишком продвинутого программиста на того, который понимает ограничения процесса.

Общаться с другими участниками группы разработки

Под «разработчками» я понимаю не только программистов, но и тестеров, электронщиков, механиков, производственников, отдел качетсва, отдел надзора и бизнес-менеджеров. Вы все в одной лодке и отсутствие потока необходимой информации может привести к катастрофе. Например, вы провели анализ рисков и выяснили, что вам жизненно необходимы сенсоры, которые будут отслеживать положение перемещаемой механической детали из предыдущего примера. Если вы про это не скажете электронщикам, то они не внесут изменения в схему. Механики не придумают куда физически поставить эти сенсоры. Бизнес-менеджер не узнает, что стоимость конечного продукта возрастет. Производственники не успеют закупить сенсоры (иногда требуется разместить сильно заблаговременный заказ, например, за полгода). В общем, вы все в одной лодке и без понимания этого, ничего толкового не выйдет!

7. Заключение

В этой статье я попытался привести базовые сведения о процессе разработки ПО критичного к безопасности. Замечу, что этим сведения далеко не исчерпывающие, так что, скорее всего, у вас будут вопросы, на которые я постараюсь ответить.