PDA

Просмотр полной версии : МКОН. Ошибка в прошивке конвертора. Возникает если в CRC16 нулевой старший байт.



Eznamos
24.09.2024, 11:29
Устройство: МКОН-24 H/W 2.0
Версия ПО: g2.43
Сер.номер: 116100240232065411
Дата пр-во: 02.2024

Собран стенд:
ПК1 <--- ethernet ---> МКОН <--- rs485 ---> ПК2, где
ПК1 - Master
ПК2 - Slave (ID=17)

ПК1 спрашивает у ПК2 один InputStatus (FC=02), по адресу (0).

Из журналов обмена:

Запрос ТСР от ПК1 к МКОН: 00 00 00 00 00 06 17 02 00 00 00 01
Запрос RTU от МКОН к ПК2: 17 02 00 00 00 01 BB 3C
Ответ RTU от ПК2 к МКОН: 17 02 01 01 64 00
Ответ TCP от МКОН к ПК1: 00 00 00 00 00 03 17 02 01

Рассмотрим подробнее Ответ TCP от МКОН к ПК1:
00 00 00 00 00 03 - это номер транзакции, код протокола, длина пакета
17 наш идентификатор
02 код фунции
01 длина данных
и всё

Обратим внимание что в ответе от МКОН нет байта с данными (т.е. пакет после преобразования приходит без данных).
После серии экспериментов установил, что в некоторых случаях ответ приходит на один байт короче, чем должен.
Естественно, мастер такой пакет считает некорректным, и обмен заканчивается ошибкой.
Из-за этого мастер может зависнут, зациклится ну или просто будет "иногда говорить", что связь, то есть, то нет.

Почему же так происходит, спросит внимательный читатель?

Проведя серию экспериментов выяснил, что эта ситуация возникает, если в ответе у (CRC16) старший байт равен 0.
Для нашего примера (см. Ответ от ПК2 к МКОН) 17 02 01 01, CRC16 = 0x0064 (в порт пишется старшим байтом вперед)

При этом "Сниффер" овен конфигуратора пишет:

1 19:32:50.595 Ethernet: master RS-485: Slave Modbus TCP (PDU) -> Modbus RTU 32 Запрос 17 02 00 00 00 01 BB 3C Slave ID: 0x17 (23) Код функции: 0x02 (2) - Read Discrete Inputs Адрес регистра: 0x0000 (0) Количество регистров: 0x01 (1) Контрольная сумма: 0xBB3C (47932)
2 19:32:50.886 RS-485: Slave Ethernet: master Modbus RTU -> Modbus TCP (PDU) 27 Ответ Ошибка Modbus. Код: 1 - Устройство не может обработать код функции. 17 02 01 Slave ID: 0x17 (23) Код функции: 0x02 (2) - Read Discrete Inputs Код ошибки: 0x01 (1)


Данная ошибка воспроизводится всегда, когда в конце ответа в RS линии стоит "0", отдельно хочу заметить, что я не исследовал, что произойдет, если "0" будет стоять в конце запроса в RS линии предполагаю, что тоже ничего хорошего).

О данной проблеме я сообщил в службу тех. поддержки 14.06.2024 (так же подробно, даже более). До сих пор нет решения, и даже подтверждения, что работа над устранением ведется.

Далее все тоже самое в картинках:
Запрос ТСР от ПК1 к МКОН: 00 00 00 00 00 06 17 02 00 00 00 01
78829
Запрос RTU от МКОН к ПК2: 17 02 00 00 00 01 BB 3C
Ответ RTU от ПК2 к МКОН: 17 02 01 01 64 00
78830
Сниффер
78832
Ответ TCP от МКОН к ПК1: 00 00 00 00 00 03 17 02 01
78833

melky
24.09.2024, 12:24
все очень странно, учитывая, что в Modbus протоколе всегда известна длина пакета.

EFrol
24.09.2024, 12:32
Она становится известной не сразу. Надо какую-то часть сначала принять и обработать, чтобы понять сколько и чего будет в пакете ещё.
А ведь конец пакета определяется по таймауту в 3.5 байта (по стандарту). Передатчик (промежуточное устройство) чуть замешкался и вот приемник ловить уже два пакета.
И если первый пакет короткий (без длины данных), то замучаешься осколки собирать.

Eznamos
24.09.2024, 13:19
Дело не в таймаутах или скорости обмена и т.п. Это происходит только при нулевом байте в CRC.
Я даже могу предположить, а при наличии исходников прошивки, на любом языке, указать точное место, где ошибся программист прошивки.
Всё дело в работе со строками в языках программирования. Библиотечные функции по работе со строками считают "\0" концом строки.
Скорее всего, что "ошибка" происходит в одной из библиотечных функций (по сути это и не ошибка) просто особенность её работы, о которой не подумал программист.
Сам такой. Написал реализацию нескольких протоколов для разных устройств и по "таким" граблям тоже ходил.
Расстраивает, что ТП не реагирует, когда так подробно им пишешь, тратя свое время ((.

melky
24.09.2024, 13:28
EFrol она известна на этапе запроса, так как мы запрашиваем Х регистров, а не "дай нам что-нибудь"

capzap
24.09.2024, 13:49
Дело не в таймаутах или скорости обмена и т.п. Это происходит только при нулевом байте в CRC.
Я даже могу предположить, а при наличии исходников прошивки, на любом языке, указать точное место, где ошибся программист прошивки.
Всё дело в работе со строками в языках программирования. Библиотечные функции по работе со строками считают "\0" концом строки.
Скорее всего, что "ошибка" происходит в одной из библиотечных функций (по сути это и не ошибка) просто особенность её работы, о которой не подумал программист.
Сам такой. Написал реализацию нескольких протоколов для разных устройств и по "таким" граблям тоже ходил.
Расстраивает, что ТП не реагирует, когда так подробно им пишешь, тратя свое время ((.
а с чего Вы решили что работа со строками должна быть, по сути там просто к пришедшему набору байт добавляется в начало служебная информация из шести байт и отбрасывается контрольная сумма, зачем там строки?
Формат ответа ТСР правильный, хоть и не верный и не ожидаемый, скорее всего он напоминает ответ ошибки, если вместо 02 будет стоять 82. То что там последние нули не обрабатываются, так это на стадии расчета контрольной суммы для проверки выяснилось бы, тут просто надо знать как выглядит ответ с ошибкой CRC, это могут сделать обладатели МКОН-а. Ну и второй момент это есть ли проверка CRC или шлюз сразу отправляет транзитом данные, тогда в этой функции не верно рассчитывается объем данных всего пакета, возможно из-за наличия нуля в последнем байте

Pavel5698
24.09.2024, 13:55
Расстраивает, что ТП не реагирует, когда так подробно им пишешь, тратя свое время ((.

А вы написали им на почту? Для Овена форум, как я понял, - последний канал связи куда они смотрят. Можете написать и просто дать ссылку на свой пост

Eznamos
24.09.2024, 14:12
А вы написали им на почту? Для Овена форум, как я понял, - последний канал связи куда они смотрят. Можете написать и просто дать ссылку на свой пост

Конечно написал:

О данной проблеме я сообщил в службу тех. поддержки 14.06.2024

Eznamos
24.09.2024, 14:43
capzap, Вы немного не разобрались. В причине. TCP сторону можете пока не рассматривать там уже никаких CRC нет, ошибка возникает до отправки ответа МКОНом в TCP об этом говорит ошибка в сниффере самого МКОН (он тоже не смог разобрать неполный пакет), о чем сообщил в журнал.


CRC считается верно, просто она 0x0064 в данном примере,
далее прошивка "получает" пакет 17 02 01 01 64 00,
по какой-то причине, далее в обработчик передаётся пакет на один байт короче 17 02 01 01 64,
от которого затем откусывается CRC16 (два байта) и остается уже 17 02 01

которые уже обрабатывает сниффер, и к которым уже добавляется TCP обвязка.

Я проводил разные эксперименты, "теряется" всегда этот байт даже если в ответе будет много байт данных, главное условие чтобы CRC16 была меньше или ровна 0x00FF.

capzap
24.09.2024, 14:56
capzap, Вы немного не разобрались. В причине. TCP сторону можете пока не рассматривать там уже никаких CRC нет, ошибка возникает до отправки ответа МКОНом в TCP об этом говорит ошибка в сниффере самого МКОН (он тоже не смог разобрать неполный пакет), о чем сообщил в журнал.


CRC считается верно, просто она 0x0064 в данном примере,
далее прошивка "получает" пакет 17 02 01 01 64 00,
по какой-то причине, далее в обработчик передаётся пакет на один байт короче 17 02 01 01 64,
от которого затем откусывается CRC16 (два байта) и остается уже 17 02 01

которые уже обрабатывает сниффер, и к которым уже добавляется TCP обвязка.

именно про выводы снифера в первой части я и говорил78847в ПК должна прийти ошибка, а приходит функция 02 которая возможно совпадает с ожидаемым ответом и вводит Вас в заблуждение, если есть эксперименты где последний байт не будет равен единице, выложите

Eznamos
24.09.2024, 15:24
capzap Вас вводит в заблуждение короткий ответ, который похож на код ошибки, но это не так. в ПК должна прийти ошибка, если её сформирует slave. Ошибка 01 ILLEGAL FUNCTION должна быть сгенерирована slave. Задача конвертора её просто транслировать. Здесь проблема не в этом. Ошибки с кодами с 01 до 08 формирует slave, шлюз может формировать ошибки к кодом 0А, 0B (так говорит стандарт).


если есть эксперименты где последний байт не будет равен единице, выложите
Да такие пакеты есть и я их видел. Но это было 3 мес. назад, после чего я написал в ТП и оправил им логи и описание того, что происходит... и тишина..

Если Вы мне сформируете пакет (запрос) в ответ на который, должен прийти ответ с CRC16 < 0x0100 и будет содержать, то что Вы хотите увидеть, я не поленюсь и соберу стенд и выложу результат.

capzap
24.09.2024, 16:15
ответ на который, должен прийти ответ с CRC16 < 0x0100 и будет содержать, то что вы хотите увидеть, я не поленюсь и соберу стенд и выложу результат.
как по формированию запроса дискретных входов можно заранее знать какой ответ придет, вот Вам ответ который можно получить запрашивая 16 входов 78854, не знаю что Вам это даст

ЗЫ если речь шла про последний ноль то возможно так должны входы активироваться чтоб был последний ноль и ответ в случае ошибки не соответствовал коду 1 78855

Валенок
24.09.2024, 16:25
Capzap, там норм ответ по rtu
17 02 01 01 64 00 (6 байт)
в tcp это
6 + (rtu - 2) => 10 байт
00 00 00 00 00 04 17 02 01 01 //10 байт
а конвертнулось в
00 00 00 00 00 03 17 02 01 //9 байт

capzap
24.09.2024, 16:27
Capzap, там норм ответ по rtu
17 02 01 01 64 00 (6 байт)
в tcp это
6 + (rtu - 2) => 10 байт
00 00 00 00 00 04 17 02 01 01 //10 байт
а конвертнулось в
00 00 00 00 00 03 17 02 01 //9 байт
ну, всё так, я написал в тему, когда пошла ересь что в мконе для транзита из одного протокола в другой используют строки

Валенок
24.09.2024, 16:38
ну, всё так, я написал в тему, когда пошла ересь что в мконе для транзита из одного протокола в другой используют строки
ТС (имхо) имел в виду что может быть для транзита кто-то внизу заюзал строки/длину пакета определил с помощью strlen/и т.п.