Контрольная сумма CRC16: HCS08 против Кермит против Xmodem

StackOverflow https://stackoverflow.com/questions/4455257

Вопрос

Я пытаюсь добавить обнаружение ошибок CRC16 к приложению микроконтроллера Motorola HCS08. Мои контрольные суммы не совпадают. Один онлайн CRC Calculator Предоставляет как результат, который я вижу в своей программе для ПК, так и результат, который я вижу на микро.

Он называет результат Micro "xmodem" и результат ПК "Kermit".

Какова разница между тем, как эти два древних протокола определяют использование CRC16?

Это было полезно?

Решение

Вы можете реализовать 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, обрабатывая битовые байт, обратившившись на конечный результат, а затем заменив два байта в результате.

Я полагаю, но не проверял и не разработал детали, что обращение каждого байта эквивалентно изменению полинома (плюс дополнительные детали). Вот почему вы увидите совершенно разные объяснения в разных местах для того, что в основном является одним и тем же алгоритмом.

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

редактировать То, что я назвал CCITT выше, задокументировано в Каталог Ревенга как 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.

Процесс для байтового CRC-16 с использованием входных данных {0x01, 0x02} и полинома 0x1021

  1. Init crc = 0
  2. Ручка первого ввода byte 0x01: 2.1 'xor-in' первое входное byte 0x01 в MSB (!) CRC: 0000 0000 0000 0000 (CRC) 0000 0001 0000 0000 (вход BYTE 0x01 сменен на 8)


    0000 0001 0000 0000 = 0x0100 MSB этого результата - наш текущий Divident: MSB (0x100) = 0x01. 2.2 SO 0x01 - дивидент. Получите остаток для Divident из нашей таблицы: Crctable16 [0x01] = 0x1021. (Ну, это значение является Famila из ручного вычисления выше.) Помните, что текущее значение CRC составляет 0x0000. Сдвиньте MSB текущего CRC и XOR IT с текущим оставшимся, чтобы получить новый CRC: 0001 0000 0010 0001 (0x1021) 0000 0000 0000 0000 (CRC 0x0000 Левой сдвиг на 8 = 0x0000)


    0001 0000 0010 0001 = 0x1021 = промежуточный CRC.

  3. Ручка Следующего ввода Byte 0x02: В настоящее время у нас есть промежуточный CRC = 0x1021 = 0001 0000 0010 0001. 3,1 'xor-in' входной байт 0x02 в MSB (!) CRC: 0001 0000 0010 0001 (CRC 0x1021) 00000 0000 0000 (вход Byte 0x02 левша на 8)


    0001 0010 0010 0001 = 0x1221 MSB этого результата - наш текущий Divident: MSB (0x1221) = 0x12. 3.2 Итак, 0x12 - дивидент. Получите остаток для Divident из нашей таблицы: Crctable16 [0x12] = 0x3273. Помните, что текущее значение CRC составляет 0x1021. Сдвиньте MSB текущего CRC и XOR IT с текущим оставшимся, чтобы получить новый CRC: 0011 0010 0111 0011 (0x3273) 0010 0001 0000 0000 (CRC 0x1021 Левой сдвиг на 8 = 0x2100)


    0001 0011 0111 0011 = 0x1373 = окончательный CRC.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top