Складання програми для використання у високо радіоактивних середовищах


1456

Ми складаємо вбудовану програму C / C ++, яка розгорнута в екранованому пристрої в середовищі, обстріленому іонізуючим випромінюванням . Ми використовуємо GCC та крос-компіляцію для ARM. Під час розгортання наш додаток генерує деякі помилкові дані та збої частіше, ніж нам би хотілося. Обладнання розроблено для цього середовища, і наш додаток працює на цій платформі вже кілька років.

Чи є зміни, які ми можемо внести до нашого коду чи вдосконалення часу компіляції, які можуть бути зроблені для виявлення / виправлення помилок та пошкодження пам’яті, спричинених розладами однієї події ? Чи мали інші розробники успіх у зменшенні шкідливого впливу м'яких помилок на тривалому застосуванні?


186
Чи змінюються значення в пам'яті чи змінюються значення в процесорі? Якщо апаратне забезпечення розроблене для навколишнього середовища, програмне забезпечення має працювати так, ніби працює в нерадіоактивному середовищі.
Томас Меттьюз

3
Якщо можливо, вам слід створити систему реєстрації, яка зберігає події в енергонезалежній пам'яті, стійкій до випромінювання. Зберігайте достатньо інформації, щоб можна було простежити подію та легко знайти першопричину.
Томас Меттьюз

2
@Thomas Matthews У всій пам'яті є показник помилок FIT, а виробники обладнання дають багато обіцянок. Більшість проблем, ймовірно, викликані SEU, що змінюють оперативні пристрої під час виконання.
грак

9
Це комбіноване апаратне / програмне рішення, але я знаю, що Texas Instruments (і, мабуть, інші) робить вбудовані мікросхеми для критично важливих для безпеки програм, які складаються з двох дублікатів ядер, що працюють в режимі замкового кроку, півгодинного циклу поза фазою. Існують спеціальні переривання та дії скидання, які приймаються, коли апаратне забезпечення виявляє щось інше між ядрами, тому ви можете відновитись після помилок. Я вважаю, що TI називає їх процесорами безпеки "Геркулес".
mbrig

5
Надмірно міцні мотори, деякі передачі, вали та храповики! Замінюйте щорічно або частіше, оскільки вимагають норми дози. Ні, насправді, моє перше питання щодо таких питань завжди було, чи справді вам потрібно стільки програмного забезпечення? Будьте настільки ж аналогом, наскільки ви зможете піти.
jwdonahue

Відповіді:


814

Працюючи близько 4-5 років над розробкою програмного забезпечення / мікропрограмного забезпечення та тестуванням навколишнього середовища мініатюризованих супутників *, я хотів би поділитися своїм досвідом тут.

* ( мініатюризовані супутники набагато більше схильні до розладів одиночних подій, ніж більші супутники через його відносно невеликі, обмежені розміри для його електронних компонентів )

Щоб бути дуже короткими і прямими: немає ніякого механізму , щоб оговтатися від виявленої, помилкової ситуації з допомогою програмного забезпечення / микропрограммного себе без , по крайней мере, одна копії з мінімальної робочої версії цього програмного забезпечення / прошивок де - то для відновлення мети - і з апаратною підтримкою відновлення (функціональне).

Зараз ця ситуація зазвичай вирішується як на апаратному, так і на програмному рівні. Тут, як ви просите, я поділюся тим, що ми можемо зробити на рівні програмного забезпечення.

  1. ... відновлення ... мета . Забезпечити можливість оновлення / перекомпіляції / перепрошивання програмного забезпечення / мікропрограмного забезпечення в реальному середовищі. Це майже обов'язкова функція для будь-якого програмного забезпечення / мікропрограмного забезпечення у високоіонізованому середовищі. Без цього у вас може бути стільки програмного забезпечення / обладнання, скільки хочете, але в один момент всі вони підірвуться. Отже, підготуйте цю функцію!

  2. ... мінімальна робоча версія ... Майте у своєму коді чуйну, декілька копій, мінімальну версію програмного забезпечення / мікропрограмного забезпечення. Це як безпечний режим у Windows. Замість того, щоб мати лише одну, повністю функціональну версію програмного забезпечення, майте кілька копій мінімальної версії програмного забезпечення / мікропрограмного забезпечення. Мінімальна копія, як правило, має значно менший розмір, ніж повна копія, і майже завжди має лише дві або три функції:

    1. здатний слухати команди із зовнішньої системи,
    2. здатний оновлювати поточне програмне забезпечення / прошивку,
    3. здатний відслідковувати основні дані ведення господарства.
  3. ... скопіюйте ... десь ... Майте десь зайве програмне забезпечення / прошивку.

    1. Ви можете, з надмірним обладнанням або без нього, спробувати мати зайве програмне забезпечення / прошивку у вашому ARM uC. Зазвичай це робиться за допомогою двох або більше однакових програм / мікропрограмного забезпечення за окремими адресами, які надсилають серцебиття один одному, але одночасно буде активний лише один. Якщо одне або більше програмного забезпечення / мікропрограмного забезпечення, як відомо, не відповідають, перейдіть до іншого програмного забезпечення / мікропрограмного забезпечення. Перевага використання цього підходу полягає в тому, що ми можемо мати функціональну заміну відразу після виникнення помилки - без будь-якого контакту з будь-якою зовнішньою системою / стороною, яка відповідає за виявлення та виправлення помилки (у супутниковому випадку це, як правило, Центр контролю місії ( MCC)).

      Власне кажучи, без зайвих апаратних засобів, недоліком цього є те, що ви насправді не можете усунути всі окремі точки відмов. Як мінімум, у вас все одно буде одна точка відмови, а саме перемикач (або часто початок коду). Тим не менш, для пристрою, обмеженого розмірами у високоіонізованому середовищі (наприклад, супутники pico / femto), зменшення одиничної точки відмов до однієї точки без додаткового обладнання буде все-таки варто враховувати. Сомеморе, фрагмент коду для комутації, безумовно, буде набагато меншим, ніж код для всієї програми - значно знизивши ризик потрапляння в неї єдиної події.

    2. Але якщо ви цього не робите, у вашій зовнішній системі має бути хоча б одна копія, яка може контактувати з пристроєм та оновлювати програмне забезпечення / мікропрограмне забезпечення (у супутниковому випадку це знову центр управління місією).

    3. Ви також можете мати копію у постійному сховищі пам’яті на своєму пристрої, що може бути запущено для відновлення програмного забезпечення / мікропрограмного забезпечення працюючої системи.
  4. ... помилкова ситуація, що виявляється .. Помилка повинна бути виявлена , як правило, за допомогою апаратної схеми виправлення / виявлення помилок або невеликого фрагмента коду для виправлення / виявлення помилок. Найкраще ставити такий код невеликим, множинним та незалежним від основного програмного забезпечення / мікропрограмного забезпечення. Основне його завдання - лише перевірка / виправлення. Якщо апаратна схема / прошивка є надійною(наприклад, він більше піддається випромінюванню, ніж спочиває - або має декілька схем / логік), тоді ви можете розглянути можливість виправлення помилок. Але якщо це не так, краще зробити це як виявлення помилок. Виправлення може здійснюватися за допомогою зовнішньої системи / пристрою. Для виправлення помилок можна розглянути можливість використання базового алгоритму виправлення помилок, такого як Hamming / Golay23, оскільки вони можуть бути легше реалізовані як у схемі / програмному забезпеченні. Але це в кінцевому рахунку залежить від можливостей вашої команди. Для виявлення помилок зазвичай використовується CRC.

  5. ... апаратне забезпечення, що підтримує відновлення Тепер, підходить до найскладнішого аспекту в цьому питанні. Зрештою, для відновлення потрібно апаратне забезпечення, яке відповідає за відновлення, бути принаймні функціональним. Якщо обладнання постійно порушено (зазвичай це відбувається після досягнення загальної іонізуючої дози певного рівня), програмне забезпечення (на жаль) не допоможе відновити його. Таким чином, апаратне забезпечення має надзвичайно важливе значення для пристрою, що зазнає високого рівня випромінювання (наприклад, супутника).

На додаток до пропозиції щодо передбачення помилки вбудованого програмного забезпечення внаслідок розладу однієї події, я також хочу запропонувати вам:

  1. Алгоритм виявлення помилок та / або виправлення помилок в протоколі зв'язку між підсистемами. Це ще одне, що мало бути, щоб уникнути неповних / неправильних сигналів, отриманих від іншої системи

  2. Фільтр у вашому читанні ADC. Як НЕ використовувати АЦП для читання безпосередньо. Фільтруйте його за середнім фільтром, середнім фільтром або будь-якими іншими фільтрами - ніколи не довіряйте одному значенню читання. Проби більше, не менше - розумно.


401

У NASA є документ про програмне забезпечення, захищене від радіації . У ньому описано три основні завдання:

  1. Регулярний моніторинг пам'яті на предмет помилок, а потім очищення цих помилок,
  2. надійні механізми відновлення помилок та
  3. можливість переналаштування, якщо щось більше не працює.

Зауважте, що частота сканування пам’яті повинна бути достатньо частою, щоб рідко виникати багатобітні помилки, оскільки більшість пам’яток ECC можуть відновлюватися після однобітних помилок, а не багатобітних помилок.

Надійне відновлення помилок включає передачу потоку управління (як правило, перезапуск процесу в момент перед помилкою), звільнення ресурсів та відновлення даних.

Основна їхня рекомендація щодо відновлення даних - уникати необхідності в них через те, що проміжні дані трактуються як тимчасові, щоб перезапуск перед помилкою також повертав дані до надійного стану. Це схоже на поняття "транзакції" в базах даних.

Вони обговорюють методи, особливо підходящі для об'єктно-орієнтованих мов, таких як C ++. Наприклад

  1. На базі програмного забезпечення ECC для суміжних об'єктів пам'яті
  2. Програмування за контрактом : перевірка передумов і постумов, потім перевірка об'єкта для перевірки його ще в дійсному стані.

І, так це відбувається, NASA використовує C ++ для великих проектів, таких як Mars Rover .

Абстракція та інкапсуляція класів C ++ дозволили швидко розробити та протестувати серед багатьох проектів та розробників.

Вони уникали певних функцій C ++, які можуть створити проблеми:

  1. Винятки
  2. Шаблони
  3. Iostream (без консолі)
  4. Багатократне успадкування
  5. Перевантаження оператора (крім newі delete)
  6. Динамічний розподіл (використовується спеціальний пул пам’яті та розміщення, newщоб уникнути можливості пошкодження купи системи).

28
Це насправді звучить як щось, у чому чиста мова була б хорошою. Оскільки значення ніколи не змінюються, якщо вони пошкоджені, ви можете просто повернутися до початкового визначення (таким, яким воно має бути), і ви випадково не зробите те ж саме двічі (через відсутність побічних ефектів).
PyRulez

20
RAII - погана ідея, тому що ви не можете залежати від того, щоб вона працювала коректно чи навіть взагалі. Це може випадково пошкодити ваші дані тощо. Ви дійсно хочете стільки незмінності, скільки ви можете отримати, так і механізмів виправлення помилок. Набагато простіше просто викинути зламані речі, ніж намагатися якось їх поправити (як саме ви знаєте достатньо, щоб повернутися до правильного старого стану?). Напевно, ви хочете використовувати для цього досить тупу мову - оптимізація може зашкодити більше, ніж вони допоможуть.
Луань

67
@PyRulez: Чисті мови - це абстракція, апаратне забезпечення не є чистим. Компілятори досить добре приховують різницю. Якщо у вашої програми є значення, яке логічно не слід використовувати більше після кроку X, компілятор може замінити його значенням, яке обчислюється на кроці X + 1. Але це означає, що ти не можеш повернутися назад. Більш формально можливі стани програми чистою мовою утворюють ациклічний графік, що означає, що два стани еквівалентні і можуть бути об'єднані, коли стани, доступні для обох, є рівнозначними. Це злиття знищує різницю шляхів, що ведуть до цих держав.
MSalters

2
@Vorac - Згідно з презентацією, проблема із шаблонами C ++ викликає розширення коду.
jww

3
@DeerSpotter Точна проблема набагато більша, ніж ця. Іонізація може пошкодити біти вашої запущеної програми спостерігача. Тоді вам знадобиться спостерігач спостерігача, потім - спостерігач
вахти

116

Ось кілька думок та ідей:

Використовуйте ROM більш творчо.

Зберігайте все, що можна, в ROM. Замість обчислення речей зберігайте таблиці пошуку в ПЗУ. (Переконайтесь, що ваш компілятор виводить ваші таблиці перегляду в розділ лише для читання! Роздрукуйте адреси пам’яті під час виконання, щоб перевірити!) Зберігайте свою векторну таблицю переривань у ПЗУ. Звичайно, проведіть кілька тестів, щоб побачити, наскільки надійний ваш ROM в порівнянні з вашою ОЗУ.

Використовуйте найкращу оперативну пам’ять для стека.

SEU в стеці - це, мабуть, найбільш вірогідне джерело збоїв, оскільки саме там зазвичай проживають такі речі, як індексні змінні, змінні стану, зворотні адреси та вказівники різних типів.

Запровадьте таймер-контрольні та контрольні функції таймера.

Ви можете запустити процедуру "перевірки правильності" кожного галочки таймеру, а також розпорядження сторожового собаки для роботи із системою блокування. Ваш основний код також може періодично збільшувати лічильник, щоб вказувати на прогрес, і розпорядок перевірки правильності може забезпечити це.

Впроваджуйте коди на виправлення помилок у програмному забезпеченні.

Ви можете додати зайвих даних до своїх даних, щоб мати можливість виявляти та / або виправляти помилки. Це додасть часу на обробку, потенційно залишаючи процесор, що піддається впливу радіації на довший час, тим самим збільшуючи ймовірність помилок, тому потрібно враховувати компроміс.

Запам’ятайте кеші.

Перевірте розміри кеш-процесорів. Дані, до яких ви отримали доступ чи змінили нещодавно, ймовірно, будуть знаходитися в кеші. Я вірю, що ви можете вимкнути принаймні деякі кеші (з великою ціною продуктивності); Ви повинні спробувати це, щоб побачити, наскільки кеші сприйнятливі до SEU. Якщо кеші складніші за оперативну пам’ять, ви можете регулярно читати та переписувати критичні дані, щоб переконатися, що вони залишаються в кеші та повертають оперативну пам’ять у відповідність.

Використовуйте розумно оброблювачі сторінки.

Якщо ви позначаєте сторінку пам'яті як такою, що не є, CPU видасть помилку сторінки під час спроби доступу до неї. Ви можете створити обробник помилок сторінки, який здійснить деяку перевірку перед обслуговуванням запиту на читання. (Операційні системи ПК використовують це для прозорого завантаження сторінок, які були замінені на диск.)

Використовуйте мову монтажу для критичних речей (що може бути все).

З мовою складання ви знаєте, що є в регістрах, а що в оперативній пам’яті; ви знаєте, які спеціальні таблиці оперативної пам’яті використовує процесор, і ви можете спроектувати речі навколо, щоб уникнути ризику.

Використовуйте, objdumpщоб насправді переглянути сформовану мову складання, і розробити, скільки коду займає кожна з ваших процедур.

Якщо ви використовуєте велику ОС на зразок Linux, то ви просите проблем; просто так багато складностей і стільки речей, щоб піти не так.

Пам’ятайте, це гра ймовірностей.

- сказав коментатор

Кожна рутина, яку ви пишете, щоб виправити помилки, підлягає невдачі з тієї ж причини.

Хоча це правда, шанси помилок у (скажімо) 100 байтах коду та даних, необхідних для правильної роботи контрольної програми, значно менші, ніж шанси помилок в інших місцях. Якщо ваш ROM є досить надійним і майже весь код / ​​дані є насправді в ROM, то шанси ще краще.

Використовуйте надмірне обладнання.

Використовуйте 2 або більше однакових налаштувань обладнання з однаковим кодом. Якщо результати відрізняються, слід здійснити скидання. За допомогою трьох або більше пристроїв ви можете використовувати систему "голосування", щоб спробувати визначити, який з них був порушений.


14
На сьогоднішній день ЄКК доступний через апаратне забезпечення, що економить час обробки. Першим кроком було б вибрати мікроконтролер із вбудованим ECC.
Лундін

23
Десь у мене в голові є посилання на апаратні засоби польотів авіоніки (можливо, космічного човника?), Де надмірна архітектура була чітко розроблена таким, щоб не бути однаковим (і різними командами). Це зменшує можливість системної помилки в дизайні апаратного / програмного забезпечення, зменшуючи ймовірність того, що всі системи голосування виходять з ладу одночасно при зіткненні з однаковими входами.
Пітер М

8
@PeterM: AFAIK, що також вимагається для польотного програмного забезпечення Boeing 777: три версії трьох команд на трьох мовах програмування.
Відновіть Моніку - М. Шредер

7
@DanEsparza ОЗУ зазвичай має конденсатор (DRAM) або кілька транзисторів у зворотній зв'язку (SRAM), що зберігають дані. Подія випромінювання може помилково заряджати / розряджати конденсатор або змінювати сигнал у циклі зворотного зв'язку. ПЗУ, як правило, не потребує можливості запису (принаймні, без особливих обставин та / або більш високих напруг), і, отже, він може бути природним чином більш стабільним на фізичному рівні.
нанофарад

7
@DanEsparza: Є кілька типів пам'яті ROM. Якщо "ПЗУ" імітується, тобто, eeprom або спалахом, що читається лише на-5V, але програмується-at-10v, тоді "ROM" все ще схильний до іонізації. Можливо, лише менше, ніж інші. Однак є хороші «жорсткі» речі, такі як Mask ROM або PROM на основі запобіжників, які, на мою думку, потребують дуже серйозної кількості радіації, щоб почати виходити з ладу. Не знаю, однак, чи все ще є вироблені.
quetzalcoatl

105

Можливо, вас також зацікавить багата література на тему алгоритмічної відмовостійкості. Сюди входить і старе завдання: Напишіть сорт, який правильно сортує його вхід, коли постійна кількість порівнянь не вдасться (або, трохи більш злу версію, коли асимптотичне число невдалих порівнянь масштабується, як і log(n)для nпорівнянь).

Місце для початку читання - праця Хуана та Авраама 1984 р. " Допущення помилок на основі алгоритму для матричних операцій ". Їх ідея нечітко схожа на гомоморфні зашифровані обчислення (але насправді це не те саме, оскільки вони намагаються виявити / виправити помилки на рівні операції).

Більш пізнім нащадком цього документу є Босілка, Дельмас, Донгара та Лангу, "Допущення до помилок на основі алгоритму, застосованих до обчислень з високою продуктивністю ".


5
Мені дуже подобається ваша відповідь. Це більш узагальнений програмний підхід до цілісності даних, і алгоритмічне рішення про відмовостійкість буде використано в нашому кінцевому продукті. Дякую!
грак

41

Написання коду для радіоактивних середовищ насправді не відрізняється від написання коду для будь-якого критичного завдання.

Окрім того, що вже було сказано, ось декілька різних порад:

  • Використовуйте щоденні заходи безпеки "хліб і масло", які повинні бути присутніми в будь-якій напівпрофесійній вбудованій системі: внутрішня сторожова собака, внутрішній низьковольтний детектор, внутрішній монітор годинника. Про ці речі навіть не варто згадувати у 2016 році, і вони є стандартними для майже кожного сучасного мікроконтролера.
  • Якщо у вас MCU, орієнтований на безпеку та / або автомобіль, він матиме певні функції сторожового собаки, наприклад, задане часове вікно, всередині якого вам потрібно оновити сторожову собаку. Це бажано, якщо у вас є система критичного значення в режимі реального часу.
  • Загалом, використовуйте MCU, що підходить для таких систем, а не якийсь загальний пух, який ви отримали в пакеті з кукурудзяними пластівцями. Практично кожен виробник MCU має спеціалізовані MCU, призначені для застосувань для безпеки (TI, Freescale, Renesas, ST, Infineon тощо тощо). У них є безліч вбудованих функцій безпеки, в тому числі кермових блоків: це означає, що є два ядра процесора, що виконують один і той же код, і вони повинні погоджуватися між собою.
  • ВАЖЛИВО: Ви повинні забезпечити цілісність внутрішніх регістрів MCU. Усі регістри контролю та стану апаратних периферійних пристроїв, що записуються, можуть знаходитися в оперативній пам'яті, і тому є вразливими.

    Щоб убезпечити себе від пошкодження реєстру, бажано вибрати мікроконтролер із вбудованими функціями регістрів «записувати один раз». Крім того, потрібно зберігати значення за замовчуванням усіх апаратних регістрів у NVM та копіювати ці значення у свої регістри через регулярні проміжки часу. Ви можете забезпечити цілісність важливих змінних таким же чином.

    Примітка: завжди використовуйте захисне програмування. Це означає, що вам потрібно налаштувати всі регістри в MCU, а не лише ті, які використовує додаток. Ви не хочете, щоб якийсь випадковий апаратний периферійний апарат раптом прокинувся.

  • Існують всілякі методи перевірки помилок в оперативній пам’яті чи NVM: контрольні суми, «шаблони ходьби», програмне забезпечення ECC тощо тощо. Найкращим рішенням сьогодні є не використовувати жодне з них, а використовувати MCU із вбудованим ECC та аналогічні перевірки. Оскільки робити це в програмному забезпеченні складно, а сама перевірка помилок може призвести до помилок і несподіваних проблем.

  • Використовуйте надмірність. Ви можете зберігати як летючу, так і енергонезалежну пам'ять у двох однакових «дзеркальних» сегментах, які завжди повинні бути еквівалентними. До кожного сегменту може бути додана контрольна сума CRC.
  • Уникайте використання зовнішніх пам’яток за межами MCU.
  • Реалізуйте звичайну службову програму переривання переривання / обробку винятків за замовчуванням для всіх можливих переривань / виключень. Навіть ті, якими ви не користуєтесь. Програма за замовчуванням не повинна робити нічого, крім відключення власного джерела переривання.
  • Розуміти та приймати концепцію оборонного програмування. Це означає, що вашій програмі потрібно обробляти всі можливі випадки, навіть ті, які теоретично не можуть виникнути. Приклади .

    Високоякісна прошивка з критичною місією виявляє якомога більше помилок, а потім безпечно ігнорує їх.

  • Ніколи не пишіть програми, які покладаються на погано задану поведінку. Цілком ймовірно, що така поведінка може кардинально змінитися при несподіваних апаратних змінах, спричинених радіацією або ІМС. Найкращий спосіб переконатися, що ваша програма позбавлена ​​такої лайна - це використовувати стандарт кодування, як MISRA, разом із інструментом статичного аналізатора. Це також допоможе в оборонному програмуванні та у відмиванні помилок (чому б ви не хотіли виявляти помилки в будь-якому застосуванні?).
  • ВАЖЛИВО: Не застосовуйте жодних залежностей від стандартних значень змінних тривалості зберігання за замовчуванням. Тобто не довіряйте за замовчуванням вмісту .dataабо .bss. Між точкою ініціалізації до точки, де реально використовується змінна, може бути будь-який проміжок часу, оперативна пам’ять може бути достатньою, щоб пошкодити ОЗУ. Натомість запишіть програму так, щоб усі такі змінні були встановлені з NVM під час виконання, безпосередньо до часу, коли така змінна використовується вперше.

    На практиці це означає, що якщо змінна оголошена в області файлу або як static, ви ніколи не повинні використовувати її =для ініціалізації (або ви могли, але це безглуздо, тому що ви не можете покладатися на значення так чи інакше). Завжди встановлюйте його під час виконання, безпосередньо перед використанням. Якщо є можливість повторного оновлення таких змінних від NVM, то зробіть це.

    Аналогічно в C ++, не покладайтеся на конструктори для статичних змінних тривалості зберігання. Запропонуйте конструкторам (ім) викликати загальнодоступну процедуру "налаштування", яку ви також можете зателефонувати пізніше під час виконання, безпосередньо з програми для виклику.

    Якщо можливо, видаліть стартовий код "копіювання", який повністю ініціалізує .dataта .bss(і викликає конструктори C ++), так що ви отримаєте помилки в посиланнях, якщо ви пишете код, спираючись на такий. Багато компіляторів мають можливість пропустити це, як правило, називається "мінімальний / швидкий запуск" або подібне.

    Це означає, що будь-які зовнішні бібліотеки повинні бути перевірені, щоб вони не містили такої залежності.

  • Реалізуйте та визначте безпечний стан для програми, куди ви звернетесь у разі критичних помилок.

  • Впровадження системи звітів про помилки / журнал помилок завжди корисно.

Одним із способів боротьби з пошкодженнями булів (як у вашому прикладі посилань) може бути TRUEрівне значення 0xffffffffта використання POPCNTз порогом.
wizzwizz4

@ wizzwizz4 Враховуючи, що значення 0xff є типовим значенням непрограмованої флеш-комірки, це звучить як погана ідея.
Лундін

%01010101010101010101010101010101, XOR тоді POPCNT?
wizzwizz4

1
@ wizzwizz4 Або просто значення 0x1, як того вимагає стандарт C.
Лундін

1
@ wizzwizz4 Для чого ви використовуєте деякі або всі вищезгадані методи (ECC, CRC тощо). Інакше космічний промінь може також перевернути один біт у вашому .textрозділі, змінивши оп-код або подібне.
Лундін

34

Можливо використовувати C для написання програм, які ведуть себе в таких умовах, але тільки якщо більшість форм оптимізації компілятора вимкнено. Оптимізація компіляторів призначена для заміни багатьох, здавалося б, надлишкових моделей кодування на "більш ефективні", і може не мати поняття, що причина, яку програміст тестує, x==42коли компілятор знає, що немає можливості, xможливо, утримати щось інше, тому що програміст хоче запобігти виконання певного коду з xутримуванням іншого значення - навіть у випадках, коли єдиним способом він міг би утримувати це значення було б, якби система отримала якийсь електричний збій.

Декларування змінних volatileчасто корисно, але може не бути панацеєю. Особливо важливо зауважити, що безпечне кодування часто вимагає, щоб небезпечні операції мали апаратні блокування, які потребують декількох кроків для активації, а цей код записується за допомогою шаблону:

... code that checks system state
if (system_state_favors_activation)
{
  prepare_for_activation();
  ... code that checks system state again
  if (system_state_is_valid)
  {
    if (system_state_favors_activation)
      trigger_activation();
  }
  else
    perform_safety_shutdown_and_restart();
}
cancel_preparations();

Якщо компілятор переводить код відносно буквально, і якщо всі перевірки стану системи повторюються після цього prepare_for_activation(), система може бути надійною щодо практично будь-яких правдоподібних подій одного глюка, навіть тих, які б довільно пошкодили лічильник програм та стек. Якщо глюк виникає відразу після виклику до prepare_for_activation(), це означатиме, що активація була б доречною (оскільки жодної іншої причини prepare_for_activation()не було б викликано перед глюком). Якщо глюк спричиняє prepare_for_activation()неналежне надходження коду , але немає наступних подій глюка, не було б способу згодом дійти до цього коду, trigger_activation()не пройшовши через перевірку перевірки або зателефонувавши вначало cancel_preparations [якщо стек глючить, виконання може перейти до місця передtrigger_activation()після контексту, який викликав, prepare_for_activation()повертається, але заклик до cancel_preparations()цього відбувся б між дзвінками до prepare_for_activation()та trigger_activation(), таким чином, зробивши останній дзвінок нешкідливим.

Такий код може бути безпечним у традиційних C, але не у сучасних компіляторах C. Такі компілятори можуть бути дуже небезпечними в такому середовищі, оскільки агресивні вони прагнуть включити лише код, який буде доречний у ситуаціях, які можуть виникнути через якийсь чітко визначений механізм і наслідки якого також були б чітко визначені. Кодекс, метою якого було б виявлення та очищення після відмов, у деяких випадках може погіршити ситуацію. Якщо компілятор визначить, що спробу відновлення в деяких випадках викликає невизначене поведінку, може зробити висновок, що умови, які потребують такого відновлення в таких випадках, не можуть виникнути, тим самим усуваючи код, який би перевіряв їх.


6
Реально кажучи, скільки сучасних компіляторів, які не пропонують -O0або еквівалентний комутатор? GCC зробить багато дивних речей, якщо ви дасте йому дозвіл , але якщо ви попросите їх не робити, він, як правило, може бути досить буквальним.
Левшенко

24
Вибачте, але ця ідея принципово небезпечна. Якщо вимкнути оптимізацію, програма створює більш повільну програму. Або, іншими словами, вам потрібен швидший процесор. Як це буває, швидші процесори швидші, тому що заряди на їх транзисторних воротах менші. Це робить їх набагато більш чутливими до радіації. Кращою стратегією є використання повільного, великого чіпа, де один фотон набагато рідше перебиває трохи і повертає швидкість за допомогою -O2.
MSalters

27
Вторинна причина, чому -O0це погана ідея, полягає в тому, що вона дає набагато більше марних інструкцій. Приклад: не вбудований виклик містить інструкції щодо збереження регістрів, здійснення дзвінка, відновлення регістрів. Все це може вийти з ладу. Інструкція, якої немає там, не може не виконати.
MSalters

15
Ще одна причина, чому -O0це погана ідея: вона, як правило, зберігає змінні в пам'яті, а не в регістрі. Зараз невідомо, що пам'ять сприйнятливіша до СЕУ, але дані в польоті сприйнятливіші, ніж дані в спокої. Слід уникати марного руху даних і -O2допомагати в цьому.
MSalters

9
@MSalters: Важливо не те, що дані не захищені від збоїв, а в тому, що система зможе впоратись із порушеннями таким чином, щоб відповідати вимогам. У багатьох компіляторах, які вимикають усі оптимізації, виходить код, який виконує надмірну кількість рухів реєстрації до регістра, що погано, але зберігання змінних у пам’яті безпечніше з точки зору відновлення, ніж зберігання їх у регістрах. Якщо в пам'яті є дві змінні, які повинні відповідати певній умові (наприклад, v1=v2+0xCAFEBABEі всі оновлення двох змінних виконані ...
supercat

28

Це надзвичайно широка тема. В основному ви не можете реально відновитися після пошкодження пам’яті, але ви можете принаймні спробувати негайно відмовитися . Ось кілька методів, які ви можете використовувати:

  • постійні дані контрольної суми . Якщо у вас є якісь дані конфігурації, які тривалий час залишаються постійними (включаючи налаштовані вами регістри обладнання), обчисліть контрольну суму при ініціалізації та періодично перевіряйте їх. Коли ви побачите невідповідність, настав час повторно ініціалізувати чи скинути.

  • зберігати змінні з надмірністю . Якщо у вас є важлива змінна x, написати своє значення в x1, x2і x3та читати його як (x1 == x2) ? x2 : x3.

  • впровадити моніторинг потоку програми . XOR глобальний прапор з унікальним значенням у важливих функціях / гілках, що викликаються з головного циклу. Запуск програми в радіаційному середовищі з майже 100% тестовим покриттям повинен дати вам список прийнятних значень прапора в кінці циклу. Скиньте, якщо побачите відхилення.

  • стежити за вказівником стека . На початку основного циклу порівняйте покажчик стека з його очікуваним значенням. Скидання на відхилення.


27

Що може допомогти вам - сторожовий пес . Вартові собаки широко використовувались у промислових обчисленнях у 1980-х роках. Апаратні збої були набагато частіше тоді - ще одна відповідь стосується цього періоду.

Вартовий собака - це комбінована апаратна / програмна функція. Апаратне забезпечення - це простий лічильник, який відлічується від числа (скажімо, 1023) до нуля. TTL або інша логіка може бути використана.

Програмне забезпечення було розроблено таким чином, що слід контролювати правильність роботи всіх основних систем. Якщо ця програма завершена правильно = вважає, що комп'ютер працює нормально, він встановлює лічильник назад на 1023.

Загальна конструкція така, що при нормальних обставинах програмне забезпечення перешкоджає тому, щоб апаратний лічильник досяг нуля. Якщо лічильник досягає нуля, апаратне забезпечення лічильника виконує своє єдине завдання та скидає всю систему. З точки зору лічильника нуль дорівнює 1024, і лічильник продовжує відлік знову.

Цей сторожовий собака забезпечує перезавантаження приєднаного комп'ютера у багатьох, багатьох випадках виходу з ладу. Треба визнати, що я не знайомий із обладнанням, яке здатне виконувати таку функцію на сучасних комп’ютерах. Інтерфейси до зовнішнього обладнання зараз набагато складніші, ніж раніше.

Невід'ємним недоліком сторожової собаки є те, що система недоступна з моменту її виходу з ладу, поки лічильник сторожових досягнень не досягне нуля + час перезавантаження. Хоча цей час, як правило, набагато коротший, ніж будь-яке зовнішнє або людське втручання, обладнання, що підтримується, потребує можливості без комп'ютерного контролю за цей часовий період.


9
Бінарні лічильники сторожових установок із стандартними ІС TTL - це справді рішення 1980-х років. Не робіть цього. Сьогодні на ринку не існує жодного MCU без вбудованої схеми сторожових дог. Все, що вам потрібно перевірити, це чи має вбудований сторожовий будинок індивідуальне джерело годинника (добре, швидше за все, так) чи він успадковує свій годинник від системного годинника (погано).
Лундін

1
Або реалізувати сторожового в ПЛІС: ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20130013486.pdf
NOS

2
Досі широко використовується у вбудованих процесорах, до речі.
Грем

5
@Peter Mortensen Будь ласка, зупиніть свої редагування на кожну відповідь на це питання. Це не Вікіпедія, і ці посилання не корисні (і я впевнений, що всі знають, як знайти Вікіпедію в будь-якому випадку ...). Багато ваших редагувань є невірними, оскільки ви не знаєте теми. Я роблю відкази ваших неправильних праць, коли я стикаюся з ними. Ви не обертаєте цю нитку краще, а гірше. Зупиніть редагування.
Лундін

Jack Ganssle має хорошу статтю про сторожових собак
Ігор Скочинський

23

Ця відповідь передбачає, що Ви турбуєтесь про те, щоб система, яка працює правильно, вище та мати систему з мінімальною витратою або швидкістю; більшість людей, які грають з радіоактивними речами, цінують правильність / безпеку над швидкістю / вартістю

Кілька людей запропонували зміни апаратного забезпечення, які ви можете зробити (прекрасно - тут є багато хороших речей у відповідях, і я не збираюся все це повторювати), а інші запропонували надмірність (в принципі чудова), але я не думаю хтось підказав, як це надмірність може працювати на практиці. Як ви провалилися? Звідки ви знаєте, коли щось пішло не так? Багато технологій працюють на основі того, що все буде працювати, і, таким чином, невдача - це хитра справа. Однак деякі розподілені обчислювальні технології, розроблені для масштабування, очікують збою (адже з достатньою шкалою відмова одного з багатьох вузлів неминуча з будь-яким MTBF для одного вузла); Ви можете використати це для свого оточення.

Ось кілька ідей:

  • Переконайтеся, що весь апаратний апарат повторюється в nрази (де nбільше, ніж 2, і переважно непарно), і що кожен апаратний елемент може спілкуватися один з одним апаратним елементом. Ethernet - це один очевидний спосіб зробити це, але є багато інших набагато простіших маршрутів, які б забезпечили кращий захист (наприклад, CAN). Мінімізуйте загальні компоненти (навіть джерела живлення). Це може означати, наприклад, вибірку входів АЦП у кількох місцях.

  • Переконайтесь, що стан вашої програми знаходиться в одному місці, наприклад, у машині з кінцевим станом. Це може бути повністю на базі оперативної пам’яті, хоча це не виключає стабільної пам’яті. Таким чином, він буде зберігатися в декількох місцях.

  • Прийняти протокол кворуму щодо змін стану. Наприклад, див. RAFT . Оскільки ви працюєте в C ++, для цього є добре відомі бібліотеки. Зміни до FSM відбудуться лише тоді, коли більшість вузлів погодиться. Використовуйте відому гарну бібліотеку для стека протоколів і протоколу кворуму, а не прокручуючи один, інакше вся ваша хороша робота над надмірністю буде витрачена даремно, коли протокол кворуму зависне.

  • Переконайтеся, що ви перевіряєте суму (наприклад, CRC / SHA) свого FSM та зберігаєте CRC / SHA в самому FSM (а також передавати в повідомленні та перевіряти суму повідомлень). Отримайте вузли, щоб регулярно перевіряти їх FSM щодо цих контрольних сум, контрольних сум вхідних повідомлень та перевіряти, чи відповідає їх контрольна сума контрольній сумі кворуму.

  • Створіть якомога більше внутрішніх перевірок у вашій системі, зробивши вузли, які виявляють власну несправність, перезавантажтеся (це краще, ніж виконувати наполовину працюючий за умови, що у вас достатньо вузлів). Спробуйте дозволити їм чисто видалити кворум під час перезавантаження, якщо вони більше не з'являться. Після перезавантаження їм слід перевірити зображення програмного забезпечення (і все інше, що вони завантажують) і зробити повний тест оперативної пам’яті, перш ніж повторно представити себе в кворумі.

  • Використовуйте обладнання для підтримки, але робіть це обережно. Наприклад, ви можете отримати оперативну пам'ять ECC і регулярно її читати / записувати, щоб виправити помилки ECC (і панікувати, якщо помилка не може бути виправлена). Однак (з пам’яті) статична ОЗУ набагато толерантніша до іонізуючого випромінювання, ніж DRAM в першу чергу, тому може бути краще використовувати статичну DRAM. Перший пункт див. Також у розділі "речі, які я б не робив".

Скажімо, у вас є 1% шанс виходу з ладу будь-якого даного вузла протягом одного дня, і давайте зробимо вигляд, що ви можете зробити збої абсолютно незалежними. З 5 вузлами вам потрібно буде три виходити з ладу протягом одного дня, це шанс .00001%. Що більше, ну, ви отримуєте ідею.

Що я б не робив:

  • Недооцінюйте значення того, що у вас немає проблеми починати. Якщо вага не викликає занепокоєння, великий металевий блок навколо вашого пристрою стане набагато дешевшим і надійнішим рішенням, ніж може придумати команда програмістів. Дитто-оптичне з’єднання входів EMI - це проблема тощо. Що б там не було, намагайтеся, коли ви знайдете свої компоненти, щоб отримати джерела, які найкраще оцінюються проти іонізуючого випромінювання.

  • Прокатуйте власні алгоритми . Люди робили це раніше. Використовуйте їх роботу. Толерантність до відмов і розподілені алгоритми важкі. Використовуйте чужі роботи, де це можливо.

  • Використовуйте складні настройки компілятора з надією, ви виявите більше відмов. Якщо вам пощастить, ви можете виявити більше збоїв. Швидше за все, ви будете використовувати шлях коду в компіляторі, який був менш тестований, особливо якщо ви його прокатували самостійно.

  • Використовуйте методи, які не перевірені у вашому оточенні. Більшість людей, які пишуть програмне забезпечення високої доступності, повинні імітувати режими відмов, щоб перевірити, чи працює їх HA належним чином, і в результаті пропускають багато режимів відмов. Ви перебуваєте в положенні "пощастило", що часто виникають збої на вимогу. Тому протестуйте кожну техніку та переконайтесь, що її застосування фактично покращує MTBF на суму, що перевищує складність її впровадження (зі складністю поставляються помилки). Особливо застосуйте це до моїх порад щодо алгоритмів кворуму тощо.


2
Ethernet, напевно, не чудова ідея для використання в критичних для місії додатках. Також не є I2C, поза самою друкованою платою. Щось міцне, як CAN, було б набагато більше.
Лундін

1
@Lundin Справедливий пункт, хоча все, що оптично пов'язане (включаючи ethernet), повинно бути нормальним.
abligh

1
Фізичні медіа - це не стільки причина непридатності Ethernet, скільки відсутність детермінованої поведінки в режимі реального часу. Хоча я вважаю, що зараз є способи забезпечити дещо надійний Ethernet, я просто групую його разом з комерційною / іграшковою електронікою за старою звичкою.
Лундін

1
@Lundin це справедливий момент, але, як я пропоную використовувати його для запуску RAFT, в алгоритмі все одно буде (теоретично) недетермінована поведінка в реальному часі (наприклад, одночасні вибори лідера, що призводять до повторних виборів, схожих на CSMA / CD). Якщо потрібна сувора поведінка в режимі реального часу, можливо, моя відповідь має більше проблем, ніж ethernet (і зауваживши, що в голові моєї відповіді я сказав, що "правильне", швидше за все, трапляється за рахунок "швидкої"). Я включив ваш пункт про МОЖЛИВО.
abligh

1
@Lundin: Жодна система, що включає асинхронні аспекти, не може бути повністю недетермінованою. Я думаю, що найгірше поведінка Ethernet може бути обмежена за відсутності апаратних збоїв, якщо програмні протоколи налаштовані відповідним чином, а пристрої мають унікальні ідентифікатори і існує відомий ліміт кількості пристроїв (чим більше пристроїв, тим більше найгірша кількість повторних спроб).
supercat

23

Оскільки ви спеціально запитуєте програмні рішення, а ви використовуєте C ++, чому б не використовувати перевантаження оператора для створення власних, безпечних типів даних? Наприклад:

Замість того щоб використовувати uint32_tdouble, і int64_tт.д.), зробити свій власний , SAFE_uint32_tякий містить кілька (мінімум 3) uint32_t. Перевантажте всі операції, які ви хочете виконати (* + - / << >> = ==! = Тощо), і змусьте перевантажені операції виконувати незалежно на кожному внутрішньому значенні, тобто не виконайте це один раз і скопіюйте результат. Як до, так і після, перевірте, чи всі внутрішні значення відповідають. Якщо значення не збігаються, ви можете оновити неправильне значення до найпоширенішого. Якщо немає найпоширенішого значення, можете сміливо повідомити про помилку.

Таким чином, не має значення, якщо в АЛУ, регістрах, оперативній пам’яті чи в автобусі трапляється корупція, у вас все одно будуть багаторазові спроби та дуже хороший шанс виявити помилки. Однак зауважте, що це працює лише для змінних, які ви можете замінити - наприклад, ваш покажчик стека все ще буде сприйнятливим.

Побічна історія: я зіткнувся з подібною проблемою, також на старому чіпі ARM. Це виявилося ланцюжком інструментів, який використовував стару версію GCC, яка разом із конкретною мікросхемою, яку ми використовували, викликала помилку в певних крайніх випадках, які (іноді) пошкоджували б значення, передані у функції. Переконайтесь, що на вашому пристрої немає проблем, перш ніж звинувачувати його у радіоактивності, і так, іноді це помилка компілятора =)


1
Деякі з цих пропозицій містять щось подібне до способу виявлення корупції «багатобітна перевірка здорового ставлення». Мені дуже подобається ця пропозиція, що найбільше
подобається

2
У світі є системи, де кожен надлишковий вузол був розроблений і розроблений різними командами, з арбітром, щоб переконатися, що вони випадково не вирішили одне і те ж рішення. Таким чином, у вас немає, щоб усі вони виходили на одну і ту ж помилку, а подібні перехідні процеси не проявляли подібних режимів відмов.
jwdonahue

16

Відмова від відповідальності: Я не є професіоналом радіоактивності і не працював над цим додатком. Але я працював над м'якими помилками та надмірністю для довготривалого архівування критичних даних, що дещо пов'язане (та сама проблема, різні цілі).

Основна проблема радіоактивності, на мою думку, полягає в тому, що радіоактивність може перемикати біти, таким чином радіоактивність може / підриває будь-яку цифрову пам'ять . Ці помилки зазвичай називають м'якими помилками , бітовою гниттю тощо.

Тоді виникає питання: як надійно обчислити, коли пам’ять недостовірна?

Щоб значно знизити швидкість м'яких помилок (за рахунок обчислювальних накладних витрат, оскільки це в основному будуть програмні рішення), ви можете:

  • покладатися на стару добру схему надмірності , а точніше на більш ефективні коди виправлення помилок (та сама мета, але розумніші алгоритми, щоб ви могли відновити більше бітів із меншою надмірністю). Це іноді (неправильно) також називають контрольною сумою. Завдяки такому рішенню вам доведеться зберігати повний стан вашої програми в будь-який момент у головній змінній / класі (чи структурі?), Обчислювати ECC та перевіряти правильність ECC, перш ніж робити що-небудь, і якщо ні, відремонтуйте поля. Це рішення, однак, не гарантує, що ваше програмне забезпечення може працювати (просто, що воно буде працювати правильно, коли воно може, або перестає працювати, якщо ні, тому що ECC може сказати вам, якщо щось не так, і в цьому випадку ви можете зупинити своє програмне забезпечення, щоб ви не отримуйте підроблених результатів).

  • або ви можете використовувати стійкі алгоритмічні структури даних, які гарантують, до деякої межі, що ваша програма все одно дасть правильні результати навіть за наявності м'яких помилок. Ці алгоритми можна розглядати як поєднання загальних алгоритмічних структур із схемами ECC, що вперше змішані, але це набагато стійкіше, ніж це, оскільки схема стійкості жорстко прив'язана до структури, так що вам не потрібно кодувати додаткові процедури перевірити ECC, і зазвичай вони набагато швидше. Ці структури надають спосіб забезпечити роботу вашої програми за будь-яких умов, аж до теоретичної межі м'яких помилок. Ви також можете змішати ці стійкі структури зі схемою надмірності / ECC для додаткової безпеки (або кодувати ваші найважливіші структури даних як стійкі, а решта - витратні дані, які ви можете перерахувати з основних структур даних,

Якщо ви зацікавлені в стійких структурах даних (що є нещодавним, але захоплюючим, новим полем в алгоритміці та техніці надмірності), раджу прочитати наступні документи:

  • Введення структури даних про стійкі алгоритми Джузеппе Ф.Італьяно, університет Роми "Тор Вергата"

  • Christiano, P., Demaine, ED, & Kishore, S. (2011). Структури даних, що не мають втрат, без втрат з додатковою накладними витратами В алгоритмах та структурах даних (с. 243-254). Спрингер Берлін Гейдельберг.

  • Ferraro-Petrillo, U., Grandoni, F., & Italiano, GF (2013). Структури даних, стійкі до помилок пам'яті: експериментальне вивчення словників. Журнал експериментальної алгоритміки (JEA), 18, 1-6.

  • Italiano, GF (2010). Еластичні алгоритми та структури даних. В алгоритмах і складності (с. 13-24). Спрингер Берлін Гейдельберг.

Якщо вам цікаво дізнатися більше про сферу стійких структур даних, ви можете перевірити твори Джузеппе Ф. Італіано (і пропрацювати свій шлях через посилання) та модель Failed-RAM (представлена ​​в Finocchi et al. 2005; Finocchi та Italiano 2008).

/ EDIT: Я ілюстрував запобігання / відновлення з м'яких помилок, головним чином для оперативної пам'яті та зберігання даних, але не говорив про помилки обчислень (CPU) . Інші відповіді вже вказували на використання атомних транзакцій, як у базах даних, тому я запропоную іншу, простішу схему: надмірність і голосування більшості .

Ідея полягає в тому, що ви просто робите x разів однакові обчислення для кожного обчислення, що вам потрібно зробити, і зберігаєте результат у x різних змінних (з x> = 3). Потім можна порівняти свої змінні x :

  • якщо вони згодні, то помилки в обчисленні взагалі немає.
  • якщо вони не згодні, ви можете використовувати більшість голосів, щоб отримати правильне значення, і оскільки це означає, що обчислення було частково пошкоджено, ви також можете запустити сканування стану системи / програми, щоб перевірити, чи все в порядку.
  • якщо більшість голосів не може визначити переможця (усі значення x різні), то це ідеальний сигнал для запуску процедури безвідмовної роботи (перезавантаження, підвищення попередження для користувача тощо).

Ця схема надмірності є дуже швидкою порівняно з ECC (практично O (1)) і дає вам чіткий сигнал, коли вам потрібно відмовитися . Більшість голосів також (майже) гарантують, що ніколи не даватимуть пошкоджених результатів, а також відновлюватись від незначних помилок обчислень , оскільки ймовірність того, що x обчислення дають однаковий результат, є нескінченно малою (оскільки існує величезна кількість можливих результатів, майже неможливо випадковим чином отримують 3 рази те саме, ще менше шансів, якщо x> 3).

Отже, маючи більшість голосів, ви захищені від пошкодженого виводу, а при надмірності x == 3 ви можете відновити 1 помилку (при x == 4 це буде виправлено 2 помилки тощо) - точне рівняння - nb_error_recoverable == (x-2)х число - точне повторів обчислень, оскільки для відновлення потрібно використовувати принаймні два узгоджені розрахунки, використовуючи більшість голосів).

Недолік полягає в тому, що вам потрібно обчислити х разів замість одного разу, так що у вас є додаткові витрати на обчислення, але лінійна складність настільки асимптотично, що ви не втрачаєте багато заради отриманих переваг. Швидкий спосіб зробити більшість голосів - це обчислити режим на масиві, але ви також можете використовувати середній фільтр.

Крім того, якщо ви хочете переконатися, що обчислення ведуться правильно, якщо ви можете зробити власне обладнання, ви можете сконструювати свій пристрій за допомогою x процесорів та підключити систему, щоб обчислення автоматично дублювалися через x процесори з більшістю голосів. механічно в кінці (наприклад, використовуючи ворота AND / OR). Це часто реалізується в літаках та критично важливих пристроях (див. Потрійну модульну надмірність ). Таким чином, у вас не виникне жодних обчислювальних витрат (оскільки додаткові обчислення будуть проводитися паралельно), і у вас є ще один рівень захисту від м'яких помилок (оскільки дублювання обчислень та голосування більшості будуть керуватися безпосередньо апаратними засобами, а не програмне забезпечення - яке може легше пошкодитися, оскільки програма просто біти, що зберігаються в пам'яті ...).


9

Один момент, здається, ніхто не згадував. Ви кажете, що ви розвиваєтеся в GCC та перекладаєте на ARM. Звідки ви знаєте, що у вас немає коду, який передбачає припущення про вільну оперативну пам’ять, цілий розмір, розмір вказівника, скільки часу потрібно для певної операції, скільки часу система буде працювати безперервно, або подібні різні речі? Це дуже поширена проблема.

Відповідь, як правило, є автоматизованим тестуванням одиниць. Напишіть тестові джгути, які виконують код у системі розробки, а потім запустіть ті самі тестові джгути на цільовій системі. Шукайте відмінності!

Також перевірте наявність помилок на вбудованому пристрої. Ви можете виявити щось про "не робити цього, тому що воно вийде з ладу, тому ввімкніть цей варіант компілятора і компілятор обійде його".

Словом, найімовірнішим джерелом збоїв є помилки у вашому коді. Поки ви не переконаєтесь, що це не так, не переживайте (поки що) про більш езотеричні режими відмов.


1
Дійсно, ніде в тесті запитання автор не згадує, що програма виявилася справною за межами радіоактивного середовища.
Марк.2377,

9

Вам потрібно 3+ раб-машини з майстром поза радіаційним середовищем. Весь вхід / вивід проходить через головний механізм, який містить механізм голосування та / або повторного спроби. Раби повинні мати апаратну сторожову собаку кожного, і заклик їх нарізати повинен бути оточений СРС або подібним, щоб зменшити ймовірність мимовільного удару. Нахил повинен контролювати ведучий, тому втрачений зв’язок з майстром дорівнює перезавантаженню протягом декількох секунд.

Однією з переваг цього рішення є те, що ви можете використовувати той же API для ведучого, що і для рабів, тому надмірність стає прозорою особливістю.

Редагувати: З коментарів я відчуваю потребу уточнити "ідею CRC". Можливість нападника рабовласницької власної сторожової собаки близька до нуля, якщо ви оточуєте груди CRC або дайджест перевірки випадкових даних від майстра. Ці випадкові дані надсилаються від ведучого лише тоді, коли раб, який знаходиться під контролем, узгоджується з іншими. Випадкові дані та CRC / дайджест негайно видаляються після кожного удару. Частота нахилу головного підлеглого повинна бути більше ніж удвічі більше, ніж удвічі вичерпана. Дані, що надсилаються від ведучого, щоразу створюються унікально.


7
Я намагаюся розробити сценарій, коли ви можете мати господаря поза радіаційним середовищем, здатного надійно спілкуватися з рабами всередині радіаційного середовища, де ви не могли просто поставити рабів поза радіаційним середовищем.
fostandy

1
@fostandy: Раби або вимірюють, або контролюють, використовуючи обладнання, яке потребує контролера. Скажіть лічильник гейгера. Майстер не потребує надійного спілкування через надмірність рабів.
Jonas Byström

4
Представлення майстра автоматично не означатиме підвищення безпеки. Якщо раб x зійшов з розуму через пошкодження пам’яті, щоб він неодноразово казав собі «господар тут, господар щасливий», то жодна кількість CRC-пакетів або наказових замовлень майстра не врятує його. Ви б мали дати господареві можливість скоротити владу цього раба. І якщо у вас є загальна причина помилки, додавання більше рабів не підвищить безпеку. Також пам’ятайте, що кількість помилок програмного забезпечення та кількість речей, які можуть зламатися, збільшуються зі складністю.
Лундін

5
Зважаючи на це, було б, звичайно, приємно «передавати» більшу частину програми десь менш підданому впливу, зберігаючи електроніку всередині радіоактивного середовища максимально просто, якщо у вас є такий варіант.
Лундін

7

Як щодо запуску багатьох примірників вашої програми. Якщо збої трапляються через випадкові зміни біту пам'яті, швидше за все, деякі з ваших програм додадуть це та дадуть точні результати. Напевно, досить легко (для когось із статистичним досвідом) підрахувати, скільки екземплярів вам потрібно з урахуванням ймовірності бітового флопу, щоб досягти якнайменшої невеликої загальної помилки.


2
Безумовно, вбудована система буде віддавати перевагу критичним захопленням безпеки в одному екземплярі надійного додатку, ніж просто вистрілення декількох примірників, підвищення вимог до обладнання та певною мірою сподівання на сліпу везіння, що хоча б один екземпляр робить це добре? Я розумію, що це дійсно, але більше
схиляйтесь

7

Те, що ви запитуєте, досить складна тема - не легко відповідати. Інші відповіді в порядку, але вони охоплювали лише невелику частину всього, що вам потрібно зробити.

Як видно в коментарях , виправити проблеми з апаратним забезпеченням неможливо на 100%, проте можна з високою ймовірністю зменшити або наздогнати їх за допомогою різних методик.

Якби я був ти, я створив би програмне забезпечення найвищого рівня безпеки цілісності (SIL-4). Отримайте документ IEC 61513 (для ядерної промисловості) та дотримуйтесь його.


11
А точніше, прочитайте технічні вимоги та застосуйте ті, що мають сенс. Значна частина стандартів SIL - це нісенітниця, якщо дотримуватись їх догматично, ви опинитесь небезпечними та небезпечними продуктами. Сьогодні сертифікація SIL в основному полягає у створенні тонни документації, а потім підкупі тестового будинку. Рівень SIL нічого не говорить про фактичну безпеку системи. Натомість вам захочеться зосередитись на фактичних технічних заходах безпеки. У документах SIL є кілька дуже хороших, а є і цілковиті дурниці.
Лундін

7

Хтось згадав, що використовує повільніші чіпи, щоб іони не легко перевертали біти. Аналогічно, можливо, використовуйте спеціалізований процесор / операційний пам'ять, який фактично використовує кілька біт для зберігання одного біта. Таким чином, забезпечується апаратне відмовлення від помилок, оскільки малоймовірно, що всі біти будуть перевернуті. Так 1 = 1111, але потрібно було б потрапити 4 рази, щоб насправді перевернути. (4 може бути поганим числом, оскільки якщо два біти перевернуть його вже неоднозначно). Отже, якщо ви переходите з 8, ви отримуєте в 8 разів менше оперативної пам’яті та деяку частку більш повільного часу доступу, але набагато більш надійне представлення даних. Можливо, ви могли б зробити це як на програмному рівні за допомогою спеціалізованого компілятора (виділіть на х кількість більше місця для всього) або мовної реалізації (запишіть обгортки для структур даних, які розподіляють речі таким чином).


7

Можливо, це допоможе дізнатись, чи означає це обладнання, "яке призначене для цього середовища". Як це виправляє та / або вказує на наявність помилок SEU?

На одному з проектів, пов'язаних з космічним дослідженням, у нас був спеціальний MCU, який би викликав виняток / переривав помилки SEU, але з деякою затримкою, тобто деякі цикли можуть проходити / виконуватись інструкції після того, як той інн, який спричинив виключення SEU.

Особливо вразливим був кеш даних, тому обробник недійсний рядок кешу порушень і перезапустив програму. Тільки те, що через неточний характер винятку, послідовність візків на чолі з винятком, що підвищує виняток, може бути не перезапущена.

Ми визначили небезпечні (не перезавантажувані) послідовності (як-от lw $3, 0x0($2), слідом за ними, інсн, який змінюється $2і не залежить від даних $3), і я вніс зміни в GCC, тому такі послідовності не трапляються (наприклад, в крайньому випадку, відокремлюючи два ханни по а nop).

Просто щось врахувати ...


7

Якщо ваша апаратура виходить з ладу, ви можете використовувати її для зберігання. Якщо база вашого коду невелика і у вас є фізичний простір, ви можете використовувати механічний сховище даних.

Введіть тут опис зображення

Буде поверхня матеріалу, на яку не буде впливати випромінювання. Кілька передач будуть там. Механічний зчитувач буде працювати на всіх передачах і буде гнучким для руху вгору і вниз. Вниз означає, що це 0, а вище означає, що це 1. З 0 і 1 ви можете генерувати свою кодову базу.


2
Можливо, оптичне носій, такий як CD-ROM, відповідав би цьому визначенню. Він мав би додатковий бонус великої ємності.
Wossname

2
Так, це буде схоже, але CD-ROM буде використовувати менше, але це буде повністю механічна система.
Гітул

7
Цікаво, чи є причина, чому вони не використовують зчитувачі перфокарт у просторі.
Сорен

3
@Soren Швидкість і фізичний простір можуть бути причиною.
Гітул

5

Використовуйте циклічний планувальник . Це дає можливість додавати регулярні терміни обслуговування, щоб перевірити правильність критичних даних. Найбільш часто виникає проблема - корупція стека. Якщо ваше програмне забезпечення є циклічним, ви можете повторно реалізувати стек між циклами. Не використовуйте повторно стеки для переривчастих дзвінків, встановіть окремий стек кожного важливого виклику переривання.

Аналогічна концепція сторожової служби - це терміни встановлення термінів. Запустіть апаратний таймер перед викликом функції. Якщо функція не повертається до того, як таймер кінцевого терміну перерветься, перезавантажте стек і повторіть спробу. Якщо вона все-таки не працює після 3/5 спроб, вам потрібно перезавантажити з ПЗУ.

Розділіть програмне забезпечення на частини та ізолюйте ці частини, щоб використовувати окремі області пам’яті та час виконання (особливо в контрольному середовищі). Приклад: отримання сигналу, попередня обробка даних, основний алгоритм та реалізація / передача результатів. Це означає, що збій в одній частині не спричинить збоїв через решту програми. Тож, поки ми ремонтуємо прийом сигналу, решта завдань продовжується щодо застарілих даних.

Всьому потрібні CRC. Якщо ви виконуєте оперативну пам’ять, навіть ваш .text потребує CRC. Регулярно перевіряйте CRC, якщо ви використовуєте циклічний планувальник. Деякі компілятори (не GCC) можуть генерувати CRC для кожного розділу, а деякі процесори мають спеціальне обладнання для виконання обчислень CRC, але я думаю, що це не вийшло б за рамки вашого питання. Перевірка CRC також спонукає контролер ECC на пам'ять виправити одиночні бітові помилки, перш ніж це стане проблемою.


4

По-перше, спроектуйте свою програму на відмову . Переконайтесь, що в рамках нормальної роботи потоку очікується його скидання (залежно від вашої програми та типу відмови або м'якого, або жорсткого). Це важко домогтися ідеального: критичні операції, які вимагають певної міри транзакцій, можуть знадобитися перевірити та підлаштувати на рівні складання, щоб переривання у ключовій точці не могло призвести до непослідовних зовнішніх команд. Збій швидко, як тільки виявлено непоправне пошкодження пам'яті або відхилення потоку управління. Пошкодження журналу, якщо це можливо.

По-друге, де це можливо, виправити корупцію та продовжувати . Це означає часто перевіряти суми та фіксувати постійні таблиці (і код програми, якщо можна); можливо, перед кожною великою операцією або тимчасовим перериванням, а також зберігання змінних у структурах, які автокорегуються (знову перед кожним головним оп або тимчасовим перериванням, приймайте більшість голосів від 3 і виправляйте, якщо є одне відхилення). Якщо можливо, виправлення журналу.

По-третє, несправність тесту . Створіть тестове середовище, що повторюється, яке відбиває біти в пам'яті psuedo-випадковим чином. Це дозволить вам повторити корупційні ситуації та допоможе розробити ваші програми навколо них.


3

З огляду на коментарі supercat, тенденції сучасних компіляторів та інші речі, я б спокусився повернутися в стародавні часи і записати весь код у складі та статичному розподілі пам'яті скрізь. Зважаючи на таку повну надійність, я думаю, що збірка більше не несе великої відсоткової різниці у вартості.


Я великий шанувальник асемблерської мови (як видно з моїх відповідей на інші запитання), але я не думаю, що це є гарною відповіддю. Цілком можна дізнатися, чого очікувати від компілятора для більшості коду С (з точки зору значень, що живуть у регістрах проти пам'яті), і ви завжди можете перевірити, чи це те, чого ви очікували. Написання великого проекту в Asm - це лише велика кількість зайвих робіт, навіть якщо у вас є розробники, які дуже зручно писати ARM ASM. Можливо, якщо ви хочете зробити такі речі, як обчислити один і той же результат 3 рази, писати деякі функції в ASM має сенс. (укладачі відіб’ють це)
Пітер Кордес

Більш високий ризик, який в противному випадку має бути збалансований, оскільки оновлення компілятора може залишити вас несподіваними змінами.
Джошуа

1

Ось величезна кількість відповідей, але я спробую підсумувати свої ідеї з цього приводу.

Щось виходить з ладу або працює неправильно, може бути результатом ваших власних помилок - тоді це слід легко виправити, коли ви знайдете проблему. Але є й можливість апаратних збоїв - і це складно, якщо не неможливо, виправити в цілому.

Я б рекомендував спершу спробувати вловити проблемну ситуацію за допомогою входу в систему (стек, регістри, виклики функцій) - або ввівши їх десь у файл, або передавши їх якось безпосередньо ("о ні, я збиваюся").

Відновлення після такої помилки - це або перезавантаження (якщо програмне забезпечення все ще живе і натискання) або скидання обладнання (наприклад, сторожові собачі). Простіше почати з першого.

Якщо проблема пов'язана з обладнанням - то реєстрація повинна допомогти вам визначити, у якій функції виникає проблема виклику, і це може дати вам всебічне знання про те, що не працює і де.

Крім того, якщо код відносно складний - має сенс "розділити і перемогти" його - це означає, що ви видаляєте / відключаєте деякі виклики функцій, де у вас є підозра на проблему - як правило, вимкнення половини коду та включення іншої половини - ви можете отримати "працює" / Рішення "не працює", після якого ви можете зосередитися на іншій половині коду. (Де проблема)

Якщо проблема виникає через деякий час - тоді можна запідозрити переповнення стека - тоді краще контролювати регістри точок стека - якщо вони постійно зростають.

І якщо вам вдасться повністю мінімізувати свій код до тих пір, поки додаток "привіт світ" - і це все ще не вдається випадковим чином - тоді очікуються проблеми з обладнанням - і там має бути "оновлення обладнання" - це означає винаходити такий процесор / ram / ... -збірник посуду, який краще переносить радіацію.

Найголовніше - це, мабуть, як ви повернете свої журнали, якщо машина повністю зупинена / перезавантажена / не працює - напевно, перше, що потрібно зробити при завантаженні, - це повернутися додому, якщо проблематична ситуація виявиться неполадовою.

Якщо у вашому оточенні можливо також передавати сигнал і отримувати відповідь - ви можете спробувати створити якесь онлайн-середовище віддаленої налагодження в Інтернеті, але тоді у вас повинен бути принаймні робочий носій зв'язку та деякий процесор / деякий операційний режим у робочому стані. Під віддаленою налагодженням я маю на увазі або тип підходу GDB / gdb, або власну реалізацію того, що вам потрібно повернути зі своєї програми (наприклад, завантажувати файли журналів, завантажувати стек викликів, завантажувати оперативність, перезавантажувати)


Вибачте, але питання стосується радіоактивного середовища, де будуть виникати збої обладнання. Ваша відповідь стосується загальної оптимізації програмного забезпечення та способів пошуку помилок. Але в цій ситуації, невдачі не виробляються помилками
Джеб

Так, ви можете звинувачувати також земну гравітацію, оптимізацію компілятора, сторонні бібліотеки, радіоактивне середовище тощо. Але ви впевнені, що це не ваші власні помилки? :-) Якщо не доведено - я не вірю в це. Я колись запускав деякі оновлення мікропрограмного забезпечення та тестував ситуацію з потужністю - моє програмне забезпечення пережило всі ситуації з потужністю лише після того, як я виправив усі свої помилки. (Більше 4000 жителів за нічний час) Але важко повірити, що в деяких випадках була помилка. Особливо, коли ми говоримо про корупцію пам’яті.
ТармоПікаро

0

Я справді прочитав багато чудових відповідей!

Ось мій 2 цент: побудувати статистичну модель аномалії пам'яті / реєстру, написавши програмне забезпечення для перевірки пам'яті або для частого порівняння реєстру. Далі створіть емулятор у стилі віртуальної машини, де можна експериментувати з проблемою. Я думаю, якщо ви змінюєте розмір з'єднання, тактову частоту, постачальник, корпус тощо, спостерігатимете іншу поведінку.

Навіть наша пам'ять настільних ПК має певну швидкість виходу з ладу, що, однак, не шкодить щоденній роботі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.