Кодирование на физическом уровне Ethernet PHY

Электроника как Хобби, 9 мар 2020 Владимир Кисиль

Так уж получилось, что мы не можем просто передать двоичный сигнал по витой паре… хотя передать-то мы можем, а вот получить на другом конце нет. Банально потому что невозможно отличить несколько логических единиц или нулей подряд от отсутствия сигнала. Поэтому на физическом уровне двоичный сигнал кодируется, а затем модулируется.

Чтобы проверить это утверждение подключимся осциллографом к нашему роутеру и настроим соединение.

При соединении двух устройств по ethernt соединение начинает работать со скоростью самого медленного устройства. А так как мы условились рассматривать только 10Base-T, то для начала эксперимента нужно настроить скорость интерфейсов. В *nix системах это делается одной командой в консоли

# ethtool -s enp0s25 speed 10 autoneg off

Далее нам нужно как-то увидеть передаваемый сигнал на осциллографе. Для этого я снял изоляцию с витой пары, нашел в ней оранжевый и бело-оранжевый провод, и снял изоляцию с них. Провода оказались многожильными. Чтобы в таком виде витая пара прослужила дольше, провода были залужены.

подключение осциллографа

В Ethernet используется дифференциальные сигналы. Это означает, что земли в витой паре как таковой нет. Сигнал передается по паре проводов. По одному проводу идет некий сигнал, а во второму — обратный к нему, инвертированный сигнал. Помимо прочего, такой способ передачи информации обеспечивает повышенную устойчивость к помехам.

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

активный высоковольтный дифференциальный пробник HDP50

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

Фазовая манипуляция

Внимание на осциллограмму, это реальный сигнал 10Base-T, но без нагрузки и помех соответственно, поэтому форму сигнала можно считать почти идеальной.

Измеренный дифференциальный случайный сигнал 10Base-T без нагрузки

Измеренный дифференциальный случайный сигнал 10Base-T без нагрузки

Видите эти «полочки» ? Это изменение фазы сигнала, или фазовая манипуляция.

Кодирование на физическом уровне Ethernet PHY, изображение №4

По «научному» она называется BPSK или двоичная фазовая манипуляция с частотой несущей 10МГц или периодом 100 наносекунд.

пример манипуляции BPSK

BPSK это одна из самых простых PSK фазовых манипуляций, где модуляция осуществляется смещением несущего сигнала на π, а значит имеет всего два возможных перехода π и 2π, и передает всего один бит на символ : 0 или 1.

Кодирование на физическом уровне Ethernet PHY, изображение №6

Поколдуем в графическом редакторе, теперь наша осциллограмма приобретает читаемый вид, и может быть преобразована к двоичному коду. Но это еще не всё, такой двоичный сигнал нужно еще декодировать, чтобы извлечь исходную информацию.

Кодирование на физическом уровне Ethernet PHY, изображение №7

Манчестерское кодирование

Для кодирования информации в Ethernet используется алгоритм разработанный в университете Манчестера и впервые использованный на практике в 1949 для кодирования информации для вычислительной машины Манчестерский Марк I. То есть он реально старый и все еще востребованный из-за своей простоты и эффективности

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

Кодирование на физическом уровне Ethernet PHY, изображение №9

Существует несколько вариантов кода манчестера:

Вариант № 1 (по Томасу): логический ноль кодируется перепадом напряжения с низкого уровня на верхний уровень, а логическая единица кодируется перепадом напряжения с верхнего уровня на нижний.

Вариант № 2 (стандарт IEEE 802.4, стандарт IEEE 802.3): логический ноль кодируется перепадом напряжения с верхнего уровня на нижний, а логическая единица кодируется перепадом напряжения с низкого уровня на верхний уровень. Непосредственно используется в Ethernet.

Вариант № 3 (дифференциальное манчестерское кодирование, разностное манчестерское кодирование, IEEE 802.5): логический ноль кодируется изменением состояния в начале значащего интервала, а логическая единица кодируется сохранением предыдущего уровня.

Кодирование на физическом уровне Ethernet PHY, изображение №10

Обратите внимание, что единички и нолики передаются с фиксированной скоростью.

Поскольку искать единички и нолики на осциллограмме довольно утомительно, я поискал и нашел скрипт для выгрузок с осциллографов Rigol, делающий за нас эту рутинную работу. Вам потребуется установить среду интерпретатора python для их запуска.

Благодаря скрипту мы можем увидеть весь Ethernet-фрейм в бинарном виде:

# Преамбула занимает 8 байт. Помимо прочего, она может быть
# использована  для калибровки часов на принимающей  стороне.
10101010
10101010
10101010
10101010
10101010
10101010
10101010
10101011  
# MAC-адрес получателя: E4:95:6E:43:42:7F
# Важно! Используется порядок  бит lsb-first.
00100111
10101001
01110110
11000010
01000010
11111110 
#  MAC-адрес отправителя:  0E:18:77:10:72:DC
00000111
00011000
11101110
00001000
01001110
00111011 
# Тип  пакета: 08 00, означает IPv4
# https://en.wikipedia.org/wiki/EtherType#Examples
00010000
00000000 
# Полезная нагрузка: от 46 до 1500 байт,
# в данном случае - 84  байта.
10100010
00000000
00000000
00101010
# ... и так далее, см payload.dat 
# Контрольная сумма фрейма:
00010001 # 0x88
10100110 # 0x65
00101001 # 0x94
00000111 # 0xE0

Контрольная сумма является самым обыкновенным CRC32 и вычисляется от всего фрейма за исключением преамбулы и, понятно, самой контрольной суммы. Скрипт сохраняет соответствующие данные в отдельном бинарном файле, благодаря чему контрольную сумму очень легко проверить:

$ crc32 frame.date
0946588

Как видите, контрольная сумма сходится, только порядок байт в Ethernet используется обратный.

Также скрипт сохраняет в отдельном файле полезную нагрузку фрейма. Его при желании можно открыть в Wireshark. Для этого полезную нагрузку нужно перевести из бинарного формата в текстовый:

$ od -Ax -tx1 -v payload.dat > payload.hex

а затем воспользоваться диалогом File → Import from Hex Dump. В выпадающем списке Encapsulation type выбираем Raw IPv4.

Кодирование на физическом уровне Ethernet PHY, изображение №11

У нас получилась чертовски насыщенная информацией статья, которую мы в скором времени проверим на практике. Надеюсь она вас не утомила :)

FrBrGeorge/EthernetPHY (last edited 2024-02-17 21:09:53 by FrBrGeorge)