Как определить начальную контрольную сумму CRC16, чтобы результирующая контрольная сумма была равна нулю

Работа по коммуникационной шине SPI между массивом микроконтроллеров SAMD.

У меня есть входящий пакет, который выглядит примерно как { 0x00, 0xFF, 0x00, 0xFF }. Чип приемника выполняет проверку CRC16 для входящего пакета.

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

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

Мне нужно загрузить начальную контрольную сумму CRC на стороне получателя, поэтому после проверки входящего пакета результирующий CRC равен нулю (если пакет не поврежден).

Ответ здесь, на SO на самом деле это то, что я ищу, но это для формата CRC32, и я на самом деле не понимаю принципа кода, поэтому я не могу переписать его для формата CRC16.

Любая помощь будет принята с благодарностью!

С уважением, Нико


person NikoDiYana    schedule 23.04.2020    source источник


Ответы (2)


Решение состоит в том, чтобы просто использовать CRC на основе справочной таблицы. Если вы не можете добавить контрольную сумму (также известную как Frame Check Sequence, FCS) в пакет, сначала выполните поиск в таблице, а затем просто сравните ее с ожидаемой последовательностью для ваших фиксированных данных. .

Обратите внимание, что «CRC 16» может означать что угодно, существует несколько версий и (не) стандартов. Самый распространенный из них, пожалуй, называется «CRC-16-CCITT» с 1021h poly и начальным значением FFFFh, но даже для него существует несколько алгоритмов - некоторые правильные, некоторые неработающие. Ваша самая большая проблема - найти надежный алгоритм CRC.

Однако я действительно думаю, что SAMD специально использует аппаратно сгенерированный CRC-16-CCITT на кристалле для целей прямого доступа к памяти. Поскольку это SPI, он должен поддерживать DMA, поэтому, возможно, выясните, можете ли вы как-то его использовать.

person Lundin    schedule 23.04.2020
comment
Да, вы правы, действительно, версия CRC16 оборудования SAMD, которую я использую, - это CRC-16-CCITT с полиномом 0x1021. Канал DMA, который считывает кадры SPI, используется для его вычисления. Что касается таблицы поиска, то я делаю это прямо сейчас, зная все возможные состояния входящего пакета, у меня есть LUT для сравнения контрольных сумм. Однако я также получаю обычные пакеты с добавленной FCS, поэтому мне нужно предварительно загрузить состояние перед передачей, чтобы знать, какую контрольную сумму ожидать. И я хочу избежать этого, просто сравнивая контрольную сумму с нулем для всех пакетов. - person NikoDiYana; 23.04.2020
comment
@NikoDiYana Я не знаю, как вы собираетесь решить эту проблему. Будут ли пакеты иметь разные размеры с добавлением FCS или без него, или как вы можете отличить их? - person Lundin; 23.04.2020
comment
Мастер-чип SPI отправляет подчиненным запрос номера байта. Вот как он знает, какой пакет ожидать. При следующей транзакции подчиненные ответят. - person NikoDiYana; 23.04.2020
comment
@NikoDiYana Значит, можно ли включать / отключать аппаратную проверку CRC? В зависимости от того, чего вы ожидаете. - person Lundin; 23.04.2020
comment
Да, но мне еще нужно проверить содержимое входящего пакета. Если микросхема на линии не отвечает, ее слот в пакете будет 0x00. Я прекрасно понимаю, что могу сделать это с помощью LUT или цикла, но дело в том, что ведущее устройство тем временем выполняет вычисления, и в прерывании приема данных можно выполнить быструю проверку на ноль, а не прервать основной цикл. - person NikoDiYana; 23.04.2020

Я нашел решение благодаря совету Бастьяна Молкентина, который сделал этот замечательный онлайн Калькулятор CRC.

Он посоветовал попробовать вычисление методом перебора всех 2 ^ 16 значений начального значения CRC16. Действительно, после нескольких строк кода и нескольких микросекунд спустя SAMD51 обнаружил начальное значение, которое соответствует нулевому значению CRC для данного буфера.

person NikoDiYana    schedule 26.04.2020