Своими разработками c нуля, решил тягаться с Rockwell Automation и Siemens в АСУ ТП
Интерфейс 3osheet , среда разработки программ на LD, FBD, частично ST, и на псевдо-ассемблере (инструкции виртуальной машины)
Все началось с работы, где я занимался системным администрированием в промышленности. После того как уволился, зная в чем нуждаются предприятия, разрабатывал собственную систему SCADA. Но решил пойти еще дальше в сторону разработки настоящего промышленного контроллера.
Цели которые поставил перед собой:
1) Среда разработки, отображающая в режиме реального времени значений переменных и место выполнения код .
2) Гибрид LD и FBD. Возможность создавать свои блоки (рисовать, и описывать на псевдо ассемблере для виртуальной машины).
3) Создание среды выполнения программ на стороне - микроконтроллера (или ПК если это SCADA).
4) Разработка изолированой среды выполнения (виртуальная ОЗУ) с заменой кода на лету. Например - отключить задачу, через MODBUS переписать или изменить ее программу, и запустить выполнение, и при этом не останавливать другие задачии и не перезагружая ПЛК физичесски.
Являюсь фанатом - оптимизации, восхищаюсь способностью выжать из минимум ресурсов - максимум эффективности. Потому выполнил важную цель - разработка и запуск виртуальной машины (собственной виртуальной машины, об этом в следующих статьях) выполняющий программу ПЛК на микроконтроллере с 8 KB ОЗУ!
Среда разработки. Написана на OpenJDK, Java весом 80мб с самыми примиитивными GUI. Легкая и работает даже на старых Raspberry PI. Если установить IDE(среду разработки с компилятором) и среду выполнения на CPU, получится самодостаточноый ПЛК Сервер, способен сам себя перепрограммировать(пользователем) без внешнего ПК.
LD программы не имеют ограничений по сложности, можно безконечно вставлять ветки друг в друга в любом месте, насколько хватит ОЗУ на стороне микроконтроллера. Мною придуман эффективный алгоритм отрисовки веток LD который не использует рекурсии или графы. Все элементы - линейны и последовательны , а двумерность программы в некоторым смысле илюзорна. Поэтому гарантировано - то что пользователь видит на экране , то видит виртуальная машина на выполнении. Новая ветка на отображении просто скачок координат на дисплее, а для виртуальной машины - скачок счетчика выполнения команд.
Трансляция LD\FBD\ST программ на язык инстукций виртуальной машины, а потом компилятором в байткод для машины
Компилятор. Программная архитектура
Несмотря на то что я пытался сделать инструкции для виртуальный машины, максимально соответствующие машинным, работу с переменными я реализовал - высокоуровневую. То есть, пользователь может создавать свои структуры любой сложности внутри, без ограничений. Типы могут в себе содержать внутри другие типы и массивы любой размерности, и эти массивы также могут внутри содержать сложные типы чередующиеся с массивами.
тут мне пришлось проделать огромную работу компиляторостроения - Memory Manager Layout.
types:
Sensor typedef {
id: word;
value: real;
is_ok: byte;
}
Status typedef {
is_running: byte;
error_code: word;
error_msg: byte[50];
}
ProductionLine typedef {
line_id: word;
sensors: Sensor[10];
production_rate: real[7][24];
status: Status;
};
Таким образом в данный момент, описание пользовательского LD FBD выглядит так:
Data:
line_1: ProductionLine;
program:
//Init
MOVI R1 1;
SDR line_1.line_id R1;
MOVI R1 TRUE;
SDR line_1.status.is_running R1;
MOVIF R2 24.5;
SDR line_1.sensors[0].value R2;
MOVIF R1 105.7;
SDR line_1.production_rate[0, 8] 105.7;
Но уже сейчас работаю над транслятором ST, чтоб можно было создавать свои LD FBD с описанием их на ST.
То есть, самый низкий уровень VM это гибрид ассемблера с высокоуровневыми данными, поддержку этого я намеренно реализовал для возможности в будущем писать код на свою платформу не только на языке ST, да хоть на Java. При этом, напомню, я разрабатывал VM способную работать на микроконтроллерах с ОЗУ от 8Кб. Да возможно если писать на языке ST , то в такой МК влезет всего под сотню строк кода, но ничего не мешает подгружать инструкции с внешней карты (если пользователю не важна строгость выполнения по времени, будут небольшие задержки), ну или взять МК с ОЗУ побольше. VM имеет эфективное адресное пространство 1 мегабайт, то есть - прочитать переменную с адресом меньше <1МБ можно за один раз:
LDR R1 R10 @ADDr(PID_CONTROLLER.setpoint);
если работать адресами по выше, то тут нужно использовать две виртуальные иснтрукции - загрузить старшие биты адреса, а потом младшие.
Что можно выжать из МК с ОЗУ 8 килобайт
Инструкции VM - 4 байтные. Одна булевая LD инструкция занимает 8 - 12 байт:
// 8 Байт, Аналог XIC
LDB R15 Reset;
JFALSE R15 Start;
//12 байт если LD читает целое, но проверяет бит
LDB R15 MPPress;
MSK R15 #5
ISFALSE Branch 2;
таким образом, в однозадачном режиме, если создавать ПЛК на МК с ОЗУ 8КБ ( 4 КБ - виртуальная ОЗУ+4 КБ нативный код СИ - сама машина), на 4 КБ виртуальной ОЗУ можно загрузить 300-400 LD (при булевых переменных - 400 LD ) инструкций и около сотни переменных размером 1-4 байта.
Если режим многозадачный ( парралельные не связанные между собой задачи) то среда разработки допишет свой код, где будет дополнительно уходить 80 байт на каждую задачу для создания виртуального стека, и около 160 байт на простейший менеджер задач, который будет управлять выполнением.
В следующей статье напишиу - как это выглядит уже на микроконтроллере.










