Контрольная сумма CRC16: HCS08 против Kermit против XMODEM
Я пытаюсь добавить обнаружение ошибок CRC16 в приложение микроконтроллера Motorola HCS08. Однако мои контрольные суммы не совпадают. Одинонлайн калькулятор CRC предоставляет как результат, который я вижу в своей компьютерной программе, так и результат, который я вижу на микро.
Он называет результат микро "XModem", а результат ПК "Kermit"."
В чем разница между тем, как эти два древних протокола определяют использование CRC16?
3 ответов:
Вы можете реализовать 16-битные IBM, CCITT, XModem, Kermit и CCITT 1D0F, используя одну и ту же базовую кодовую базу. см. http://www.acooke.org/cute/16bitCRCAl0.html который использует код из http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
В следующей таблице показано, чем они отличаются друг от друга:name polynomial initial val reverse byte? reverse result? swap result? CCITT 1021 ffff no no no XModem 1021 0000 no no no Kermit 1021 0000 yes yes yes CCITT 1D0F 1021 1d0f no no no IBM 8005 0000 yes yes noГде "обратный байт" означает, что каждый байт является бит-реверсированным до обработки; "обратный результат" означает, что 16-битный результат является бит-реверсированным после обработки.; "результат подкачки" означает, что два байта в результате подкачки меняются местами после обработки.
Все вышесказанное было проверено с помощью тестовых векторов против http://www.lammertbies.nl/comm/info/crc-calculation.html (если это неверно, то мы все погибли...).
Таким образом, в вашем конкретном случае вы можете преобразовать код для XModem в Kermit путем реверсирования каждого байта, битового реверсирования конечного результата, а затем поменять местами два байта в результате.
[я верю, но не проверял и не работал из деталей, что реверсирование каждого байта эквивалентно реверсированию полинома (плюс некоторые дополнительные детали). именно поэтому вы увидите очень разные объяснения в разных местах для того, что в основном является одним и тем же алгоритмом.
Кроме того, приведенный выше подход не эффективен, но хорош для тестирования. если вы хотите эффективно, то лучше всего перевести все вышесказанное в таблицы поиска.]
Edit то, что я назвал CCITT выше, задокументировано в RevEng Каталог as CCITT-FALSE. для получения дополнительной информации смотрите обновление к моему сообщению в блоге по ссылке выше.
Насколько я помню (когда-то я занимался модемными вещами), Кермит обрабатывает биты в каждом байте данных, используя сначала наименее значимый бит.
Большинство программных реализаций CRC (вероятно, Xmodem) сначала проходят через байты данных, наиболее значимые.
При просмотре источника библиотеки (загрузите его из http://www.lammertbies.nl/comm/software/index.html ) используется для страницы вычисления CRC, на которую вы ссылаетесь, вы увидите, что XModem использует CRC16-CCITT, многочлен для которого равен:
x^16 + x^12 + x^5 + 1 /* the '^' character here represents exponentition, not xor */Полином представлен растровым изображением (обратите внимание, что бит 16 подразумевается)
0x1021 == 0001 0000 0010 0001 binaryРеализация Kermit использует:
0x8408 == 1000 0100 0000 1000 binaryКоторый является тем же растровым изображением, что и XModem, только перевернутым.
В текстовом файле, сопровождающем библиотеку, также упоминается следующее отличие Kermit:Только для CRC-Kermit и CRC-SICK: после обработки всех входных данных вычисляется одно дополнение CRC и два байта CRC поменялись местами.
Поэтому, вероятно, будет легко изменить вашу процедуру CRC, чтобы она соответствовала результату ПК. Обратите внимание, что исходный код в библиотеке CRC, похоже, имеет довольно либеральную лицензию - возможно, имеет смысл использовать его более или менее как есть (по крайней мере, те части, которые применяются для вашего приложения).
X-Modem 1K CRC16.
Процесс для bytewise CRC-16 с использованием входных данных {0x01, 0x02} и полинома 0x1021
- Init crc = 0
Обрабатывать первый входной байт 0x01: 2.1 'Xor-in' первый входной байт 0x01 в MSB(!) КПР: 0000 0000 0000 0000 (crc) 0000 0001 0000 0000 (входной байт 0x01 сдвинут влево на 8)
0000 0001 0000 0000 = 0x0100 MSB этого результата является нашим текущим делителем: MSB (0x100) = 0x01. 2.2 Итак, 0x01-это делитель. Узнать остаток по делитель из нашей таблицы: crctable16[0x01] = 0x1021. (Ну, это значение является Фамила из ручного вычисления выше.) Помните, что текущее значение crc равно 0x0000. Переключения на ГРЩ на ток КПР и XOR с текущим остатком, чтобы получить новые КПР: 0001 0000 0010 0001 (0x1021) 0000 0000 0000 0000 (CRC 0x0000 сдвинут влево на 8 = 0x0000)
0001 0000 0010 0001 = 0x1021 = промежуточный crc.
Обрабатывать следующий входной байт 0x02: В настоящее время мы имеем промежуточный crc = 0x1021 = 0001 0000 0010 0001. 3.1 'Xor-in' ввод байта 0x02 в MSB(!) КПР: 0001 0000 0010 0001 (crc 0x1021) 0000 0010 0000 0000 (входной байт 0x02 сдвинут влево на 8)
0001 0010 0010 0001 = 0x1221 MSB этого результата является нашим текущим делителем: MSB(0x1221) = 0x12. 3.2 Итак, 0x12-это делитель. Получите остаток для делителя из нашей таблицы: crctable16[0x12] = 0x3273. Помните, что текущее значение crc равно 0x1021. Переключения на ГРЩ на ток КПР и XOR с текущим остатком, чтобы получить новый КПР: 0011 0010 0111 0011 (0x3273) 0010 0001 0000 0000 (CRC 0x1021 сдвинут влево на 8 = 0x2100)
0001 0011 0111 0011 = 0x1373 = окончательный crc.
Comments