реклама на сайте
подробности

 
 
> Свойства CRC16(Modbus), почему так?
AlexOr
сообщение Jul 20 2010, 05:07
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Введение
1. Рассчитаем CRC16(Modbus) (см. тут On-line CRC calculation http://www.lammertbies.nl/comm/info/crc-calculation.html) от двух байт 0x01, 0х02. Получаем значение 0xE181.
2. А теперь рассчитаем CRC16(Modbus) от четырех байт 0x01, 0х02, 0x81, 0xE1 (добавили младший и старший от ранее рассчитанного CRC). Получаем значение 0x0000.
ДА именно 0x0000 и байты 0x01, 0х02 можно заменить на любые (при выполнении 1 и 2). Все равно будет 0x0000.
Что это за свойство и неужели все про него знают? Я не знал.
Как называется это свойство и вообще подобные свойства? Есть ли подобные свойства при другом полиноме? А у CRC32?


Итог
История применения CRC16(Modbus)
Был на скорую руку сделан протокол с разделением пакетов по специальному символу. Соответственно был применен байт-стаффинг. В общем, длина пакета определяется по количеству байт до специального символа и далее сразу рассчитывается CRC для проверки пакета. Было выявлено, что при наличии интенсивных помех в канале связи, происходит добавление нулей в принимаемую последовательность и иногда вместо приема 0x01, 0х02, 0x81, 0xE1 получатся прием 0x01, 0х02, 0x81, 0xE1, 0х00 , 0х00.
!!!!!!!!!!!!!!!!!!!!!!!!!!!
А так как мы считаем два последних байта значением CRC, то такой неверный пакет проходит как правильный.
!!!!!!!!!!!!!!!!!!!!!!!!!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 12)
MrYuran
сообщение Jul 20 2010, 05:18
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(AlexOr @ Jul 20 2010, 09:07) *
А теперь рассчитаем CRC16(Modbus) от четырех байт 0x01, 0х02, 0x81, 0xE1 (добавили младший и старший от ранее рассчитанного CRC). Получаем значение 0x0000.
ДА именно 0x0000 и байты 0x01, 0х02 можно заменить на любые. Все равно будет 0x0000.

Вот это место осветите подробнее.
Что-то у вас в консерватории не то.
Если вы измените байты, изменится и ЦРЦ.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jul 20 2010, 05:28
Сообщение #3


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



ТС, Вы неправильно считаете CRC. Советую, взять контрольные примеры и отладить свой алгоритм.
Если будут проблемы, то можно что-то найти из примеров.
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Jul 20 2010, 05:38
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Цитата(MrYuran @ Jul 20 2010, 09:18) *
Вот это место осветите подробнее.

Дабавил пункты 1 и 2.

Цитата(alexander55 @ Jul 20 2010, 09:28) *
ТС, Вы неправильно считаете CRC. Советую, взять контрольные примеры и отладить свой алгоритм.

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

Цитата(MrYuran @ Jul 20 2010, 09:18) *
Если вы измените байты, изменится и ЦРЦ.

0х03, 0х04 CRC(Modbus) равна 0x8300
0х03, 0х04, 0х00, 0х83 CRC(Modbus) равна 0х0000 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jul 20 2010, 05:39
Сообщение #5


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(AlexOr @ Jul 20 2010, 09:32) *

Нашел примеры от Шнайдера (считайте, законодателя модбаса - модикона).
Проверяйте реализацию алгоритма.
01 03 0C00 0002 (C75B)
01 03 04 0000 0000 (FA33)
01 03 02 1234 (B533)
Хватит для тестирования.
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jul 20 2010, 05:51
Сообщение #6


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(AlexOr @ Jul 20 2010, 08:07) *
ДА именно 0x0000 и байты 0x01, 0х02 можно заменить на любые (при выполнении 1 и 2). Все равно будет 0x0000.

Именно так - всегда будет ноль. Это свойство СRC как остатка от полиномиального деления. То есть - вы взяли произвольную битовую последовательность, поделили ее на полином, получили некоторый остаток (пункт 1 в Вашем описании). Потом Вы взяли получившийся остаток добавили к последовательности и снова поделили, результирующий остаток ессно будет ноль.
Если привести аналогию (не совсем корректную) к обычной (не полиномиальной арифметике). То у Вас было число S (исходная последовательность), Вы его поделили на некоторое P (полином), получили остаток D. То есть S = N*P + D. А потом Вы вычли из S остаток D и получили новое число S' = S-D. Ессно S' будет нацело делиться на P и остаток всегда будет 0. И при такой операции совершенно неважно какое у Вас было изначальное S - итоговый остаток всегда 0.
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Jul 20 2010, 05:53
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Цитата(alexander55 @ Jul 20 2010, 09:39) *
Проверяйте реализацию алгоритма.
01 03 0C00 0002 (C75B)

Согласно онлайн калькулятору
0x01, 0x03, 0x0c, 0x00, 0x00, 0x02 имеет CRC(Modbus) 0x5BC7
т.е. все правильно
и не надо разводить не по существу.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jul 20 2010, 06:03
Сообщение #8


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(AlexOr @ Jul 20 2010, 09:53) *
Согласно онлайн калькулятору
0x01, 0x03, 0x0c, 0x00, 0x00, 0x02 имеет CRC(Modbus) 0x5BC7
т.е. все правильно

Ясно, без этой проверки говорить было бы бессмысленно.
Теперь по существу вопроса.
КС находится в конце пакета принятого. А новый пакет пока не пошел. Адрес 00 не рекомендуется использовать (если Вы внимательно почитаете мануалы). Проблем нет.
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Jul 20 2010, 06:12
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Цитата(VslavX @ Jul 20 2010, 09:51) *
Именно так - всегда будет ноль. Это свойство СRC как остатка от полиномиального деления. То есть - вы взяли произвольную битовую последовательность, поделили ее на полином, получили некоторый остаток (пункт 1 в Вашем описании). Потом Вы взяли получившийся остаток добавили к последовательности и снова поделили, результирующий остаток ессно будет ноль.

В пакете протокола Modbus передается сначала старший байт CRC в отличии от моего формирования пакета. Я правильно понимаю, что такое решение Modbus позволяет полностью обойти данную проблему?

Цитата(alexander55 @ Jul 20 2010, 10:03) *
Ясно, без этой проверки говорить было бы бессмысленно.

Ясно что Вам нечего сказать.


Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 20 2010, 06:28
Сообщение #10


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(AlexOr @ Jul 20 2010, 09:38) *
0х03, 0х04 CRC(Modbus) равна 0x8300
0х03, 0х04, 0х00, 0х83 CRC(Modbus) равна 0х0000 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Ну да, так и должно быть.
Ноль означает отсутствие ошибок.
Неноль - ошибка.

Пока так и не понимаю, в чём заключается ваша проблема.
Хотя, кажется, догадываюсь.
Если в пакет включаются нули, они не оказывают влияния на ЦРЦ, а пакет искажают.
В том же модбасе есть поле длины пакета, по которому такие пакеты можно однозначно вычислить.
То есть, проверяется целостность пакета и CRC
Если не совпало - пакет битый.
Вам наверно лучше подойдёт модбас ASCII, он как раз с маркером начала и конца пакета
Кроме того, принимаемые байты должны соответствовать строго определённым ASCII-символам, что даёт дополнительную защиту, от тех же нулей, например


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jul 20 2010, 06:33
Сообщение #11


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(AlexOr @ Jul 20 2010, 10:12) *
Ясно что Вам нечего сказать.

Очень эмоционально.
Навеяло. biggrin.gif
Что же тебе сказать, если ты ничего не говоришь (ц).
ЗЫ.
Обычно проблемы бывают, когда низкий процент прохождения пакетов в условиях повышенной помеховой обстановки. Проблему решают подтверждением прохождения пакетов и повторной отправкой пакета в случае его непрохождения. С достоверностью принятых пакетов проблем никогда не возникало.
Go to the top of the page
 
+Quote Post
Oldring
сообщение Jul 20 2010, 07:08
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(AlexOr @ Jul 20 2010, 09:07) *
Что это за свойство и неужели все про него знают? Я не знал.
Как называется это свойство и вообще подобные свойства? Есть ли подобные свойства при другом полиноме? А у CRC32?


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

И вообще говоря, CRC-16 не очень подходит для линий с высоким уровнем шума. Слишком мало проверочных битов. Велика вероятность пропустить групповую ошибку.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
i-mir
сообщение Sep 1 2011, 14:27
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 197
Регистрация: 17-06-10
Из: Киев
Пользователь №: 57 986



Цитата(AlexOr @ Jul 20 2010, 08:07) *
добавили младший и старший от ранее рассчитанного CRC. Получаем значение 0x0000.


Тема была давно, но суть не меняется.

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

Так вот задумка и была таковой, что остаток CRC добавлялся передатчиком к концу посылки,
и приемник вычисляя CRC на ходу, принимал данные и остаток - получал 0. По этому факту
посылка или принималась или отбраковывалась тут-же. Очень просто и красиво.

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




Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 07:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01476 секунд с 7
ELECTRONIX ©2004-2016