Архитектура систем управления самолётом

    «Мы работаем для того, чтобы вы не боялись летать»

    image
    рис 1. Модель Bombardier BD 500 в аэродинамической трубе

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

    К моему удивлению, моя предыдущая статья вызвала неожиданно большой резонанс как на Хабре, так и за его пределами. Мне задали ряд вопросов и высказали ряд недовольства, законно обозвав это «закрытой областью». Вопреки такому мнению, всё, о чём я рассказывал в статье и о чём речь пойдёт в этой, можно найти в интернете. Быть может по разрозненным кускам, быть может, на разных языках, но ни один факт не является ноу-хау. Задача моей статьи — познакомить читателя с замечательной областью авиации и классифицировать весь опыт и знания, которые мне удалось накопить. Что же касается проблемных тем и вопросов, затронутых мной, хочется вспомнить схожий случай, описанный г-ном Фейнманом в замечательной книжке «Какое тебе дело до того, что о тебе думают другие?». Если кто не читал, то обязательно прочтите. Там Ричард рассказывает о проблемах в НАСА. О проблемах, которые привели к крушению челнока. И о том, что не всегда бывает виновато оборудование, программы, программисты их писавшие, а часто виноватыми оказываются допуски, сокрытие фактов и принятые консервативные решения. И знаете что? НАСА из-за этого случая и огласки не стало хуже, а лишь научилось на своём хоть и печальном, но опыте. Престиж не только не упал, но вырос, НАСА показала себя организацией, которая умеет решать проблемы и признавать их. Потому что как космос, как и авиация — великолепные области, в которых работают великолепные компании и преданные люди. И не верьте тем, кто говорит, что после установки туалетов в самолётах небо перестало быть местом для романтиков.

    Automation is great. It’s essential. It reduces fatigue, and enhances safety. But what if it breaks?

    Все вы конечно знаете, что законы Мерфи работают, и один из них гласит, что всё, что может сломаться — сломается. Всё, что не может сломаться — тоже сломается. Каков бы не был низок процент отказа оборудования, вероятность отказа существует. Но существуют методы, позволяющие эти отказы минимизировать. И, в первую очередь, это архитектурные особенности программно-аппаратного комплекса.

    image
    рис 2. Т-4

    Современный самолёт управляется так называемой ЭДСУ — Электродистанционной Системой Управления. На самом деле, это не такая уж новинка. Впервые такая система была установлена на советском самолёте «Максим Горький», управляющая поверхностями путём передачи электрического тока (аналоговая ЭДСУ). Позже в военной технике она появится в полностью цифровом виде на советском Т-4, а в гражданской авиации — на Airbus A320 и Ту-204. Тем не менее, ни что не стоит на месте и технологии совершенствуются, разрабатываются новые подходы и достигаются новые уровни безопасности.

    ЭДСУ



    Что представляет собой ЭДСУ? В первую очередь, это программно-аппаратный комплекс, состоящий из:

    • Приводов управляющих поверхностей самолёта
    • Датчиков контроля
    • Системы управления
    • Системы индикации и вспомогательных систем
    • Системы коммуникации и силовой системы


    Каждая из систем обычно как минимум дублируется один раз. В зависимости от требуемых законов управления, ценовых и компоновочных решений архитектура может варьироваться — содержать больше контуров дублирования, контроля, силовых контуров, или же, напротив, меньше. А так же возможны комбинации ЭДСУ и механической, гидромеханической систем управления.


    рис 3. структурная схема ЭДСУ

    Использование ЭДСУ в первую очередь обеспечивает значительное уменьшение веса системы управления, что на больших самолётах имеет критическую важность. Так же даёт более гибкие возможности компоновки, часто позволяет расположить систему управления практически в любом доступном месте самолёта. Кстати говоря, поэтому управление по проводам (fly-by-wire) всё ещё является наиболее популярным, т. к. является не столь сложным и капризным, как fly-by-light (с использованием оптики ) или fly-by-wireless (с использованием беспроводных технологий). Уменьшение веса и упрощение компоновки позволяет ввести дополнительные контуры, обеспечивающие нормальное управление самолётом в состоянии отказа одного из работавших ранее контуров. Позволяет по возможности уменьшить человеческий фактор, контролируя параметры полёта в автоматическом режиме и корректируя команды пилотов. Контролирует состояние критических систем самолёта в режиме реального времени, что позволяет обнаружить, отследить и по возможности исправить ошибку в минимально возможное время.


    рис 4. функциональная схема ЭДСУ

    Тем не менее, в процессе проектирования таких систем критически важно создать правильную архитектуру. Это — наиболее уязвимое место ЭДСУ. Наиболее классическими случаями ошибок являются:

    • зависимость системы от электропитания, что в случае механического управления является катастрофой, но не ведёт к потере управления всем самолётом (посадка Ту-154).
    • неверное дублирование системы управления (инцидент с Ан-148)
    • «глупые» ошибки ПО, например такие, как смена знака при пересечения экватора или часовых поясов, возможность отрицательной скорости на гражданском самолёте и пр.


    Какой бы ни была архитектура систем управления, их объединяет следующие вещи:
    • дублирование управления
    • наличие ответного сигнала (feedback)
    • система самоконтроля (разделение на управляющую и контролирующую часть).


    К сожалению, не имею представления о технологиях, которые были применены в советских самолётах, но думаю, он схож с современным подходом, который справедлив и для иностранных, и для российских проектов.

    Система управления



    Типичная система управления состоит из:

    • PFC – Primary Flight Computer — центрального компьютера управления, в который включены все законы управления и который умеет анализировать все поступающие данные от датчиков и feedback и отдавать данные на исполнение электроникой. PFC в самолётах бывает как 1 (в наиболее либо простых, либо дешевых системах), как 2, так и 3. PFC работают в штатном режиме сообща и одновременно.
    • ACE – Actuator Control Electronic — исполнительные модули контроля актуаторами (приводами). Включают в себя часть логики управления поверхностью на случай отказа основного компьютера. Передают непосредственно команды на исполнения актуаторами. В зависимости от типов как бывают спроектированы как для управления электроприводами, так и гидравлическими. Любой ACE так же в зависимости от архитектуры дублируется.ACE при наличие дублёра работают попеременно.
    • Ручек управления (штурвал\ручка (sidestick), педали и пр.).
    • Индикаторов \ информационных экранов.
    • Актуаторов.
    • Силовой электроники (если не включена в модули управления).



    рис 5. ЭДСУ Boeing 777

    В зависимости от сложности системы могут быть добавлены дополнительные устройства \ разделены существующие. В любом случае, при правильном дублировании и проектировании системы главный принцип — это соблюдение принципа «различия» (dissimilarity), что означает, что для каждого элемента работающего в режиме дублирования дожна быть применены различные электронные компоненты, процессоры, языки программирования, написан разный код, а соединяющие провода проложены независимо разными путями.

    Электроника управления


    Компьютеры управления (PFC) и исполнительные модули (ACE) состоят в свою очередь из нескольких независимых каналов. В простейшем случае они состоят из канала управления, который вычисляет команду к исполнению (Control Channel) и канала контроля, который проверят правильность команд (Monitor Channel). Для простоты можно сказать, что первый должен выдавать наиболее точные данные, рассчитанные с использованием сложных законов управления, базирующихся на динамических моделях поведения самолёта, а второй — давать правильную оценку на основе оценки окружающей обстановки, поступающей от датчиков с принимая и допуская некий «усреднённый вариант», но делая это быстрее канала управления, имея возможность заблокировать новый неверный сигнал до того, как пройдёт команда к исполнению и обработать ошибку.


    рис 6. архитектурная схема PFC для Boeing 777

    В зависимости от проекта применяется разное число модулей и разные комбинации каналов внутри них. В Boeing-777, например, три главных компьютера по три канала в каждом. Причём каждый канал может исполнять разные роли, но неизменно один из них — канал управления, а два других — контроля. В Boeing, к примеру, популярна схема с 1 MC, 1 CC и 1 канал горячей замены (standby). В других компоновках так же могут быть отдельно вынесен канал для управления силовой электроникой, или для целей наладки и проектирования — платы расширения функциональности (Extender Board) или внедрения ошибок (Fault Insertion Board). Общение между каналами обычно происходит по шине CAN или любой другой достаточно быстрой шине, такой как spacewire, 1394 и пр… Главный критерий — скорость передачи данных.

    Общение же между модулями управления и периферии в авиации традиционно принято осуществлять через шину ARINC. В общем случае главный критерий — надёжность даже при больших расстояниях.


    рис 7. Упрощённая схема типичной реализации системы управления

    Так же используются непосредственно аналоговые и цифровые сигналы. Классической компоновкой является применение ADC \ DAC (аналого-цифровых и цифро-аналоговых конвертеров) внутри ACE для опроса датчиков и для командования приводами, а так же с использованием Resolver'ов для их чуткого управления. Использования дискретных сигналов — для синхронизации (в т.ч. от тактовых генераторов), пин-кодинга (определения положения и роли модуля) модулей. Модули, как правило, знают о состоянии друг друга и во многих случаях архитектура подразумевает «горячий» старт, когда резервный модуль подхватывает состояние главного и переходит в режим активного, заменяя прошлый главный модуль в течение пары секунд. ACE и PFC являются модулями LRU (Line Replaceable Unit), т. е. модулями линейной замены, что подразумевает собой возможность заменить один модуль (как плату расширения) на подобный без необходимости замены (модификации) всей связной системы. Схожая архитектура используется и для компоненов системы в отдельности, для таких система управления шасси, гидравликой, люками.

    Принятие решения на основе совместной работы различных устройств — это сложный вопрос, на который нельзя ответить однозначно. Есть разные пути решения: синхронизация, решение методом среднего с использованием данных о состоянии (об ошибках), пути обнаружить неисправные модули и отключить их, сценарии работы. К примеру, при использовании трёх PFC при наличии двух одинаковых команд и одной отличной — отличная будет отбракована. При трёх разных — система будет отключена, как и при разных показания в системе, использующей только два PFC. Различных логик может быть много, как и включая алгоритмы работы при дублировании ЭДСУ механической системой управления. В последнем случае вероятность отказа возрастает, т. к. при сбое механической системы управления должна быть информирована ЭДСУ об отказе и среагировать на это переходом в аварийный режим.


    рис 8. Схема парного исполнения ACE для электрогидравлической системы

    Режимы работы.


    В зависимости от окружающей обстановки система может функционировать в различных режимах. Типичными режимами являются:

    • Init Mode – режим загрузки устройства, который обычно включает определение состояние устройства путём синхронизации и проведения встроенных и внешних тестов.
    • Normal Mode – штатный режим, в котором процесс полёта контролируется основными компьютерами и команды пилота корректируются в соответствии с законами управления. Например, это позволяет запрещать недопустимые комбинации команд — запрещает критические углы атаки, крена, газа, запрещает недопустимые команды (например выпуск шасси в воздухе), а так же демпфирует поверхности в зависимости от внешних параметров (ветра, тяги двигателей, особенностей планера). В штатном режиме команды от PFC посылаются на безусловное выполнение ACE с оговоркой, что ACE проверяет валидность сигналов путём опроса статуса о PFC. Так же иногда разделяют нормальный режим на режим полёта (in air) и на режим на земле (weight on wheel), который может в свою очередь может быть разделён на режим стоянки, такси, взлёта\посадки. По современной классификации некоторые системы управления в режиме Normal Mode могут быть отнесены к IFCS (Intelligent Flight Control System – Умным Системам Управления). Как повод для гордости, могу отметить, одна из первых и лучших в гражданской авиации, чтобы обеспечивать полёт как по рельсам разработана для Sukhoi Superjet, а не в более именитых её собратьях. В будущем, надеюсь, такие системы будут использовать вс мощ искуственного интеллекта под своим контролем.
    • Alternative \ Secondary law – особый режим, позволяющий комбинировать логику ACE и PFC, либо замещать нормальные законы управления заранее откалиброванными. Это особый режим(ы), который типичен для самолётов Airbus \ Boeing в случае когда надо добиться нетипичного поведения самолёта либо в особых, но некритичных случаях (в режиме пониженного энергопотребления, дефекта поверхностей).
    • Direct mode — режим прямого управления. Этот режим управления без использования PFC, путём передачи прямых команд от органов управления к ACE. В действительности он является виртуально прямым, т. к. если ACE функциональны, то они имеют ограниченные законы управления и трансформации получаемых от пилотов сигналов. В случае потери ACE, теряется так же и полностью поверхность.
    • Mechanical law – режим механического управления. Возможен в случае наличия резервной механической системы управления. Его всё реже можно встретить на самолётах, но, тем не менее, обеспечивает управление некоторыми поверхностями даже в случае потери ACE.
    • Failsafe mode – режим отказа, сигнализирующий об отказе устройства или критичных систем, которые к нему относятся. Обычно является следствием отказа как внутри оборудования (аппаратного или программного), либо подконтрольних устройств. Тем не менее, может быть разделён на критичный — когда выход возможен только путём наземного обслуживания и\или замены оборудования, и на исправимый отказ, который может быть возвращён в рабочий режим (Direct, Normal, Alternative – в зависимости от логики) путём диагностики системы или её полётного перезапуска.
    • Rigging (Calibration) Mode – режим обслуживания, калибровки оборудования на земле — изменение калибровочных параметров самолёта (к примеру в зависимости от геометрии или имевших ранее отказов на самолёте). Обычно инициируется на земле в регулярном порядке (тех. обслуживание) или после ошибки (падения в Failsafe mode). Обслуживание производится как со снятием модуля и считывания данных через внутренние порты (RS232, USB), так и непосредственно на самолёте с использованием терминала (RS232, LAN), либо OMS (Onboard Maintenance System) через USB, COM, LAN.



    рис 9. схема работы с четыремя PFC

    Ещё раз про дублирование и защиту



    Чтобы не вдаваться в технические подробности и конкретные реализации, кратко подытожу: каждая система дублируется. Так, помимо модулей управления, дублируются цепи питания (три и более), магнитные замки, датчики, сообщения от устройств, ручки управления. Каждая информация требует подтверждения. Так, для диагностирования ошибки в зависимости от её критичности требуется время для её подтверждения (чтобы не отключить систему раньше времени из-за помехи), обычно с разных устройств сразу. Даже в случае отказа или даже множественных отказов есть возможность осуществлять управление в альтернативном режиме. Это достигается путём использования различных аппаратных и программных средств. Так, для одного и того же устройства используются различные процессоры и схема платы для разных каналов. Например, для Control Channel — процессор от Motorola, а для Monitor – от Infineon, для другого LRU – от Texas Instruments и т.п… Используются различные компиляторы, пишется разный код. В идеале для разных PFC \ ACE должны быть так же разные программно-аппаратные решения, но в простом случае (это не всегда возможно и целесообразно как в техническом, так и финансовом плане) dissimilarity достигается различным пин-кодированием и различным расположением модулей в пространстве. Система в идеале защищена «от дураков». В первую очередь — от человеческого фактора. В последующие — от критических условий (режимов короткого замыкания, потери питания, высоких и низких температур), а так же от невозможного события по Мерфи. В коде это выливается, к примеру в пароноидальное программирование.


    рис 10. четыре PFC разбиты на пары

    Код


    static bool_t CANInterface_StripStatusData (CanMsgFrm_t * CanRxMsg_ip)
    {
    /*#FUNCTION_SIGNATURE# CANInterface_StripStatusData */
    bool_t bSuccess = TRUE;
    
        /* Extract data from message ID 0xN using following layout:                              */
        /* ------------------------------------------------------------------------------------- */
        /* |  Layout  |  Range |       Name        | Unit Ident | Description                  | */
        /* |-----------------------------------------------------------------------------------| */
        /* | Byte 0   | 0, 1   | ConsNgWow         | 1, 2       | Consolidated Nose Gear       | */
        /* | Bit 0    |        |                   |            | Weight on Wheel              | */
        /* |-----------------------------------------------------------------------------------| */
    
    /* If data is send trough valid pointer */
    if (CanRxMsg_ip EQU_C NULL_C)
    {
    bSuccess = FALSE;
    }
    else
    {
    /* Process, only if unit is valid */
    /* There is no data clipping and loss, we extracting only actual bits from message. */
    if (cUnitIdent_g EQU_C UNIT_IDENT_UNIT1_E)
    {
    bConsNgWow_g = (bool_t)(CanRxMsg_ip->Message.cUint8_a[ZERO_C]
    & BITMASK_ONE_BIT_C);
    /* … */
    /* Other bits are spare here, not used in this message */
    }
    else if (cUnitIdent_g EQU_C UNIT_IDENT_UNIT2_E)
    {
    bConsNgWow_g = (bool_t)(CanRxMsg_ip->Message.cUint8_a[ZERO_C]
    & BITMASK_ONE_BIT_C);
    }
    else
    {
    bSuccess = FALSE;
    }
    }
    return(bSuccess);
    /*#end ACD# CANInterface_StripStatusData */
    }
    


    Знакомые с типичным Coding Standard узнают выполнение обычных правил в этом коде. Вообще такой код не самый хороший и оптимальный, тем не менее он гарантирует исключение невозможных ситуаций:
    1. функция не может вызваться с нулевым указателем, т. к. ей передаётся адрес объекта. Тем не менее есть проверка на отличие указателя от нуля. На моей практике встречались ошибки с невалидным указателям не раз, которые могли проявляться на одной машине даже при нормальной работе стека, а на другой никогда и ни при каких обстоятельствах.
    2. Все магические номера заменены константами на случай, что если когда-то изменится архитектура, не нужно будет отслеживать изменения, а так же оттого, что сложнее что-то поломать выполнив случайную контекстную замену.
    3. обязательное приведение типов, это MISRA-правило, которое наряду со своей частой неоправданностью позволяет отловить signed\unsigned conversion и sign loss.
    4. битмаска на один бит выглядит идиотством, ибо bool в данном случае может быть только true или false. Но, тем не менее, при последующем изменении кода можно гарантировать, что даже если в эту область памяти будет записано что-то другое, это останется ожидаемой 0 или 1, да и при сдвиге на несколько бит актуальной позиции — это изоляция от прочих значимых битов.
    5. возврат статуса, даже если функция не делает вообще ничего и её работа не влияет на систему позволяет диагностировать возникшую проблему с точностью до функции.
    6. описание всех вариантов, даже если это дублирующий код. Помимо требования к софту A, из-за особенностей компиляторов код с использованием одной инструкции if-else может интерпретироваться не так, как ожидается, тем более при внесении изменений может быть допущена ошибка или не отработана ситуация с невозможным идентификатором PFC. В случае если код дублирующий, обычно оптимизации компилятора его компонуют сами. Dead Code же напротив, следует избегать всеми возможными средствами, за исключением deactivated \ conditional (project\build-specific) кода.
    7. стандартные типы не должны использоваться, чтобы предотвратить ошибки связанные с особенностями платформ и компиляторов
    8. должна соблюдаться венгерская нотация, чтобы обеспечить достаточный уровень ясности кода даже без использования специальных IDE.
    9. код должен содержать ясные комментарии
    10. код должен быть быстрым и не требовательным к ресурсам

                  /* convert label */
                  nTmp = (uint16_t)ArincData.Octet.nByte0;
                  nTmp = ((nTmp & 0x55U) << ONE_U_C)  | ((nTmp & 0xAAU) >> ONE_U_C);
                  nTmp = ((nTmp & 0x33U) << TWO_U_C)  | ((nTmp & 0xCCU) >> TWO_U_C);
                  nTmp = ((nTmp & 0x0FU) << FOUR_U_C) | ((nTmp & 0xF0U) >> FOUR_U_C);
                  /* write converted label back */
                  ArincData.Octet.nByte0 = nTmp;
    
    Инвертирование бит с алгоритмом Уоррена.

    Выводы



    На этом, пожалуй, стоит завершить статью и эту тему в частности. В заключение хочу сказать, что какова бы ни была система, решения — сложные как у Boeing или простые, как на начинающем китайском авиопроме, системы развиваются в сторону удобства и безопасности. И каждый защищённый провод и бит — труд многих людей, зачастую энтузиастов, работающей в этой области, а так же вас, граждане пассажиры, которые своей любовью к нему и своей критикой к человеческому несовершенству делает эту жизнь лучше.

    P.S. кстати говоря, во время написания этой статьи выяснилось, что ПО управления Boeing 777 написано на ada.
    Share post

    Similar posts

    Comments 52

      0
      Во всех картинках меня напрягают одиночные провода.

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



      Когда я не вижу вот этой характерной сетчатки на графике, мне становится тревожно.

        +19
        Блин, три четверти статьи про дублирование механизмов, кода, методы контроля и обработки ошибок — а тут, оказывается, «провода не в сеточку». Текст-то читали?
          –4
          Читaл. Проблема в том, что если хотя бы в одном месте есть узел, принимающий решение в единственном числе (например, компаратор, который должен сказать, какой из узлов «неправильный» — а сам единственный), то это приводит к точке отказа.

          Кстати, ровно то же касается и каналов связи.

          И вот что мне поразило глаз — это узлы, к которым идёт единственный канал связи, или которые стоят в единственном числе.
            +10
            Вы, по-видимому, невнимательно читали.
            • связи так же дублируются. На обзорных схемах это обычно пропускают. Но например схематично это есть на рис 6. для PFC. Не всегда, правда по разным каналам передаётся одни и те же данные, да и это особо не нужно.

              Рассмотрим пример. Возьмём сферический ACE в вакууме от сторонней компании-поставщика электроники контроля. Что и как в остальной системе сделано — неизвестно. В нём, допустим, согласно тех заданию есть помимо внутренних связей для самодиагностики (общение между CC и MC так же продублировано двумя CAN), есть три входных канала ARINC. Назовём их для простоты PFCC(Channel)1, 2 и 3 соответственно. По ним передаются управляющие команды от главных компьютеров управления. А может быть это один компьютер, но вычисляющий трёмя разными способами? Нам не известно, но у нас три шины ARINC. Помимо этого у нас требуется ещё служебная шина ARINC для того, чтобы узнать, что происходит вокруг. Ведь как известно, подчинённые на местах осведомлены о состоянии гораздо лучше руководителей. Назовём такую шину DMC (Data Maintenance Channel). Итак, что мы имеем в итоге?

              У нас есть четыре физически независимых канала. По каждому из которых приходят команды. Рассмотрим следующие ситуации:

              1) Обрыв связи одного из PFCC не вызовет потерю управления. Тем не менее, в худшем случае это не объясняет, отключена ли система и два других дают неверную информацию, либо просто сломан один из каналов. Это решается тем, что: по каждому каналу идёт свой сигнал управления. В идеале они должны совпадать. Однако, PFC так же общаются друг с другом, поэтому знают о состоянии каждого из них. Каждый из PFC отсылает информацию о состоянии себя и других ACE. В этом случае принятие решения будет примерно таким:

              ((PFCC1 Command * PFC1 Valid) + (PFCC2C * PFC2V) + (PFCC3C * PFC3V))/Voter rule = ACE command

              В такой реализации принятие решения перекладывает на ACE. Он по сути является Voter'ом. Однако, в зависимости от режима и архитектуры может быть и такой вариант, когда три PFC приняли решение:

              (Consolidated PFC Command) ^Comparsion rule^ (Ace command) = Ace final command

              В зависимости от режима работы ACE выполняет как самопроверку, так и воплощает собой реализацию «доверяй, но проверяй». Хотя есть режимы и bypass, когда данные ACE могут игнорироваться (за исключением фатальных сценариев).

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

              Тогда сообразно усечённым законам управления в ACE:

              (ACE Control Laws Result * ACE Valid) ^Comparsion rule^ (Consolidated PFC Command) ^Comparsion rule^ (Ace command) = Ace final command

              в одном из сложных вариантов.

              Т.е. система будет функционировать в режиме тяжелого отказа. Хотя конечно тут алгоритмы сложнее, они ещё должны учитывать внутреннее состояние, внешнее, режим работы.

              2) Отказ ACE. Это наиболее простой случай, т.к. обычно отказ ACE обнаруживается системой самодиагностики или через Feedback консолидацию от состояния поверхности и положения ручек.

              (Consolidated PFC Command) ^Comparsion Rule^ (Position Status ^Check^ Feedback) => ACE Validity

              В этом случае включается парный ACE при наличии. В случае потери двух ACE (или более, если они продублированы большим числом) — теряется вся поверхность.

              Итого:

              1) в безопасной архитектуре все связи продублированы, в том числе каналы передачи данных, быть может, за исключением связей с некритичными системами и узлами (таких, как единичные датчики, вторичные системы)
              2) архитектура должна избегать «единственного узла» связи, функциональность должна частично дублироваться. Система не содержит внешних, не входящих в вычислители Voter'ов. Решение принимается всегда сообща, в том числе на разных уровнях системы. За исключением специальных режимов, например таких, как Direct Mode.
              0
              Компьютерным системам бы такую избыточность всех узлов, не ложились бы датацентры и хостинги… Ну а про качество кода, я думаю, и упоминать не стоит
                +3
                … и стоили бы они как самолёты :)
                  0
                  Вы не поверите… Но некоторые компьютерные системы стоят буквально как самолёты :)
        +5
        Прочитал статью. Слава богу, в стране есть ещё настоящие инженеры. Спасибо.
          0
          подозреваю, что некоторые вещи дублировать не получится. Например, протоколы, по которым системы общаются между собой. Или протоколы, по которым происходит их переключение с одного контура на другой.

          Как решается эта проблема? Путём максимального упрощения протоколов чтобы избежать потенциальных ошибок?
            0
            В том числе путём упрощения. Например новые версии протоколов ARINC хороши, но не всегда используются, т.к. не атомарно просты, в отличие от топорных и старых. Но всё-таки главными являются решения, о которых я ответил двумя комментариями выше. Для протокола, даже если он единственный, существуют разные сигнатуры для подписей сообщений и\или различная калибровка на разных каналах (скорость, чётность и т.п.).
            +4
            Почему в последнем примере nTmp & 0x55U, а не nTmp & FIFTYFIVE_U_C? Почему только операция сравнения заменена на EQU_C? С тем же успехом можно проморгать bSuccess == FALSE;

            Я не придираюсь, просто интересно, осознанный ли это выбор или «так вышло».
              0
              >Почему в последнем примере nTmp & 0x55U, а не nTmp & FIFTYFIVE_U_C?
              Потому, что NULL_C в зависимости от компилятора и стандарта может быть заменено, например на NULL или nullptr. А 0x55U в любом компиляторе и стандарте останется 0x55U. Заводить дефайты на все числа от нуля до бесконечности — хлопотное дело.

              >Почему только операция сравнения заменена на EQU_C?
              Я так думаю, по тем же причинам, почему пишут if (5 != a ). Чтобы в условии не написать присваивание случайно.
                0
                >А 0x55U в любом компиляторе и стандарте останется 0x55U
                Угу, а при каких условиях TWO_U_C и FOUR_U_C будут не 2 и 4? О том и речь, что хлопотно, но не понятна выборочность.

                >Чтобы в условии не написать присваивание случайно
                Это-то понятно. Но если мы не доверяем предупреждениям компилятора в сравнении, то почему не боимся делать похожие ошибки: nTmp && 0x55U, bSuccess == FALSE?
                  0
                  Выборочность определяется тем, что NULL — это условность, абстракция, которая может быть 0, 0L, NULL, nullptr в зависимости от обстоятельств. А «55» — это число 55, в любом компиляторе и стандарте, всегда и везде.

                  На счет «мы не доверяем предупреждениям компилятора» — ага, не доверяем, потому что не все компиляторы и не на всех уровнях их показывают. Почему мы не боимся делать «bSuccess == FALSE» — потому, что символа "==" в коде быть не должно, это может легко проверяться каким-нибудь статическим анализатором. На счёт «nTmp && 0x55U» — нет идей.
                0
                Вы совершенно правы.

                Тем не менее существуют некоторые послабления. Которые, как в этом swap-примере из-за требований уровня B, а не A. Например, послабление из-за того, что магические числа не всегда надо определять константами, в случае если они используются единожды в коде.

                Все требования исходят из Coding Standard. Что и когда применять. В том числе и замена операторов.
                На самом деле, такой подход просто позволяет избегать ошибок во время кодирования. Во время сборок код полностью вычищается от Warning'ов компилятора и от error\warning\fail'ов статических анализаторов. А потом код ревью и всё что я писал в прошлой статье.
                +1
                По-моему большую часть этого кодстайла (который превращает Си в несколько другой язык) можно заменить набором warnings-as-error. И это будет лучше, так как проверяется автоматически. А соответствие кодстайлу надо ревьюить.
                  0
                  В-общем так и есть. Но некоторые ошибки не отлавливают ни компилятор, ни static checker, но тем не менее, некритичные для них ошибки являются ошибками для конечного представления кода сертификационной комиссии.
                  +5
                  «Мы работаем для того, чтобы вы не боялись летать»
                  Анализируя причины падений самолетов могу сказать что страхи порождает не то, как устроена авионика, а то, кто им (самолетом) управляет. Как на самом судне, так и с земли.
                  За статью спасибо.
                    +3
                    Да, частично ЭДСУ позволяет уменьшить человеческий фактор. Например после инцидента над Боденским озером командам электроники о столкновении был присвоен приоритет выше, чем командам человека. К сожалению, любую защиту от дурака более глупый дурак поломает: принудительно перейдет в Direct Mode против Normal, или же попросту выдернет шнур, разрубит топором связку проводов, чтобы не мешала назойливая индикация.
                    Тут помимо вопроса недоверия к человеческому фактору и вообще исключения человеческого фактора ещё немаловажна проблема обучения персонала, если не управляющего, то контролирующего. Как бы ни была умна и надёжна техника, пока во главе её должны стоять более умные существа — люди разумные.
                      +5
                      Программирование сегодня — это гонка разработчиков программ, стремящихся писать программы больше и с лучшей идиотоустойчивостью, и вселенной, которая пытается создавать больших и лучших идиотов. Пока вселенная побеждает.
                      — Rick Cook
                    +1
                    > что ПО управления Boeing 777 написано на ada.
                    777 был сделан в начале 90х. Пик расцвета Ады в тамошнем ВПК и связанным с ним отраслями.
                    До СССР краешком дошло, ходил по ящикам какой-то транслятор для СМ4 неизвестно кем сделанный, но как раз в этот момент все навернулось медным тазом.
                      0
                      Вы много времени посвятили описанию как избавится от ошибок, это просто замечательно, однако вы же не можете избавится от всех них? И редкие ошибки остались, так вот как вы их отлавливаете?

                      На самолёте есть блок который следит за отказами других приборов и логирует их? или вы просто ждёте когда самолёт упадёт и только потом принимаетесь за поиск ошибок?
                        0
                        Есть, обычно для каждого блока электроники есть хранилище ошибок (faults) и предупреждений (warnings) в NVM (None Volatile Memory). Во время наземного обслуживания эти логи загружаются и анализируются. Не совсем уверен насчёт централизованного хранилища (уверен, оно есть — фатальные данные передаются, например в FMS (?)), но данные во время обслуживания загружаются со всего кабинета, и, если надо, то с каждого блока в отдельности. К каждой ошибке прилагается штамп времени, и если есть реализация — выдержка из параметров системы на момент ошибки.

                        Для некоторых реализаций, когда замечена ошибка или найдена особенность работы системы после её сертификации и во время эксплуатации; могут быть внесены изменения в систему без обновления ПО систем управления. Это так называемое Field Loadable Software. Встречается редко, не затрагивает жизненно важных параметров, правда, но позволяет немного подлатать самолёт до внедрения исправленной версии. Такое обслуживание, конечно, доступно только специальным инженерам по обслуживанию. Обычно из штата самих разработчиков систем управления.
                        0
                        А какие защиты бывают от хакерских взломов подобных систем?
                          0
                          :) Охранники с автоматами. Ну и связка пароля на девайс и пин-код для устройства обслуживания.
                            0
                            ПИН-код аппаратный, конечно же.
                          +2
                          C каждой статьей проникаюсь все большим уважением к отрасли! Спасибо!
                            +1
                            Гм, а если CanRxMsg_ip != null, и как это водится был передан указатель на освобожденный объект?
                              +1
                              Это интересная проблема. Или переполнение стека.
                              Как одно из возможных решений — Validity Pattern, который при инициализации\уничтожении выставлять уникальное магическое число и стирать его для каждой функции\объекта. Но вообще именно «освобожденных объектов» и вообще динамических объектов для безопасности стараются не использовать. Память выделяется \ освобождается и объекты создаются \ уничтожаются единожды, для надёжности критичные объекты жестко примаплены в девайсе.
                                –1
                                Странно, почему не передается reference или smart pointer? Если от второго отказываются из-за производительности, то уж по референсу NULL не передать никак.
                                  0
                                  1) Ссылок в C нет. Эта конструкция C++. В моём примере и в тех проектах, над которыми я работал, используется Pure C. Возможно, в проектах на C++ эта проблема решена именно ссылками.
                                  2) Smart Pointer — абстракция из стандартной \ boost библиотеки. Их, согласно требованиям авионики использовать нельзя в чистом виде. В виде Validity Pattern реализация может быть похожа на реализацию библиотечного smart pointer.
                                  +1
                                  А с переполнением стека как боретесь? И еще, предусмотрены ли таймауты на выполнение функций, чтобы избежать зацикливания?
                                    +1
                                    Для этого предусмотрены StackMonitor, OverrunMonitor (фреймы не должны перекрывать друг друга).
                                    В коде запрещены конструкции, ожидающие чего-либо без таймаута, за исключением ожидания системных\хардварных прерываний. Во время тестирования всё это проверятся с разным calltree. На это существуют определённые требования к системе — сколько времени должен занимать фрейм, насколько загружен стек и т.п… Обычно все реализации таких мониторов являются предупреждающими событие, т.е. ловят заполнение стека до его переполнение по меткам. Вообще всё, что может рухнуть и поломаться проверяется загодя, до того, как передан сигнал аппаратной ошибки (devision by zero, overflow, stak overflow, underrun, overrun).
                                      0
                                      division*
                                        0
                                        Используете ли вы какие-то open source решения для этих целей/выкладываете свои с открытым кодом? Я был бы очень рад например сертифицированному тщательно протестированному StackMonitor-у :)
                                          0
                                          К сожалению, код является закрытым.
                                          Прецедентов, чтобы какой-либо код открывали — не было. Во всяком случае во время эксплуатации самолёта, во всяком случае официально.

                                          Что касается использования open source решений, как я и писал раньше, если надо использовать что-то стандартное, оно должно быть переписано. Другими словами, просто анализируется существующее решение, оценивается его оптимальность (обычно оно максимально эффективно, но к нему добавляется дополнительная защита и проверки) и затем внедряется с изменениями в виде стиля кода.
                                            0
                                            Кстати говоря, реализация может существенно отличаться в зависимости от CPU. Хотя и стараются использовать код вторично, это не всегда эффективно. Например, в TMS320C28 есть свои рекомендации и механизма отлавливания Overflow против забития сигнатуры в область стека как c C166.
                                    +3
                                    Вдохновляющая, по сути, статья.
                                    Если уж с таким люди справляются, то в проектах где риска для жизни нет — можно сказать все совсем просто :)

                                    Спасибо!
                                      +1
                                      Прочитал про Столкновение над Боденским озером, жесть какая.
                                      Благодарю вас за вашу работу!
                                        –1
                                        Уважаемый, объясните мне, пожалуйста — какой смысл жевать кактус и писать всё на этом аде (это даже не С)? 9/10 всего написанного в том примере кода обеспечил бы рантайм какого-нибудь Erlang'а или компилятор какого-нибудь Haskell'а/OCaml'а.
                                          0
                                          1) Нужен сертифицированный по авиационным стандартам компилятор.
                                          2) Программы, написанные на Haskell, имеют значительный размер объектного кода и невысокую скорость исполнения. У меня нет данных, что написанный на этих языках будет так же хорошо транслироваться в байт-код и будет так же быстр для обеспечения жесткого реального времени ~3-4нс?
                                          3) Отсутствие кодогенераторов, UML-платформы (как минимум сертифицированной) под эти языки.
                                          4) Сейчас не так уж много программистов и тестеров сейчас знаете, работающих на этих языках.
                                          5) Код разный бывает, это лишь один из простейших примеров, призванных показать стилистику.
                                          6) Бедность языка и неуместность для работы с железками (а это 2\3 кода)
                                            –1
                                            >Нужен сертифицированный по авиационным стандартам компилятор.
                                            Вопрос желания.

                                            Откуда ваша цитата не знаю, люди пишут DSL'и, если уж прям hard realtime нужен: en.wikipedia.org/wiki/Atom_(programming_language) Кроме того, в каких именно местах у вас такие требования? К компьютерам, заведующим вентиляцией салона или выпуском шасси (процессами, которые происходят секунды, а то и десятки секунд)?

                                            Что касается кодогенераторов — вон чуть выше пример кодогенерации.

                                            >Сейчас не так уж много программистов и тестеров сейчас знаете, работающих на этих языках.
                                            Это задача о курице и яйце. Усугубляет её ужасающая трудоёмкость написания кода, подобного коду выше: для того, чтобы заменить строителей пирамиды руками на крановщиков, вам не нужны несколько сотен тысяч крановщиков, достаточно десятка.

                                            >это лишь один из простейших примеров
                                            Даже он дик.

                                            >Бедность языка
                                            Это ваше экспертное заключение?

                                            >неуместность для работы с железками
                                            Это как?
                                              0
                                              >>компилятор
                                              >Вопрос желания.
                                              Помимо желания это стоит больших денег и времени, которое тоже преобразуется во время. И без того дорогая разработка будет дороже.

                                              > Atom
                                              это замечательно, что есть такой Haskell. Теперь вокруг него надо выстроить техпроцесс, сертифицировать всё, написать стандарты, что тоже стоит денег. Бизнес не всегда благороден. Что это принесёт в конечном итоге? Через 5? 10 лет? Через 2? 3 проекта? В чём преимущества? Выгоднее ли это того, что есть? Думаю, не самые далёкие люди от техники такой анализ производят.

                                              >Кроме того, в каких именно местах у вас такие требования
                                              Вы точно читали статьи? Системы управления. Решения принимаются в зависимости за микросекунды, чтобы парировать ветер, чтобы избежать ошибки, если дрогнет рука пилота. Да даже если шасси, если они не выпустятся при посадке, то поднимать самолёт может быть поздно (особенно в случае аварии), кондиционирование? Не знаю, какие там системы и какие к ним требования, но при разгерметизации салона за секунды, а то и доли секунд нужно среагировать, чтобы спасти жизнь людям и выпустить те же кислородные маски.

                                              >ужасающая трудоёмкость написания кода
                                              Вы утрируете. Всё просто, что знаешь. Этот код писать просто, если изучить заблаговременно Software Design и Coding Standart. Код схожий и блочный. Только для пущего удобства IDE как в MS VS не хватает.

                                              >>неуместность для работы с железками
                                              >Это как?
                                              Всё ли, относящееся к железу легко написать на них? Как быстро будет это работать? Как haskell работает с Interrupts (насколько я знаю — это наибольшая проблема)? Я знаю очень мало примеров низкоуровнего программирования на этих языках. То, что есть — начало появляться лишь намедни.

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

                                              Возможно, это изменяется и изменится и они будут применяться, если это будет просто и дёшево. Возможно, у них всё впереди.
                                                0
                                                Ок.
                                          0
                                          разве у Bombardier BD 500 двигатели не на хвосте, а не на крыльях?
                                            0
                                            Хороший вопрос. Самолёт в стадии разработки. Начало лётных испытаний планировалось на начало текущего лета. Речь идёт о C Series. Когда я над ним работал, его рисунок выглядел именно так, как модель в аэродинамической трубе + рендер с окошечками и бликами. Но в интернете ходят такие фотографии: image
                                            Быть может вы и правы, спорить не буду. Фото взято с aviationnews.
                                          0
                                          Интересно, спасибо! Подскажите а есть ли какое-то автоматическое тестирование и как оно реализовано? Т.е. как примерно разработчики пишут тесты «если нажать кнопку, ввести неверные данные, то пользователь увидит сообщение об ошибке». А здесь есть что-то подобное, например «тестируем отказ такого-то датчика/привода», «тестируем неверную команду пилота/порыв ветра/приближающийся самолёт», и т.д. Наверняка должно что-то подобное быть, но как именно это происходит с учётом того что тестировать нужно не только код но и в связке с аппаратной частью. Есть ли какие-то требования к тестам?
                                            +1
                                            Спасибо. Я достаточно подробно описал в прошлой статье процессы тестирования и инструменты.
                                            Если интересно поподробнее узнать методологию составления тест кейсов, почитайте о систематическом тестировании.

                                            Что касается ваших примеров — это сценарные тесты, обычно выполняются на полнофункциональной модели самолёта на земле либо уже в полёте на реальном самолёте. Наши лётчики-испытатели умудрялись тестировать «разрыв связи» и «отключение питания» в воздухе для всех систем сразу путём физического насилия, ну как и посадку без флаперонов. Наши — суровые ребята. В Airbus, к примеру, такое редкость.

                                            Если есть подробные вопросы — задавайте, отвечу.
                                              0
                                              Видимо пропустил первую часть, почитаю.
                                            0
                                            Сурово. Интересно выглядят методы «зачехления» такого острого инструмента, как Си.
                                              0
                                              К слову «актуаторы» — есть термин «исполнительный механизм», которое и следовало бы употребить :)

                                              Only users with full accounts can post comments. Log in, please.