Pull to refresh

Comments 61

PinnedPinned comments

Добавлю программных методов защиты от сбоев RAM, как аппаратных, так и программных сбоев.

1) Минимизация времени хранения объекта в RAM. Если возможно, нужно стремиться исключить длительное хранение в RAM таких объектов, которые нельзя валидировать, вместо нужно заменять это хранение на вычисление таких объектов, которых можно валидировать. Например, вместо хранения указателя вычислять его из индекса и базового указателя из ROM. В этом случае указатель в ROM будет периодически контролироваться подсчётом CRC прошивки, а индекс обычно имеет довольно узкий диапазон валидных значений, который легко быстро проверить перед его использованием. Это даёт возможность очень быстро (за микро или миллисекунды) обнаружить сбой в RAM, который иначе может не обнаруженным часами или даже годами, пока не проявится в поведении системы.

2) Локализация данных блоков данных частей программы и контроль неизменности их содержимого вне интервала доступа в этим данных. Если есть некий объект в RAM, данные которого могут и именоваться периодически, на интервале времени, составляющем, малую часть всего цикла работы программы, то после изменения этих данных можно защитить этот блок памяти, пересчитав его контрольный код - например CRC или контрольную сумму, а перед использования этих данных - проверить его. Это может достигнуто уменьшения времени возникновения сбоя, который может остаться незамеченным.

3) Программный watchdog на аппаратном таймере. Из-за того, что аппаратный watchdog нередко основывается на RC-генераторе, его точность часто оставляет желать лучшего. В этом случае можно дополнить его программный watchdog-ом на аппаратном таймере с большей точностью, на кварцевом генераторе, и функцией Window watchdog , если она не доступно аппаратно, или тоже имеет проблемы с точностью.

4) Предупреждения о подозрительных таймингах на основе таймера. Очень полезны для отладки. О то время, как watchdog часто программируется не очень жестко по времени, потому что иначе при изменении программы его установки придётся часто менять, предупреждения о подозрительных таймингах с более жестким контролем времени, часто позволяют заметить программный сбой без обязательной перезагрузки.

Спасибо. Еще вспоминается: 1) учет хранения LittleEndian, BigEndian, 2) возврат кодов ошибки в виде констант через enum, 3) учет мутабельности при написании функций.

Ещё добавлю 1. Проверка ALU, FPU, регистров, конвейера процессора 2. Проверка CRC ROM памяти, 3.Проверка RAM блюждающтюим битом. 4. Task монитор, следящиц за переодичностью выполнения задач. 5. Защита данных в NV контрольной суммой или инверсной копией. 6. Измерение и контроль тактовой частоты

3.Проверка RAM блюждающтюим битом.

Но как сделать так, чтобы не пострадали данные стека и глобальные переменные?

В линкере настраивается буфер или два буфера, куда предварительно копируются данные из проверяемой области.

Алгоритм такой, копируем скажем 64 байта в буфер, проверяем блок, Потом копируем данные обратно из буфера. И так всю память.

Очевидно, что в момент проверки надо запрещать все прерывания и DMA.

Есть библиотека от STM, она именно это и делает. https://www.embedded-office.com/articles/stm32-safety-platform

Измерение и контроль тактовой частоты

Это, как будто, только осциллографом можно померять на MCO пинах. Вручную.

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

Я бы ещё добавил использование специализированных IDE. Они позволяют провести отладку, профилирование, обеспечивают удобный контроль памяти. За счёт этого упрощается процесс разработки и сильно снижается вероятность ошибок связанных с человеческим фактором.)

специализированных IDE

Какие именно?

А про кучу откуда взяли? Просто куча во встроенных системах практически не используется. Знаю, что freertos, при разведывании предлагает часть озу выделить под кучу, но сам никогда этот режим не использовал.

"ты суслика видишь?"

Функция snprintf использует кучу. Функция snprintf необходима для сериализаторов структур.

Сериализаторы структур необходимы для printf отладки и для uart shell-a.

Ещё стоит при запуске смотреть смотреть reset reason если МК поддерживает

Да. Отличная вещь. Однако В STM32 такого регистра что-то не найти.

Да. В самом деле, спасибо за наводку.

Регистр RCC clock control & status register (RCC_CSR)

Для отладки - то, что надо. Однако как это может улучшить надежность прошивки мне не ясно.

чет все намешано в кучу, при это собственно о надёжности софта ничего не сказано.

про атомарные операции, дедлоки и про ограничения на работу в прерываниях ничего не сказано.
про прерывания вообще какой-то поток, вероятно сгенерированного ИИ мутного бреда

10. Критические секции

Перед прыжком в приложение загрузчик должен отключить все прерывания. Иначе программа приложения зависнет, если в ней сработает прерывание для которого в приложении нет функции обработчика. Еще критическую секцию надо активировать при операциях с FIFO. Иначе данные могут исказиться.

Бывает такие неприятные моменты, что в многоядерных системах перезагрузка одного ядра сбрасывает прерывания другого ядра. Ибо внешние прерывания (UART, SPI и пр.) общие на все ядра.

Намедни как раз общался с ИИ на предмет вотчдогов, так вот он этих сторожевых псов очень любят

1. Сторожевой таймер (сторожевой пёс)

Ну и с русской языкой проблемы, там где к тексту ИИ добавляется отсебятина

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

И еще пять копеек нащёт ИИ из одного профильного чата
- Меняй плату , вентилятор, прессостат
- И меняй ещё дымоход.
- И диодный мост..
- А потом весь этот чат скармливается искусственному интеллекту...

Если Вас есть, возможность написать про еще какой-нибудь метод повышения надежности прошивок, то можно обсудить это в комментариях.

У нас есть.

Я в своих разработках использую концепцию здоровья ("Health") системы.

Смысл в следующем: сложные системы содержат десятки подсистем и всё это контроллировать довольно сложно.

Для каждой подсистемы вводятся "веса" и критерии работоспособности, затем специальный процесс постоянно контроллирует работу всех подсистем и выдаёт интегральный уровень её "здоровья".

Это очень удобно, чтобы одним взглядом оценить состояние сложной системы из десятков и сотен подсистем.

Тут прямая аналогия с работой биологических объектов.

21 - перестать велосипедить одно и тоже в сотый раз. Ведь у каждого эмбедера есть своя собственная реализация протокола Модбас и библиотека инициализации периферии?)

Ч.Т.Д.

  1. Разработать собственный HAL вместо готового от производителя.

  2. Стойко и упорно в одиночку выгребать баги и работать над повышением его надежности.

Там не собственный Hal а обертки sdk от вендоров с другими именами.

Ок, пусть 20 строк вместо 2-х будут считаться оберткой:

Но зачем? Три коммита, две звезды, 0 форков, 0 пулл реквестов:

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

Для сравнения либа от производителя:

600 звезд, 190 форков, 50 коммитов и, что самое важное, два десятка пул реквестов с фиксами багов:

каждый из которых кем-то выстрадан с потом, бессонными ночами и нервными клетками.

И это бич именно эмбеда. В виду отсутствия инструментов пакетной сборки, видимо.

Если подняться хотя бы до embedded linux, то уже там картина начинает разительно отличаться. Начинает появляться понимание, что можно подтянуть готовую опен сорсную либу/пакет/приложение, вместо того, чтобы изобретать собственную реализацию.

Тот репозиторий proxy mcal , это лишь иллюстрация. Его боевая версия в другом репозитории.

Перечитайте текст про proxy mcal. Там написано, что это нужно для безшовной миграции приложений с одного вендора МК на другого вендора МК.

Сейчас в РФ много stm проектов переносят на никому неизвестные китайские микроконтроллеры.

безшовной миграции приложений с одного вендора МК на другого вендора МК

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

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

много stm проектов переносят на никому неизвестные китайские микроконтроллеры

забыли уточнить, что это микроконтроллеры-клоны, не требующие никаких (практически) доработок кода))

Я всегда думал, что замена камня это форс-мажор (санкции, снятие с производства) случающийся раз в N-цать лет.

Подумай еще раз…

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

1--Прежний микроконтроллер морально устарел. Появились в продаже те, что производительнее, экономичнее и главное - дешевле.

2--Изначального микроконтроллера просто больше нет в продаже. Случился кризис полупроводников.

2--Прежний микроконтроллер невозможно больше купить в нужных количествах

3--Государство-производитель микроконтроллера наложило Санкции и Эмбарго на поставки своего микроконтроллера на Вашу территорию.

4--В новой версии продукта понадобился новый функционал (например Bluetooth 5.3), которого не было в предыдущем микроконтроллере на PCB. Всё. Меняем МК.

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

7--Даже если Вы работаете только с одним семейством MCU, то рано или поздно Вы столкнётесь с багом, который захочется попробовать воспроизвести на другом микроконтроллере. И тут-то Вам понадобится собрать, то же приложение на , условно, STM32 или ESP32.

8--Менеджер проекта получил взятку (подарок) от производителя микроконтроллеров , чтобы в очередной версии серийного продукта компании был именно микроконтроллер от этого конкретного производителя (который дал взятку естественно). Это не шутка, я такое видел.

1. Прежний микроконтроллер морально устарел

2. Изначального микроконтроллера просто больше нет в продаже

3. Государство-производитель микроконтроллера наложило Санкции

4. В новой версии продукта понадобился новый функционал

8. Менеджер проекта получил взятку

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

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

Не успели закупить в нужном количестве, - переходим на новый камень)))

6. в офисе может банально не хватить отладочных плат

Нет под рукой отладочной платы - переходим на новый камень)))

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

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

Погуглил для интереса "STMicroelectronics longetivity", "TI longetivity", - 10-15 лет. Предостаточный срок, чтобы разработанное устройство успело морально устареть и перестать продаваться прежде, чем используемый камень снимут с производства.

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

Как-н на свалке авто посмотрите выковыренные блоки ЭРА-ГЛОНАС. Увидите там одни и те же блоки на основе Infenion, Artery, SPC56 и прочие экзотические MК.

забыли уточнить, что это микроконтроллеры-клоны, не требующие никаких (практически) доработок кода))

STM32, Nrf52, Nrf53, cc26x2, YunTu, Artery, FlagChip, Esp32 отличаются между собой как снежинки.

Каждый второй эмбедер пилит что-то свое.

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

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

Свой Hal только ИТЭЛМА пишет .

Добавлю программных методов защиты от сбоев RAM, как аппаратных, так и программных сбоев.

1) Минимизация времени хранения объекта в RAM. Если возможно, нужно стремиться исключить длительное хранение в RAM таких объектов, которые нельзя валидировать, вместо нужно заменять это хранение на вычисление таких объектов, которых можно валидировать. Например, вместо хранения указателя вычислять его из индекса и базового указателя из ROM. В этом случае указатель в ROM будет периодически контролироваться подсчётом CRC прошивки, а индекс обычно имеет довольно узкий диапазон валидных значений, который легко быстро проверить перед его использованием. Это даёт возможность очень быстро (за микро или миллисекунды) обнаружить сбой в RAM, который иначе может не обнаруженным часами или даже годами, пока не проявится в поведении системы.

2) Локализация данных блоков данных частей программы и контроль неизменности их содержимого вне интервала доступа в этим данных. Если есть некий объект в RAM, данные которого могут и именоваться периодически, на интервале времени, составляющем, малую часть всего цикла работы программы, то после изменения этих данных можно защитить этот блок памяти, пересчитав его контрольный код - например CRC или контрольную сумму, а перед использования этих данных - проверить его. Это может достигнуто уменьшения времени возникновения сбоя, который может остаться незамеченным.

3) Программный watchdog на аппаратном таймере. Из-за того, что аппаратный watchdog нередко основывается на RC-генераторе, его точность часто оставляет желать лучшего. В этом случае можно дополнить его программный watchdog-ом на аппаратном таймере с большей точностью, на кварцевом генераторе, и функцией Window watchdog , если она не доступно аппаратно, или тоже имеет проблемы с точностью.

4) Предупреждения о подозрительных таймингах на основе таймера. Очень полезны для отладки. О то время, как watchdog часто программируется не очень жестко по времени, потому что иначе при изменении программы его установки придётся часто менять, предупреждения о подозрительных таймингах с более жестким контролем времени, часто позволяют заметить программный сбой без обязательной перезагрузки.

1) Минимизация времени хранения объекта в RAM.

Что больше подвержено влиянию радиации: RAM или ROM?

Фактических данных у меня об этом нет, но если оценивать это логически, то флэш-память должна быть более чувствительна, чем статическая RAM. Масочная или однократно-прожигаемая ROM - менее чувствительна. А DRAM - зависит от технологических норм (процесса). Флэш-память также, наверное, может накапливать субпороговые уровни радиации.

то флэш-память должна быть более чувствительна, чем статическая RAM. 

Видимо поэтому на космическом микроконтроллере 5023ВС016 вообще нет Flash памяти. Прошивают на пусковом столе и отправка в космическую бездну.

Вспомнил о ещё одном способе повышения надежности встраиваемого ПО - хранении нескольких копий прошивки и периодическом обновлении прошивок повторной перепрошивкой. Это уже не так актуально, как было было когда-то, в эпоху УФ-стираемых ROM, но для настоящей надёжности всё ещё нужно и для фэлш-памяти. Не только, работающей при повышенных уровнях радиации, но и в обычных условиях, и особенно в промышленных условиях, при возможности воздействия мощных помех, уровень которых может превысить предел, штатный для используемого оборудования. Для плановой повторной перепрошивки нужно иметь не менее 3 копии прошивки - обновляемая в данный момент, рабочая, а резервная. При этом, если микроконтроллер поддерживает 2 банка встроенной памяти, например как многие из STM32, переключение между прошивками может происходить очень быстро. И все эти копии нужно постоянно проверять, как правило подсчёта CRC.

Минимизация времени хранения объекта в RAM.

Мне кажется это попытка уменьшить шансы на сбой, а не инженерное решение проблемы. Если есть возможность порчи хоть одного бита в RAM от внешних воздействий, то никакое быстрое использование не дает 100% гарантии, бит может "поплыть" в любую микросекунду. К тому же, регистры в самом CPU это такие же ячейки памяти, их вы никак не "минимизируете", а они подвержены тем же частицам и помехам.

По такой логике можно перейти на функциональные языки и не хранить стейты. Для гарантированной защиты нужно использовать либо аппаратный ECC, либо многократное дублирование данных с мажоритарным голосованием

Не какое инженерное решение проблемы аппаратных сбоев не может гарантировать их исключение на 100% - только уменьшить их вероятность настолько, этой вероятностью можно пренебречь на практике. То же широко применяемые на практике для критических по безопасности систем работа процессора в режиме Lockstep и мажорирование лишь уменьшает довольно низкую вероятность умножением на другую низкую вероятность сбоя, нередко несколько раз, до достижения приемлемо низкой невероятности сбоя. Даже применение радиационно-стойких процессоров в устройствах работающих без повышенных уровнях радиации не гарантирует исключения сбоев из-за космических лучей высоких энергий. Минимизация времени хранения объекта в RAM способна уменьшить время его хранения на много порядков, а значит и вероятность сбоя - тоже на много порядков. Само по себе это не сделает систему надёжной, но мультипликативный эффект многих мер повышение надёжности - сделает. Регистр в самом CPU это такие же ячейки памяти, но принципиальное отличие их от RAM - в их количестве - оно на порядки больше количества регистров, а значит и вероятность сбоя тоже отличается на порядки.

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

Ещё желательно сразу предусматривать альтернативные каналы для внешних измерений

Алгоритмы DSP нужно разрабатывать так, чтобы они были вычислительно устойчивыми (numerically stable):

  • к шумам в младших битах входных данных - малая погрешность на входе не должна резко усиливаться на выходе;

  • к выбросам, экстремальным значениям, Inf и NaN - такие значения не должны ломать вычисления;

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

Сторожевой таймер позволяет автоматически перезагрузиться...

И при этом можно нарваться на АВАРИЮ. Или даже КАТАСТРОФУ. Я бы, кстати, рекомендовал использовать авиационное определение, что авария это катастрофа без человеческих жертв. Или катастрофа - авария с жертвами.

И снова про сброс. Иногда надо чётко понимать, в с какого места делать рестарт. Представьте, у вас идет техпроцесс. Сушка, к примеру. Где чётко расписана температурная кривая, сначала погорячее, потом похолоднее. И вы делаете рестарт... с начал техпроцесса. А есть такие вещества, которые очень не любят нагрев в сухом виде.

Особый шик задача приобретает при мажорирование или в режиме Lockstep.

Можно, но зачем? (С) :)

Я пытался пошутить.

И при этом можно нарваться на АВАРИЮ. Или даже КАТАСТРОФУ. Я бы, кстати, рекомендовал использовать авиационное определение, что авария это катастрофа без человеческих жертв. Или катастрофа - авария с жертвами.

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

Катастрофа. Пострадали люди.

1) отказ от использования функций типа printf, scanf

2) вместо изобретения хитромудрых способов отлова переполнения стека и кучи - использовать РАСЧЕТ потребного размера стека задач ос и прерываний, запрет динамического выделения памяти (misra однако)

3) использование статического анализатора кода

РАСЧЕТ потребного размера стека задач ос

А что делать если в прошивке нет RTOS?

Механизм расчета стека ничего не знает про наличие ртос. Он считает размер стека указанной функции (функций). Выберите сами в своем проекте нужную функцию. А также функции обработчика(ов) прерываний

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

Какой статический анализатор порекомендуете?

Я пользуюсь возможностями IAR. И для расчета стеков и анализатором. И проверкой на правила misra

Я пользуюсь возможностями IAR. И для расчета стеков и анализатором

А что делать тем, кто собирает GCC?

Завидовать молча) на самом деле в гцц есть зачатки подобного (ключи компиляции + скрипт на питоне (забыл название)) но на момент 2019г для процессора есп8266 мне не удалось довести использование этих зачатков до получения реального результата. Возможно, на текущее время чтото изменилось в лучшую сторону. Это если что, камень в огород гцц. Ибо комерческие среды такой механизм имеют давно. Я его использкю с начала 2000х. Среду называть, пожалуй,

не стоит ибо уже неактуальная

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

Если уж и использовать IAR, то только его консольные утилиты: iccarm.exe, iasmarm.exe, ielftool.exe , iarchive.exe , ilinkarm.exe.
Вызывать их из Mаke.
Суть в том, чтобы иcпользовать IAR без .ewp файлов.
Тогда это нормально и здорово.

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

Ну это давно известный прием, практически все ртос его имеют, как и контроль стека задач "на лету" с выпадением в ловушку. Но это все борьба с УЖЕ случившейся проблемой. А мы выше обсуждали способ недопущения этой проблемы

Сейчас, в большинство микроконтроллеров встроена BIST (Built-In Self Test) аппаратура для тестирования узлов (память, цпу, т.д.) прямо в микроконтроллере.

Sign up to leave a comment.

Articles