STM Урок 71. LAN. ENC28J60. ARP. Часть 4

 

Урок 71

 

Часть 4

 

LAN. ENC28J60. ARP

 

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

 

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

Вернёмся в файл arp.c и подключим туда наш счётчик секунд

 

extern char str1[60];

extern uint32_t clock_cnt;//счетчик секунд

 

Продолжим дальше функцию arp_table_fill и добавим в запись таблицы количество секунд, которые нам насчитал таймер

 

memcpy(arp_rec[current_arp_index].macaddr,msg->macaddr_src,6);

arp_rec[current_arp_index].sec = clock_cnt;

 

Дальше увеличиваем позицию записи в таблице

 

arp_rec[current_arp_index].sec = clock_cnt;

if(current_arp_index<4) current_arp_index++;

else current_arp_index=0;

 

 

И по окончанию функции давайте эту таблицу посмотрим

 

  else current_arp_index=0;

  //смотрим ARP-таблицу

  for(i=0;i<5;i++)

  {

    sprintf(str1,"%d.%d.%d.%d - %02X:%02X:%02X:%02X:%02X:%02X - %lurn",

      arp_rec[i].ipaddr[0],arp_rec[i].ipaddr[1],arp_rec[i].ipaddr[2],arp_rec[i].ipaddr[3],

      arp_rec[i].macaddr[0],arp_rec[i].macaddr[1],arp_rec[i].macaddr[2],

      arp_rec[i].macaddr[3],arp_rec[i].macaddr[4],arp_rec[i].macaddr[5],

      (unsigned long)arp_rec[i].sec);

    HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  }

}

 

Соберём код, прошьём контроллер и попробуем послать ARP-запросы из терминальной программы на различные адреса, которые мы знаем в своей сети

 

image08

 

Как мы видим, таблица соответствия адресов у нас нормально заполняется, только вот если мы посылаем запрос на существующий IP он у нас добаляется ещё раз. Это непорядок. Поэтому давайте теперь, как мы и хотели, вернёмся в функцию ARP-запроса arp_request и пока вставим туда цикл, который будет перебирать записи по отысканию существующего IP-адреса

 

uint8_t i;

//проверим, может такой адрес уже есть в таблице ARP, а заодно и удалим оттуда просроченные записи

for(i=0;i<5;i++)

{

}

 

 

В тело цикла добавим условие

 

for(i=0;i<5;i++)

{

  //Если записи уже более 12 часов, то удалим её

  if ((clock_cnt-arp_rec[i].sec)>43200)

  {

    memset(arp_rec+(sizeof(arp_record_ptr)*i),0,sizeof(arp_record_ptr));

  }

}

 

Из коментария вполне ясно, что мы здесь проделали. Мы забили нулями всю память отведённую под запись.

Теперь после этого условия добавим следующее, после выполнения тела условия (не цикла)

 

  memset(arp_rec+(sizeof(arp_record_ptr)*i),0,sizeof(arp_record_ptr));

}

if (!memcmp(arp_rec[i].ipaddr,ip_addr,4))

{

  return 0;

}

 

В теле данного условия перед тем, как нам выйти из функции с помощью return 0, мы посмотрим нашу таблицу

 

if (!memcmp(arp_rec[i].ipaddr,ip_addr,4))

{

  //смотрим ARP-таблицу

  for(i=0;i<5;i++)

  {

    sprintf(str1,"%d.%d.%d.%d - %02X:%02X:%02X:%02X:%02X:%02X - %lurn",

    arp_rec[i].ipaddr[0],arp_rec[i].ipaddr[1],arp_rec[i].ipaddr[2],arp_rec[i].ipaddr[3],

    arp_rec[i].macaddr[0],arp_rec[i].macaddr[1],arp_rec[i].macaddr[2],

    arp_rec[i].macaddr[3],arp_rec[i].macaddr[4],arp_rec[i].macaddr[5],

    (unsigned long)arp_rec[i].sec);

    HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  }

  return 0;

}

 

Соберём код, прошьём контроллер и поиграем с запросами

 

image09

 

IP-адреса в таблице у нас больше не дублируются, на существующие адреса запросы не посылаются. 12 часов я ждать не стал, но я пробовал максимальное количество секунд в условии менять на значительно меньшее — устаревшие адреса удалялись. Так что всё работает.

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

 

 

 

 

Исходный код

 

Техническая документация:

Документация на микросхему ENC28J60

Перечень ошибок ENC28J60 (Errata)

 

 

Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6

Программатор недорогой можно купить здесь ST-Link V2

Ethernet LAN Сетевой Модуль можно купить здесь ENC28J60 Ethernet LAN Сетевой Модуль.

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

 

 

Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)

STM LAN. ENC28J60. ARP

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

STM LAN. ENC28J60. ARP

1 комментарий к “STM Урок 71. LAN. ENC28J60. ARP. Часть 4”

  1. Интересно было бы увидеть уроки по работе этой микросхемы (или другой) через MII (или RMII) интерфейс без LWIP.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

*