Как определить начальную контрольную сумму CRC16, чтобы результирующая контрольная сумма была равна нулю
Работа по шине связи SPI между массивом микроконтроллеров SAMD.
У меня есть входящий пакет, который выглядит примерно так: { 0x00, 0xFF, 0x00, 0xFF }
. Чип приемника выполняет проверку CRC16 для входящего пакета.
Поскольку я ожидаю каждый раз один и тот же пакет, я хочу иметь нулевую контрольную сумму CRC, когда пакет действителен, и не нулевую контрольную сумму, когда есть ошибка передачи.
Я знаю, что могу добавить вычисленный CRC16 в конец пакета при его отправке, и на стороне получателя проверка CRC выдаст 0, но в этом случае невозможно добавить контрольную сумму CRC16 к пакету, поскольку пакет построен несколькими микросхемами отправителя на линии SPI, и каждая микросхема заполняет только свои два байта из всего пакета.
Мне нужно загрузить начальную контрольную сумму CRC на стороне получателя, поэтому после проверки входящего пакета результирующий CRC будет равен нулю (если пакет не поврежден).
Ответ здесь на SO - это на самом деле то, что я ищу, но он предназначен для формата CRC32, и я на самом деле не понимаю принципа кода, поэтому я не могу переписать его для формата CRC16.
Любая помощь будет принята с благодарностью!
С уважением, Нико
2 ответа
Я нашел решение благодаря совету Бастьяна Молкентина, который сделал этот замечательный онлайн-калькулятор CRC.
Он посоветовал попробовать вычисление методом перебора всех 2^16 значений начального значения CRC16. Действительно, после нескольких строк кода и нескольких микросекунд спустя SAMD51 обнаружил начальное значение, которое соответствует нулевому значению CRC для данного буфера.
Решение состоит в том, чтобы просто использовать CRC на основе справочной таблицы. Если вы не можете добавить контрольную сумму (также известную как последовательность проверки кадра, FCS) в пакет, сначала выполните поиск в таблице, а затем просто сравните ее с ожидаемой последовательностью для ваших фиксированных данных.
Обратите внимание, что "CRC 16" может означать что угодно, существует несколько версий и (не) стандартов. Наиболее распространенным является, пожалуй, тот, который называется "CRC-16-CCITT" с 1021h poly и начальным значением FFFFh, но даже для этого существует несколько алгоритмов - некоторые правильные, некоторые неработающие. Самая большая проблема - найти надежный алгоритм CRC.
Однако я на самом деле думаю, что SAMD специально использует аппаратно сгенерированный CRC-16-CCITT на кристалле для целей DMA. Поскольку это SPI, он должен поддерживать DMA, поэтому, возможно, выясните, можете ли вы как-то его использовать.