Введение
Достаточно часто в литературе мне попадались описания ошибок и даже классификации их по типам.
Хотя, признаться, у меня не получается толком вспомнить ни одного случая, когда мне бы помогло знание того, к какому именно типу относится конкретная ошибка. Разве что уже после выяснения причин, для обьяснения их окружающим.
А вот как люди вычисляли место и докапывались до сути ошибки — мне всегда было интересно.
Сведения о системе и ошибке
С компьютера на ПЛК подаются уставки (времена, флаги режимов) и команды на устройство.
Из ПЛК на компьютер выдаются сигналы статуса устройства и времени до конца команды на это устройство. Сигналы пакуются в слова, для минимизации объемов приема и передачи.
Из ПЛК на устройство выдаются команды.
Устройство выдает на ПЛК свои статусы.
Изначально все работало, но через какое-то время при подаче команд, статусы на компьютере в SCADA начали моргать не по делу и вообще вести себя крайне недружелюбно. Причем только в одном месте, на одном объекте.
Но «танцы с саблями» появлялись стабильно, при каждой команде, что очень порадовало.
Поиск
Цифрами в круглых скобках показаны места проверок, соответствующие цифрам на схеме ниже.
Принципов и зависимостей моргания понять сходу не удается. Возможно из-за усталости, возможно по причине отсутствия таковых.
Было установлено, что ошибка присутствует не только в SCADA (1) (там, где она собственно была обнаружена), но и в OPC сервере (2).
Дальнейший разбор показал, что ошибка присутствует и в ПЛК, как минимум в слове, формируемом для компьютера (3).
Проверка наличия ошибки в статусе, приходящем от устройства – отметает устройство, как возможный источник проблемы.
Изменения статуса от устройства вручную ничего не меняют. При изменении статуса от устройства форсированием (принудительно, постоянно) ошибка все равно сохраняется.
Соответственно это и не импульсы, которых не видно при мониторинге (4).
Сравнение с кодами других объектов, на которых этой ошибки нет – различий не выдает. Полная идентичность. Вероятность ошибки в программе ПЛК уменьшается (5).
Отключается компьютер, как возможный источник ошибки, записывающий что-то в данную область памяти. Ошибка сохраняется. Вероятность ошибки из-за компьютера стремится к нулю. Соответственно, не смотря ни на что, проблема все-таки в ПЛК (6).
Ремарка: Также можно было, отключив ПЛК, руками менять статусы в OPC. Но такой вариант был сложнее технически, а в целом эти две проверки практически равнозначны.
Перенесение слова статуса, передаваемого из ПЛК на компьютер, в другую область памяти ПЛК ничего не дает. Ошибка сохраняется.
Перенесение куска кода с ошибкой в другой блок (условно функцию) тоже не влияет на ошибку. Соответственно вероятность того, что это влияет какая-то еще посторонняя команда, пишущая туда-же что-то свое – незначительна. Дело в этом куске.
Постепенно удаляются коды, и остается практически минимум, при котором сохраняется ошибка (7)
- Подача команды (без нее не понятно как проверять).
- Таймер, с которого берется время до сброса команды.
- Формирование слова на компьютере из статуса и времени до сброса команды.
Удаляется таймер. Команда не сбрасывается, но ошибка пропадает и статусы перестают прыгать.
Взамен вставляется новый таймер. Тщательно осматривается на предмет нелепостей. Таймер самый заурядный, ничего необычного. Таких в программе еще штук 200. Но ошибка появляется (8)
Рассматривается формирование сигнала от ПЛК, как самого вероятного кандидата на источник ошибки. Сигнал упакован для компактности в одно слово, биты статуса в старшем байте, время в младшем. Тремя командами:
- Запись статусов устройства в младший байт слова.
- Замена старшего и младшего байт местами командой SWAP_WORD (статусы переносятся в старший байт)
- По AND запись времени в младший байт слова
Вроде ничего необычного, причем полностью идентичная система работает с десятками идентичных устройств вокруг.
Заменяется последовательность команд упаковки в слово на работающую идентично, но состоящую из других операторов (9):
- Запись времени устройства в младший байт слова.
- В промежуточной переменной статусы умножаются на 256, сдвигаясь в старший байт слова.
- По OR производится запись статусов в старший байт слова.
Все заработало.
После разбора — ситуация становится окончательно понятной.
Причина ошибки:
Операторы увеличили стандартное время таймаута с 1,5 до 10 минут.
И если 1,5 минуты это 90 секунд, то 10 минут это 600 секунд.
600 секунд не влезали в младший байт (максимум 256), и часть времени писалась в старший.
Суть последней проверки:
При записи сначала времени, и лишь затем статуса – статус забивал биты переполнения, приходившие от значения времени. А при обратной последовательности команд, время наоборот забивало своими битами статус.
Решение:
Время и статусы были разбиты на 2 слова. Местным инженерам было предложено провести техобслуживание или заменить устройство с таймаутом, превышающим стандартное время более чем в 5 раз.
И они работали они долго и счастливо, и сломались в один день.
Выводы
Описанная ошибка не особо сложна, но по-моему довольно симпатична с точки зрения показательности.
По сути не очень важно, где именно ищется ошибка — в электронике, в ПЛК, на компьютере или где-то еще. Общие принципы всегда примерно одинаковы:
- По максимуму собрать информацию о проблеме — где и как она проявляется. Осциллографы, снифферы, утилиты от Русиновича, логи, градусники, в общем всё, что можно использовать в данном случае. Не зависит ли она от времени года, прихода уборщицы, или барометрического давления.
- Вывести из-под подозрения как можно большую часть. Перерезая дорожки на печатных платах, отключая теги, выводя из системы отдельные компьютеры. Хуже, если есть какие-нибудь обратные связи и прочие хендшейки. Тогда можно попытаться либо организовать проверку приняв во внимание отсутствие части системы, либо пробовать проэмулировать часть, например искусственно подавая сигнал на вход обратной связи. В общем думать.
- По возможности доводить каждую проверку до конца, даже если вдруг появилась «мысль!». Потому-что «мысль!» может и не сработать (и до обидного часто не срабатывает), а результатов проверки лишаешься.
- В оставшемся куске — менять всё, что вызывает подозрения. Если это ПО — попробовать переустановить или заменить на аналогичное. В принципе есть вариант начать с этого пункта. Лично видел инженера, при ремонте платы на 40-50 микросхем К155 серии, выкусившего их все и впаявшего новые. Но это на мой взгляд скорее пример того, как не надо делать. Потому-что даже если все заработает, конкретики не получишь. Тем более, что в описанном случае этот вариант не прошел и неисправность сохранилась. В общем — я этого не говорил.
Хотя разумеется рецепты для одних ситуаций могут быть совершенно бесполезны по отношению другим.
Но у всех ошибок есть конкретная причина, и эту причину всегда можно выяснить.
Например как-то причиной был тракторист с бороной, проехавшийся над кабелем. И хотя сложностей в ее устранении не возникло, их хватило в процессе написания рекомендации, для избежания повторов…
Извиняюсь за вероятную сложность чтения.
Тема не очень художественная, плюс к этому попытался сократить, пропуская не очень существенные моменты, вроде вынужденного отказа от BreakPoint'ов, из-за цикличности выполнения программы в ПЛК и наличия таймера.
Автор: PM1630