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

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

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

 

 

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

 

STM LAN. ENC28J60. ARP

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

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

*