ETHERNET 802.3 передача пакета. (Как рассчитать CRC32).
В одном из проектов на основе программируемой логики (FPGA) понадобилось передавать данные
по Ethernet. При этом необходимо было сделать проект как можно проще:
- Без раскручивания полноценного стека протоколов.
- Без применения внешнего микроконтроллера и т.п.
Для передачи данных был выбран протокол UDP, как наиболее простой в реализации.
Для того чтобы передавать данные необходимо сформировать служебные поля (заголовки) для:
1. 802.3 (Ethernet).
2. IP - протокола.
3. UDP - протокола.
Заголовки IP и UDP были сгенерированы заранее при помощи ПО EthernetUDP взятую с сайта
проекта fpga4fun.
Данное ПО позволяет сформировать ETHERNET пакет (с параметрами заданными пользователем)
и вывести в окне программы в виде массива байт.
Обновление: На дворе 2021 год, EthernetUDP - перестала запускаться выводя ошибку:
run time error 217.
Пересобрал (при помощи Delphi 7) программу предварительно выкинув все лишнее
по работе с COM портом.
В оригинальной программе создаваемый пакет посылался в COM порт.
Новая версия EthernetUDP_2021.zip
Формирование пакета ETHERNET не вызывает вопросов за исключение расчета контрольной суммы,
тут не все так просто как может показаться, поэтому рассмотрим процесс подробнее.
Расчет контрольной суммы 802.3 ETHERNET.
Функция расчета CRC32 представлена в файле crc32.v
На входе функция принимает 8 бит данных - data_in, на выходе crc_out - 32 разрядная контрольная
сумма crc_out.
Алгоритм расчета следующий:
1. Произвести начальную инициализацию crc = 0xFFFFFFFF.
Для этого производится сброс модуля расчета контрольной суммы, путем перевода сигнала rst в 1 и
затем в 0.
(При этом внутряя переменная lfsr_q = FFFFFFFF)
2. Включаем расчет контрольной суммы переведя сигнал crc_en в 1 и подавая входные данные в
переменную data_in.
В конце (после окончания данных) переводим сигнал crc_en в 0.
ВНИМАНИЕ:
Данные в data_in необходимо подавать в развернутом(зеркальном) виде, то есть меняем порядок
следования бит:
ст.7 бит мл. 0 бит
.data_in( {data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]} )
3. Полученное значение CRC32 инвертируем (XOR-рим с значением FFFFFFFF).
4. Передаем полученное значение CRC32 в конце кадра ETHERNET.
ВНИМАНИЕ:
В Ethernet(802.3) принят следующий порядок передачи данных: МЛАДШИЕ вперед
(от младшего к старшему) !
Передача значения CRC32 осуществляется СТАРШИМИ вперед, т.е. значение необходимо
развернуть (зеркально).
Т.е. передача идет в следующем порядке (по номерам индекса):
N бита передаваемых данных | 0, 1, 2, 3, 4, 5.....31 |
N бита crc32 | 31,30,29,28,27,......0 |
Тестовый проект.
Для отработки передачи пакета был создан тестовый проект позволяющий непрерывно
передавать UDP пакет в сеть.
Проект создан на языке Verilog, для отладочной платы DE0-NANO. В качестве ETHERNET трансивера
применен LAN8720 с интерфейсом RMII (плата WaveShare LAN8720 ETH Board).
В файле ram_ip_paket_tx.mif располагается тестовый пакет с описанием всех заголовков и данных.
Данный файл является образом памяти RAM, из которой осуществляется передача пакета в сеть.
Изменяя значения можно настроить передачу под другие параметры сети и т.п.
После компиляции проект занял 184 LE.
Для диагностики принятых пакетов на ПК применялась программа Wireshark.