Последовательность поиска ошибки в программе ПЛК

в 17:49, , рубрики: плк, Программинг микроконтроллеров, Программирование, метки:
Введение

Достаточно часто в литературе мне попадались описания ошибок и даже классификации их по типам.
Хотя, признаться, у меня не получается толком вспомнить ни одного случая, когда мне бы помогло знание того, к какому именно типу относится конкретная ошибка. Разве что уже после выяснения причин, для обьяснения их окружающим.
А вот как люди вычисляли место и докапывались до сути ошибки — мне всегда было интересно.

Сведения о системе и ошибке

С компьютера на ПЛК подаются уставки (времена, флаги режимов) и команды на устройство.
Из ПЛК на компьютер выдаются сигналы статуса устройства и времени до конца команды на это устройство. Сигналы пакуются в слова, для минимизации объемов приема и передачи.
Из ПЛК на устройство выдаются команды.
Устройство выдает на ПЛК свои статусы.

image

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

Но «танцы с саблями» появлялись стабильно, при каждой команде, что очень порадовало.

Поиск

Цифрами в круглых скобках показаны места проверок, соответствующие цифрам на схеме ниже.

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

Было установлено, что ошибка присутствует не только в SCADA (1) (там, где она собственно была обнаружена), но и в OPC сервере (2).

Дальнейший разбор показал, что ошибка присутствует и в ПЛК, как минимум в слове, формируемом для компьютера (3).

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

Изменения статуса от устройства вручную ничего не меняют. При изменении статуса от устройства форсированием (принудительно, постоянно) ошибка все равно сохраняется.
Соответственно это и не импульсы, которых не видно при мониторинге (4).

Сравнение с кодами других объектов, на которых этой ошибки нет – различий не выдает. Полная идентичность. Вероятность ошибки в программе ПЛК уменьшается (5).

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

Ремарка: Также можно было, отключив ПЛК, руками менять статусы в OPC. Но такой вариант был сложнее технически, а в целом эти две проверки практически равнозначны.

Перенесение слова статуса, передаваемого из ПЛК на компьютер, в другую область памяти ПЛК ничего не дает. Ошибка сохраняется.

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

Постепенно удаляются коды, и остается практически минимум, при котором сохраняется ошибка (7)

  1. Подача команды (без нее не понятно как проверять).
  2. Таймер, с которого берется время до сброса команды.
  3. Формирование слова на компьютере из статуса и времени до сброса команды.

image

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

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

Рассматривается формирование сигнала от ПЛК, как самого вероятного кандидата на источник ошибки. Сигнал упакован для компактности в одно слово, биты статуса в старшем байте, время в младшем. Тремя командами:

  1. Запись статусов устройства в младший байт слова.
  2. Замена старшего и младшего байт местами командой SWAP_WORD (статусы переносятся в старший байт)
  3. По AND запись времени в младший байт слова

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

Заменяется последовательность команд упаковки в слово на работающую идентично, но состоящую из других операторов (9):

  1. Запись времени устройства в младший байт слова.
  2. В промежуточной переменной статусы умножаются на 256, сдвигаясь в старший байт слова.
  3. По OR производится запись статусов в старший байт слова.

Все заработало.

image

После разбора — ситуация становится окончательно понятной.

Причина ошибки:

Операторы увеличили стандартное время таймаута с 1,5 до 10 минут.
И если 1,5 минуты это 90 секунд, то 10 минут это 600 секунд.
600 секунд не влезали в младший байт (максимум 256), и часть времени писалась в старший.

Суть последней проверки:

При записи сначала времени, и лишь затем статуса – статус забивал биты переполнения, приходившие от значения времени. А при обратной последовательности команд, время наоборот забивало своими битами статус.

Решение:

Время и статусы были разбиты на 2 слова. Местным инженерам было предложено провести техобслуживание или заменить устройство с таймаутом, превышающим стандартное время более чем в 5 раз.

И они работали они долго и счастливо, и сломались в один день.

Выводы

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

По сути не очень важно, где именно ищется ошибка — в электронике, в ПЛК, на компьютере или где-то еще. Общие принципы всегда примерно одинаковы:

  1. По максимуму собрать информацию о проблеме — где и как она проявляется. Осциллографы, снифферы, утилиты от Русиновича, логи, градусники, в общем всё, что можно использовать в данном случае. Не зависит ли она от времени года, прихода уборщицы, или барометрического давления.
  2. Вывести из-под подозрения как можно большую часть. Перерезая дорожки на печатных платах, отключая теги, выводя из системы отдельные компьютеры. Хуже, если есть какие-нибудь обратные связи и прочие хендшейки. Тогда можно попытаться либо организовать проверку приняв во внимание отсутствие части системы, либо пробовать проэмулировать часть, например искусственно подавая сигнал на вход обратной связи. В общем думать.
  3. По возможности доводить каждую проверку до конца, даже если вдруг появилась «мысль!». Потому-что «мысль!» может и не сработать (и до обидного часто не срабатывает), а результатов проверки лишаешься.
  4. В оставшемся куске — менять всё, что вызывает подозрения. Если это ПО — попробовать переустановить или заменить на аналогичное. В принципе есть вариант начать с этого пункта. Лично видел инженера, при ремонте платы на 40-50 микросхем К155 серии, выкусившего их все и впаявшего новые. Но это на мой взгляд скорее пример того, как не надо делать. Потому-что даже если все заработает, конкретики не получишь. Тем более, что в описанном случае этот вариант не прошел и неисправность сохранилась. В общем — я этого не говорил.

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

Извиняюсь за вероятную сложность чтения.
Тема не очень художественная, плюс к этому попытался сократить, пропуская не очень существенные моменты, вроде вынужденного отказа от BreakPoint'ов, из-за цикличности выполнения программы в ПЛК и наличия таймера.

Автор: PM1630

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js