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-запросы, но и умеет теперь их посылать.

 

 

Предыдущая часть Программирование МК STM32 Следующий урок

 

 

Исходный код

 

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

Документация на микросхему 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

Один комментарий на “STM Урок 71. LAN. ENC28J60. ARP. Часть 4
  1. Александр:

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

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

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

*