Понедельник, 14 ноября 2011 04:44

Подключение ENC28J60 + PIC к локальной сети Часть II. Featured

Written by
Rate this item
(0 votes)

В этой части рассмотрим отправку пакетов от ENC28J60 и реализацию  протоколов ARP, IP и ICMP(Ping). Надеюсь , что те , кто пока слабо  разбирается в сетевых  протоколах к концу чтения статьи поймут  для чего они нужны . К примеру, вот так  выглядит тестовый сигнал Ping и ответ от нашей конструкции в командной строке, время ответа менее 1мс.

 

 

 

 

Содержание этой части статьи:

  • Отправка пакетов.
  • Протокол ARP.
  • Протокол IP.
  • Протокол ICMP (Ping).
  • Заключение

1.Отправка пакетов.

Ранее мы рассмотрели различные ПП работы с enc28j60 и остановились на приеме пакетов , т.е. мы приняли пакет и записали его в ОЗУ микроконтроллера  начиная с адреса 0х0100 (часть служебных данных заголовка) и сам пакет начиная с адреса 0х0200. (в дальнейшем могут быть изменения в коде и адрес может быть другой, на данный момент версия проекта 1.3) . В данных заголовка ( для отправки пакета) нам понадобятся только два байта длины пакета.  Для того что бы отправить пакет необходимо сделать следующие:

  1. Проверить готовность передатчика бит TXRTS регистра ECON1.
  2. Если готовности передатчика нет, то  проверить бит ERIF регистра EIR и если он установлен произвести сброс (REZET) передатчика установкой и последующим сбросом по маске бита TXRST регистра ECON1.
  3. Записать в указатели начало и конец  пакета для передачи , регистры ETXST(L,H) и  ETXHD (L,H).
  4. Записать в регистр EWRPT(L,H) начало области буфера enc28j60 , в которую будем записывать пакет.
  5. Определить управляющий байт (для отправки по умалчиванию "0").
  6. Разрешить отправку пакета установкой бита TXRTS регистра ECON1.

Первым записываем управляющий байт , затем сам пакет и в конце будет автоматически  сформировано несколько байт  статуса передачи .(Более подробно в даташите раздел 7.2). В памяти enc28j60 у нас  будет постоянно формироваться только один пакет (можно и по другому), по этому  на данном этапе регистры ETXST и EWRPT соответственно имеют одинаковое значение, но в дальнейшем можно предварительно  прописывать часто повторяющиеся пакеты и по необходимости отправлять их прямо с буфера передатчика.

Рассмотрим ПП отправки пакета реализованной на ассемблере.

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

 

 

 

В регистр EWRPT записываем значение начало буфера передачи 0х2000 (мы всегда будем передавать один пакет). Запись в буфер передатчика  от микроконтроллера будет производиться именно с этого адреса и после передачи байта он автоматически (так у нас установлено в начале) инкрементируется (увеличивается на +1). А вот в регистрах ETXST и  ETXND записываем именно начало и конец передаваемого пакета. Начало у нас 0х2000 , а вот конец пакета высчитывается . В протоколах где необходим ответ в котором  длина пакета не меняется , данные берутся из принятого пакета (в нем есть 2 байта длины пакета) .Далее переходим к передаче в буфер enc28j60 необходимых данных.

 

 


Данные для передачи формируются ПП обработки каждого протокола в отдельности.Мы получает от ПП длину пакета (Reg_1,Reg_2) и данные , которые необходимо нам передать , они находятся в ОЗУ микроконтроллера начиная с адреса 0Х0200 . В начале передается управляющий байт (у нас 0Х00 по умалчиванию). После передачи данных разрешаем отправку пакета. В конце ПП отправки пакетов написан кусок кода для очистке ОЗУ микроконтроллера (по большому нужен для тестирования или в процессе отладки, но лучше его оставить)

 

 

 

Закончив с ПП можно перейти к необходимым нам протоколам.

Наш стек будет выглядеть следующим образом:

Как видно из схемы приняв пакет необходимо определить это IP (08 00)или ARP (08 06)? Если ARP  то переходим в ПП обработки ARP  протокола, иначе в обработку IP пакета и уже там разбираем на ICMP,UDP ...

 

 

 

 

2.Протокол ARP.


 

Вот мы и подошли к реализации на ассемблере протоколов. Начнем с протокола ARP. Для чего этот протокол  нужен ?   Он нужен для определения адреса канального уровня  по известному адресу сетевого уровня , так по крайней мере написано в "официальных документах". А по простому  каждое устройство в  интернет сетях имеет свой уникальный (физический) адрес , который покупается производителем оборудования и называется MAC адрес, его длина шесть байт . Для того что бы это устройство могло принимать IP пакеты необходимо "закрепить " за ним 4-х байтовый IP адрес , который  присваивает менеджер сети (админ). Для того что бы отправить по сети IP пакет на определенный IP адрес отправитель (ПК к примеру) просматривает у себя в кеше  так называемую ARP таблицу и если такого адреса нет отправляет широковещательный пакет (всем в сети). Устройство , с таким IP  адресом отвечает на прямую отправителю о нахождении в сети и сообщает свой MAC адрес. ПК записывает себе в ARP таблицу и периодически опрашивая о нахождение в сети. После этого отправляет IP пакет непосредственно получателю. Для просмотра ARP таблицы у себя на ПК  в командной строке напишите  ARP -a  (пуск -> выполнить -> ARP -a ) ( должно быть подключение по сети).  Вот  так к примеру эта таблица выглядит у меня на ПК.  Адрес устройства 192.168.1.61

 

 

 

В связи с тем , что инициатором обращение к нашей конструкции будет внешнее устройство  , мы реализуем только ARP сервер. Т.е. мы не будем создавать у себя таблицы, пусть тот кто обращается к нашему устройство тот и помнит.... Этим самым мы с экономим ресурсы под другие задачи. Но если будет необходимость самому проявлять инициативу (например передавать данные с определенным интервалом времени на какой то адрес ), то придется доработать протокол.

Вот так выглядит широковещательный ARP запрос.

 

 

А вот  ответ от нашего устройства. (присвоен IP адрес 192.168.1.61)

 

 

40 61 86 4e 33 09  - MAC адрес получателя .

00 d0 5c 09  6f 1f  - MAC адрес  отправителя (нашего оборудования ).

08 06 - протокол ARP.

00 01 - номер

08 00 - Код протокола. IPv4

06- длина физического адреса (MAC адрес )

04- длина логического адреса (IP адреса)

00 02 - ответ (запрос 00 01)

00 d0 5c 09  6f 1f  - MAC адрес  отправителя (нашего оборудования ).

c0 a8 01 3d - IP отправителя (наш 192.168.1.61).

40 61 86 4e 33 09  - MAC адрес получателя .

c0 a8 01 3d - IP получателя (наш 192.168.1.1).

00 .... 00 - добивка до 64 байт (настраивали при инициализации enc28j60)

Часть данных , как видно из рисунков, мы трогать не будем.  Записываем   MAC и IP адрес отправителя  в  регистры и собираем ответный ARP пакет, в котором сообщаем свои IP и MAC адреса, меняем на ответ (00 02) .Записываем в регистры Reg_1 и  Reg_2  длину пакета , (в ARP она постоянна) и передаем в буфер enc28j60. Добивку нулями делает сам контроллер enc28j60.

 

 

 

Передав пакет программа переходит к обработке нового, принятого пакета.

Переходим к IP протоколу.

Протокол IP :

 

Протокол IP является самым главным во всей иерархии протоколов семейства TCP/IP. Именно он используется для управления рассылкой TCP/IP пакетов по сети. Если опять перевести на простой язык, то IP  является транспортом для UDP,ICMP.., которые  будем рассматривать далее. Мы не будем много уделять внимания описанию IP протокола , т.к. в интернете очень много информации на данную тему, а остановимся только на том , что на понадобится в дальнейшем и рассмотрим IP совместно с другими протоколами.

Протокол ICMP.(Ping)

Ниже, на рисунке показаны запрос и ответ протокола ICMP.

 

 

Все то , что закрашено является IP заголовком. Мы не будем разбирать здесь весь пакет, он разобран к примеру здесь , можно  сравнить  пакеты (запрос, ответ)  и вы увидите отличие. Что не закрашено относится к протоколу ICMP , все вместе IP  пакетом.

В основном ICMP используется для передачи сообщений об ошибках и других исключительных ситуациях, возникших при передаче данных, например, запрашиваемая услуга недоступна, или хост, или маршрутизатор не отвечают. В нашем случае мы будем использовать только "Ping" (проверки возможности доставки IP-пакетов). С помощью "Пинга" очень удобно поверить качество линии связи и работу самого устройства. По сравнению с тем же ARP протоколом для формирования ответа протокола ICMP все на много сложней. Сложней тем , что здесь в ответе (как и запросе) есть контрольная сумма как в IP заголовке , так и в самом протоколе. По этому нам необходимо после формирования произвести расчеты контрольных сумм. Рассчитывать мы будем только сумму IP заголовка, а сумму ICMP  пакета будем высчитывать исходя из изменений в байтах, т.е. сам ICMP ответ практически одинаков , нужно поменять запрос на ответ (8 на 0). Т.е. просто изменим принятую контрольную сумму с учетом сделанных изменений в ICMP пакете, тем самым упростим процесс обработки .

Расчет контрольной суммы IP Заголовка.

Здесь сумма рассчитывается начиная с байта версии и длины заголовка (45) , считается соответственно всего 20 байт. Контрольная сумма заголовка представляет собой 16-битовое поразрядное дополнение (one's complement) суммы поразрядных дополнений всех 16-битовых слов заголовка. При вычислении контрольной суммы значение самого поля принимается нулевым. Т.е. в программе для подсчета суммы, первоначально сбрасываем принятые значение контрольной суммы.

 

 

 

Обработка ICMP пакета.

После обработки IP заголовка и подсчета контрольной суммы копируем значения суммы в IP заголовок отправляемого пакета. К контрольной сумме ICMP пакета прибавляем 0х08 (меняем запрос на ответ). Здесь длина пакета для отправки высчитывается по данным, полученным в заголовке принятого пакета, (принятый заголовок с данными  о длине находится в ОЗУ по адресу 0х0103, 0х104) с вычитанием 4 байт контрольной суммы . которые добавляет к пакету отправитель. После этого передаем пакет в буфер передатчика enc28j60.

 

 

 

Здесь можно наглядно посмотреть работу нашего устройства. Послав 4 пакета с ПК , получили 4 ответа .(IP  устройства 192.168.1.61).

 

На данном этапе можно написать приложение  и собрать конструкцию "Сторож сети" . К примеру у Вас есть устройство , которое бывает зависает, а доступ к нему затруднен (что к удивлению бывает очень часто, особенно если это устройство находится далеко). Как можно перезагрузить его?  Его можно локально (там где оно находиться) с определенным интервалом времени "пинговать"  и в случае отсутствия ответа  перегружать устройство.

В следующей части разберем UDP протокол и напишем небольшое приложение.

 

Ссылки:

Все вопросы можно задать на форуме.

Проект  v1.3 можно  скачать по ссылке на форуме.

Read 5600 times Last modified on Понедельник, 04 января 2016 08:54

Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru