惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
Cloudbric
Cloudbric
I
InfoQ
V
V2EX
博客园_首页
The Register - Security
The Register - Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Secure Thoughts
Vercel News
Vercel News
Forbes - Security
Forbes - Security
云风的 BLOG
云风的 BLOG
PCI Perspectives
PCI Perspectives
L
LINUX DO - 最新话题
D
DataBreaches.Net
H
Hacker News: Front Page
Application and Cybersecurity Blog
Application and Cybersecurity Blog
B
Blog RSS Feed
A
About on SuperTechFans
N
News and Events Feed by Topic
Apple Machine Learning Research
Apple Machine Learning Research
Help Net Security
Help Net Security
Attack and Defense Labs
Attack and Defense Labs
N
Netflix TechBlog - Medium
Spread Privacy
Spread Privacy
F
Full Disclosure
Recorded Future
Recorded Future
AWS News Blog
AWS News Blog
博客园 - 【当耐特】
The Cloudflare Blog
T
Threatpost
T
Tor Project blog
Google DeepMind News
Google DeepMind News
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
M
MIT News - Artificial intelligence
A
Arctic Wolf
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News - Newest:
Hacker News - Newest: "LLM"
WordPress大学
WordPress大学
Cyberwarzone
Cyberwarzone
小众软件
小众软件
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
Security Latest
Security Latest
The Last Watchdog
The Last Watchdog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Как я разрабатывал отказоустойчивый промышленный контроллер. Ч1
zoshytlogic · 2026-04-24 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение10 мин

Охват и читатели637

Я, автор , независимый исследователь, разработчик SCADA системы Gatherlog

А так же автор комплекса по разработке Промышленных Контроллеров под названием 3o|||sheet. Среда, IDE читается как Зошыт - тетрадь, но так как для компилятора и среды выполнения названия не придумал, пока все называю 3o|||sheet.

Это не коммерческие проекты, в будущем планирую их сделать открытыми.

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

3o|||sheet это комплекс для разработки ПЛК на подобии Codesys. Он состоит из:

1) Среда разработки: 3o|||sheet IDE. Кроссплатформенное GUI приложение с собственным графическим движком для отрисовки LD/FBD , а так же текстовых языков. Эти языки среда транслирует в универсальный - гибридный ассемблер для компилятора.

2) Компилятор: Так же собственной разработки , пример родного синатксиса:

Types:


StackMap typedef{
  R:     dword[16];
  Size:      dword;
}
Thread typedef{
  Stack:     StackMap;
  Priority:     dword;
  IsActive:     dword;
  Time:         dword;
}
TasksManager typedef{
    tasks:                Thread[32];
    Item:                     dword;
    ProgramSegment:           dword;
    CurrentContext:           dword;
    StackBorder:              dword;
    TaskCount:         dword      0;
}


GPIO_Config typedef {
  GPIOC_BSRR:    pointer    1073811472;
  opcouner:      dword           10000;
  flagsop:       dword               1;


  outreg:          dword              0;
  count32:         dword              0;
  locconst:        dword              1;
  dvf:             dword              1;
  savvr:           dword              0;
  savvrrel:        real;
  paramrel:        real              0;
  paramrel1:        real             1;
}




Declaration:
  thread:                    TasksManager;
  gpio:                       GPIO_Config;
  floatparam:   real             8.141592;
  bufferf:      real                    0;          


 
Program:


RWCNTX RDCD R0;
JISBIT R0 0 SaveContext;
CALL InitialManager;
JMP24 Taskmanager;


SaveContext:
RWCNTX WRITE thread.CurrentContext;
MOVI       R0                    0;
RWCNTX     WRCD                 R0;
JMP24 Taskmanager;




InitialManager:
CALL                      ProgramBorder;
MOV   R15                             SP;
ADDI  R15                             32;
SDR20 R15             thread.StackBorder;
MOVI  R14           @addr(BinaryOperaty);
CALL AddTask;
MOVI  R14             @addr(MathOperaty);
CALL AddTask;
MOVI  R14             @addr(RealOperaty);
CALL AddTask;
MOVI  R14               @addr(IOOperaty);
CALL AddTask;
MOVI  R14               @addr(ItemsDown);
CALL AddTask;
RET;


AddTask:
LDR20  R15                                    thread.TaskCount;
MULI   R15                                       @size(Thread);
ADDI   R15                                 @addr(thread.tasks);
ADDI   R15                               @addr(Thread.Stack.R);
SDR    R15               R14                         @addr(PC);
LDR20  R0                                   thread.StackBorder;
SDR    R15               R0                          @addr(FP);
SDR    R15               R0                          @addr(SP);
SUBI   R0                                                  128;
SDR20  R0                                   thread.StackBorder;
RET;




/*-------------------------------------------OS--------------------------------*/
Taskmanager:
LDR20    R0                     thread.Item;
MULI     R0                   @size(Thread);
ADDI     R0             @addr(thread.tasks);
ADDI     R0           @addr(Thread.Stack.R);
SDR20    R0           thread.CurrentContext;
LDR      R2           R0          @addr(PC);
LDR20    R0          thread.CurrentContext;
CALL                                ItemsUp;
RWCNTX READ           thread.CurrentContext;
JMP32    R2;
ItemsDown:
MOVI     R0                               0;
SDR20    R0                     thread.Item;
JMP24                           Taskmanager;
ItemsUp:
LDR20    R4                     thread.Item;
ADDI     R4                               1;
SDR20    R4                     thread.Item;
RET;






ProgramBorder:
MOV  R0 PC;
ADDI R0 16;
SDR20 R0 16;
RET;




BinaryOperaty:
MOVI R0 1;
SHLI R0 15;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL Processbinary;
MOVI R0 1;
SHLI R0 31;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL Processbinary;
JMP24 BinaryOperaty;
MODE 0;


MathOperaty:
MOVI R0 1;
SHLI R0 15;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessMath;
MOVI R0 1;
SHLI R0 31;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessMath;
JMP24 MathOperaty;
MODE 0;




RealOperaty:
MOVI R0 1;
SHLI R0 13;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessReal;
MOVI R0 1;
SHLI R0 29;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessReal;
JMP24 RealOperaty;
MODE 0;






IOOperaty:
MOVI R0 1;
SHLI R0 15;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessIO;
MOVI R0 1;
SHLI R0 31;
LDR20 R1 gpio.GPIOC_BSRR;
SDPHY R1 R0;
CALL ProcessIO;
JMP24 IOOperaty;
MODE 0;

Код представляет - гибридный ассемблер:

Высокоуровневые данные, поддерживающий сложные структуры в глубину и многомерные массивы.

Инструкции - похожи на ассемблер.

В данном коде написан механизм - смены ( вытеснения) задачи: сохранение\извлечение контекста, либо инициализация если это первый запуск. Это происходит на - виртуальном уровне.

3) Рантайм, система выполнения байткода который создается компилятором, из кода представленного - выше. Написан на языке СИ.

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

Как все начиналось

Чтоб сделать ПЛК который поддерживает много языков и функций (например - замена участков кода на лету и прочее) нужен собственный рантайм и компилятор который будет переводить любые языки ( LD FBD ST) в собственные инструкции. Первая версия моего компилятора давала сбой - то одно не верно посчитает, то другое. Я столкнулся "паразитными" смещениями по адресам, а точнее - в сложных местах программа могла не туда перейти, не то прочитать или не туда записать. Программа слетала, и не понятно в каком месте была ошибка - так как при тихом повреждении данных (silent corruption), и физическим вылетом могло пройти много времени, - замучаешься пошагово следить в отладке.

Дивергентное, многоверсионное выполнении программы. DME.

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

Так и было, - две компиляции но разные структурно в памяти - все паразитные смещения из за бага компилятора - всплывали сразу. Так называемые silent corruption (скрытые ошибки) стали наблюдаемы. Это позволило точно отточить алгоритмы просчета адресов, и больше компилятор не ошибался.

Фрагмент, описание моей работы

Фрагмент, описание моей работы

Отказоустойчивые системы

После того как прототип системы был готов, задумался об отказоустойчивости, и познакомился с существующими подходами:

Lockstep - две копии (одинаковые бинарники) программы на двух процессорах работают и сверяют друг друга на каждом шаге.

TMR - три копии (одинаковые бинарники) программы на трех процессорах. Если одна отличается, происходит голосование , кто не прав и работа выполняется дальше.

Lockstep и TMR - уязвимы к коррелированным сбоям. Методы эффективны только если система замечает разницу между копиями программы, сигналит об этом. Но если оба ядра ошибаются - система не заметит ошибки, и продолжит выполнять ошибочную программу.

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

Если система Lockstep и TMR "одинаковость" воспринимают как ОК, мой метод наоборот - одинаковость воспринимает как как - осторожность. А разность - как нормальную работу. Но у моего метода есть два типа разности:

  • Допустимая разность - это адреса (адреса функций, счетчика команд, переменных и т.д).

  • Не допустимая разность - в последовательности инструкций ( семантика ).

То есть, в системах Lockstep и TMR сводится к 1/2 :

  • Либо одна из копий программы ведет себя по другому - это ошибка.

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

В моем методе DME, соотношение 1/3 . Где:

  • одинаковая логика/инструкции - это Хорошо.

  • одинаковость адресов -Плохо.

  • разная логика/инструкции - Плохо.

Я сделал более узким коридор для корректности , и расширил коридор для прохождения ошибок (усилил ошибку).

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

Практика

Создаем в моей среде - тестовый проект в языке LD. Моя среда поддерживает  FBD но так же пока только внутри LD. ST язык я не реализовал в полной мере, но на каком бы языке программа ни была, она переводится в единый виртуальный ассемблер (собственный синтаксис и инструкции, см. прошлые постыкоторый выполняется внутри на голом железе Микроконтроллера, FPGA  или любого CPU.

Интерфейс. Тяжелые функциональные блоки внутри LD подходят под тесты отказоустойчивости

Интерфейс. Тяжелые функциональные блоки внутри LD подходят под тесты отказоустойчивости

Переходим к настройкам компиляции:

- количество копий программы и количество соответственно компиляций. N Должно соответствовать количеству ядер, или ПЛК если они работают в режиме похожему на Lockstep\TMR. На STM32G030 эти ядра эмулируются, в чем смысл - дальше.

+1 -1 это команда разнесения адресов в разные по знаку стороны. Если в одной копии переход из функции А к функции Б изменяет программный счетчик например PC+=94, то в второй копии компилятор организует этот переход PC-=64. Усиливает декорреляцию адресного пространства, соответственно увеличивает область детектируемых программных багов и программных ошибок из-за физического влияния среды.

Canonical trace hash: Инкрементальный хеш выполнения программы (если есть аппаратный хеш как у Cortex M4) , но на слабом железе вместо хеша может подойти обычное сравнение каждой инструкции (опкода или результата) каждой копии программы простым "=", или хеш может быть банальным XOR с степенью ( за 2 такта, это + 10..20 наносекунд к выполнению инструкции, дешево ).

Тут принцип тот же что и Lockstep\TMR - N копий программы на ядрах, только в Lockstep\TMR сравниваются идентичные бинарники и состояние на каждом такте, у меня только логическая траектория, потому что адреса переменных и инструкций в копиях разные - они (адреса) исключаются из уравнений.

Любая программа, LD ST C++ не важно, состоит из блоков кода и функций. Мой компилятор их и перемешивает по разным адресам и разным знакам (+-) направлениям перехода. Если мы скомпилируем программу, то получим пространственные -разные версии одной программы:

N компиляций, и расположение программы в памяти. Один и тот же блок или функция - по разным адресам.

N компиляций, и расположение программы в памяти. Один и тот же блок или функция - по разным адресам.

Если мы присмотримся к адресам функций на скрине, то увидим в одной копии например Main будет по адресу - 0 (ноль) в другой копии она же будет по адресу - 144. Так и со всеми остальными. Выполняется главный принцип DME - усиление ошибки программы через структурную декорреляцию адресного пространства.

Теперь, предположим в системе произошел коррелированый сбой, то есть такой который задевает все ядра или все копии программы. Чаще это возможно  когда программа криво написана, затерла адрес возврата, или  другого участка программы. Проблемы с питанием - тоже может повредить все ядра одинаково. Радиация, или помехи. Если сбой повреждает ход только одной копии программы или ядра - то тут обычный способ известный в мире Lockstep ( и мой DME) его детектирует. Но если обе копии повреждены одновременно на одно значение, то Lockstep из-за своей одинаковости его просто не заметит, если счетчик команд попадет в валидное пространство.

Давайте предположим, что сбой произошел (неважно по какой причине) ,  адрес возврата или какого либо перехода ветки , установлен в случайное значение 148: В моем методе DME будет новый эффект:

Просмотр результата компиляции в 3o|||sheet. Одна программа - разные адреса ее компонентов.

Просмотр результата компиляции в 3o|||sheet. Одна программа - разные адреса ее компонентов.

Это вызовет - Дивергенцию. Система фиксирует - две разные инструкции одновременно: CALL и  SDPHY. Несовпадение. Компаратор вызовет программу X (типа обработчик ошибки) или  осуществит переход в безопасное состояние.

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

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

Ошибка из за физических процессов: bit flip может привести к тому что в копиях, адрес изменится на константу. В методе DME это приведет к разным участкам кода, и ошибка будет детектирована. Для этого случая в копии реплик добавляются мелкие сдвиги которые в статье пока не рассматриваются.

Ошибка из за физических процессов: bit flip может привести к тому что в копиях, адрес изменится на константу. В методе DME это приведет к разным участкам кода, и ошибка будет детектирована. Для этого случая в копии реплик добавляются мелкие сдвиги которые в статье пока не рассматриваются.

Я только на пути развития своего метода. Протестировал на Микроконтроллерах и FPGA. В микроконтроллере параллельность - программная, две программы с перемешанными адресами поинструкционно выполняются по очереди. То есть с временной задержкой, что само по себе дает отказоустойчивый эффект известный как Time redundancy, EDDI/SWIFT . В такой комбинации мой метод DME хорошо справляется с программными багами и компиляции, а Time redundancy, EDDI/SWIFT дает устойчивость к физическим влияниям на систему против кратковременных (перемежающихся) сбоев, вызванных внешними помехами (космические лучи, электромагнитные шумы)

Если брать скорость работы в отказоустойчивом режиме, что технически - дублированном, небольшие данные моего теста:

Скорость выполнения операций в микросекундах. Первое значение это базовые логические операции (контакты\катушки) второе значение - математика. Для теста язык LD лучше всего подходит для сравнения так как время выполнения у большинства брендов четко описано в документации :

Mitsubishi (китайский клон) STM32F103--2.7---------math int 8.6

Allen Bradley Micro 810 ---------------2.5---------math int 8.5

Siemens LOGO!------------------------- 5.0

Schneider Electric Zelio Logic --------10.

3o|||sheet STM32G030 ---------------- 2.1 --------math int 6.5

===3o|||sheet отказоустойчивый режим N - реплик=====================

3o|||sheet STM32G030 (N=2) ---------- 4.5 --------math int 13.5

3o|||sheetSTM32F407(N=2)----------- 2.1 -------math int/float5.2

3o|||sheetSTM32F722(N=2) -----------0.9 -------math int/float2.3

3o|||sheetCyclone lV 50 MHz (N=2)-- 0.1 -------math int 0.1

Нашему прототипу ПЛК, название не придумал и записан как 3o|||sheet.

В режиме отказоустойчивости, с циклом 10 миллисекунд, 3o|||sheet STM32G030 отработает примерно 1100 операций: 550 - логические (контакты катушки) + 550 математические.

3o|||sheet STM32F722х - вытянет в быстрых (по меркам промышленности) ПИД регуляторах в режиме отказоустойчивости.

Без дублирования, в обычном режиме наши прототипы ПЛК больше чем в два раза быстрее отказоустойчивого режима. А если сравнивать с брендами, то ПЛК на STM32G030 64MHz- производительнее чем Allen Bradley Mirco 810 или китайский клон Mitsubishi FX3 на STM32F103 72 MHz.

Altera Cyclone lV EP4CE6E22C8 даже на 50 МНz , в отказоустойчивом режиме , показывает впечатляющий результат. В цикле 1 миллисекунды отработает 8000 логических или 2000 математических (целочисленных) операций. FPGA можно сказать работал в режиме двухъядерного lockstep, только в нашем случае отслеживается траектория программы, а не состояние процессоров. Свой рантайм я переработал в Soft Processor на Verilog , выполняющий тот же байткод что и микроконтроллеры.

Я не тестировал работу с физическими помехами, сбивал счетчик программы и тихо искажал данные - программно. Лабораторные Испытания еще впереди. Но старался сделать свой метод DME - математически доказуем. Тут я не буду публиковать изобилие формул, так как считаю что концепция должна быть интуитивно понятно и так.

Программные ошибки (сюда вношу и баги компиляторов) ведут в одно и тоже ошибочное место все реплики как повреждения адресов возврата и переходов. Такие сбои как раз не покрываются традиционными методами типа lockstep/TMR. Я и разрабатываю свой метод DME для подобных ошибок, расширяя возможности обычных lockstep/TMR.

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

В целом это лишь часть из моей 30 страничной в данный момент работы DME. Тут я не рассматривал более детально механизмы детектирования пропуска инструкций внутри критических функций или блоков, когда счетчик команд во всех репликах одновременно перескакивает на одинаковое небольшое значения в плоть до 1 инструкции точности. Так же метод DME охватывает темы - верификации компиляторов, канонизации инструкций разных архитектур к единому виду, для гетерогенных систем в отказоустойчивой работе, и другие некоторые направления где я вижу потенциал DME. Если будут вопросы в комментариях - отвечу следующей статьей.