Владимир Паронджанов писал(а):
Я попросил Сергея Ефанова из Липецка высказать свое мнение по данному вопросу. Вот его ответ:
Цитата:
Ньюансы применения Дракона в ПЛК мне неведомы, я ПЛК не программировал.
Поясню смысл "ПЛК".
ПЛК это компьютер, у которого есть:
1) Входы. Грубо говоря, значения подключенных датчиков.
2) Выходы. Грубо говоря, команды на управление внешними механизмами, замыкание/размыкание реле.
3) Связь с другими модулями (например, может быть внешний двигатель, которому ПЛК периодически передаёт значение скорости, а от него получает информацию о состоянии)
Так вот: прикладной код должен иметь возможность читать значения входов и изменять состояние выходов. Но возникает вопрос: в какой момент значения входов должны обновляться?
Например, если у ПЛК 10 выходов, и в программе мы записали единицу в каждый из выходов. Должны ли они включиться одновременно, или допутима задержка?
Если программа работает в вытесняющей многозадачности, то может оказаться, что выходы будут активироваться по одному.
Это будет запутывать, особенно неподготовленных программистов.
Гораздо проще составлять программу, если подразумевать, что "мир остановился в момент выполнения программы".
Как раз в в МЭК61131 такой подход и выбран.
Попросту говоря, это вытесняющая многозадачность, где возврат управления происходит лишь при завершении прикладного кода.
Шаг1) ПЛК опрашивает состояние входов
Шаг2) Выполняется пользовательская программа. При этом, программе запрещено зацикливаться, и выполниться одна должна максимально быстро.
В момент выполнения пользовательского кода состояние входов-выходов не изменяется. Т.е. пользовательский код работает с переменными=-копиями.
Шаг3) ПЛК выполняет служебные задачи на протяжении 1мс. Выполняется обработка сетевого взаимодействия и т.п.
Шаг4) По результатам работы Ш2 обновляются значения выходов
Шаг5) переход к шагу 1
На самом деле, на служебные задачи отводится не 1мс, а (1мс-длительность_шага_2). Таким образом обеспечивается то, что значения входов обновляются каждую миллисекунду.
Но при этом, если прикладной код слишком долго не возвращает управление, то система перезагружается. Как правило, более 2-5 секунд это уже перезагрузка.
То, что пишет Сергей Ефанов подходит для игрушечного примера, а к реальной задаче (с обработкой сетевого взаимодействия) уже не применить.
Проблема "Дракон-ПЛК" звучит так:
1) С точки зрения Дракона, ожидание таймера это "цикл ждать". Если сделать "цикл" в лоб (без возврата управления), то это приведёт к перезагрузке.
2) Если на уровне Дракон компилятора компилировать икону "цикл ждать" так, чтобы она таки возвращала управление в систему, то возникает ситуация, когда между действиями обновляются значения входов-выходов. Скажем, если возврат управления (т.е. обновление входов-выходов) может произойти в момент иконы ожидания, то может ли этот возврат управления в ОС произойти в момент других икон?
3) Если разрешить возврат управления после каждой иконы, то понимать программу, наверное, будет сложнее, ведь получается, что состояние входов-выходов сможет измениться в каждый момент
4) Вообще говоря, входов у ПЛК несколько. Например, у меня ПЛК получает сигналы от кнопок, датчиков движения, и в зависимости от них включает-выключает свет. Одна из простейших задач -- распознавание одинарного и двойного нажатия. С логической точки зрения это несложно: если обнаружено срабатывание кнопки, то запускаем таймер и в цикле ждать ждём (где-то 0.5сек) придёт ли второй. Если второго не последовало, значит было одинарное нажатие. Если пришло, значит было двойное нажатие. Тут знакомый нам "цикл ждать", и, значит, обработка кнопок должна быть в отдельных Дракон схемах (в отдельных процессах). Ну и собственно возникают вопросы "в каком порядке должны обрабатываться эти параллельные схемы", "как должны передаваться данные от одного процесса к другому" и т.п.
Если присмотреться к схеме А_МУР (большой, про насосы), то видно, что она сделана с расчётом на "возврат управления" происходит по иконе "Конец".
Из-за этого в схеме возникают нехорошие моменты:
a) код состояния=3, код состояния=4 и т.п. В соседних темах обсуждают "солнечный зайчик", который ходит по схеме и показывает где находимся, а тут глобальная переменная, которая влияет на выполнение всей схемы.
b) уже упомянутая связка "запуск таймера"-"проверка Q таймера". Логичнее было бы задействовать "циклы ждать" или что-то подобное
PS. Кстати, может быть неплохой идеей вообще созвониться. Например,
https://hangouts.google.com/ и YouTube live позволяют созваниваться со звуком/видео и записывать разговоры.