STM Урок 126. LAN8742A. LWIP. NETCONN. TCP. Соединяем два контролера



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

Начнём с сервера.

Проект для сервера создадим на основе проекта урока 124 LAN8742_TCP_SERVER_NETCONN и дадим ему имя немного другое — LAN8742_TCP_SERVER, чтобы наши проекты из разных занятий хоть как-то различались по именам.

Откроем наш проект в Cube MX и, ничего абсолютно в нём не трогая, сгенерируем проект для System Workbench и откроем его там. Установим уровень оптимизации в 1, уберём при наличии отладочные настройки и закомментируем неизвестные компилятору строки в файле main.c.

Попробуем собрать проект и начнём работать с файлом main.c.

Передавать мы будем уже не строку, а 32-битную величину, поэтому в связи с этим немного придётся переделать код.

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

 

struct_sock *arg_sock;

uint32_t syscnt = 0;

 

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

 

if (recv_err == ERR_OK)

{

  netbuf_data(inbuf, (void**)&buf, &buflen);

}

 

Остальной код мы сейчас допишем.

Сначала освободим память буфера, иначе он в один прекрасный момент перестанет принимать данные

 

netbuf_data(inbuf, (void**)&buf, &buflen);

netbuf_delete(inbuf);

 

Если длина буфера больше 1, то заберём 32-битную величину из локального буфера

 

netbuf_delete(inbuf);

if(buflen>1)

{

  syscnt = *(uint32_t*) buf;

}

 

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

 

syscnt = *(uint32_t*) buf;

qstruct = osMailAlloc(strout_Queue, osWaitForever);

qstruct->y_pos = arg_sock->y_pos;

sprintf(qstruct->str,"%10lu",syscnt);

osMailPut(strout_Queue, qstruct);

 

Узнаем количество прошедших системных квантов и присвоим их значение переменной

 

osMailPut(strout_Queue, qstruct);

syscnt = osKernelSysTick();

 

 

Отправим данное количество клиенту и немного подождём

 

syscnt = osKernelSysTick();

netconn_write(newconn, (void *) &syscnt, 4, NETCONN_COPY);

osDelay(1);

 

На дисплее чуть ниже отобразим также и эту величину, а затем освободим память очереди

 

osDelay(1);

qstruct->y_pos = arg_sock->y_pos + 40;

sprintf(qstruct->str,"%10lu",syscnt);

osMailPut(strout_Queue, qstruct);

osMailFree(strout_Queue, qstruct);

 

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

Соответственно мы кроме шапки не увидим ничего, так как у нас пока нет клиента.

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

Проект для клиента создадим на остнове проекта прошлого урока LAN8742_TCP_CLIENT_NETCONN и назовём её просто LAN8742_TCP_CLIENT.

Также откроем наш проект в Cube MX и, ничего в нём не трогая, сгенерируем проект для System Workbench и откроем его там. Установим уровень оптимизации в 1, уберём при наличии отладочные настройки и закомментируем неизвестные компилятору строки для видеоускорителя в файле main.c.

Попробуем собрать проект и начнём работать с файлом main.c.

В функции задачи по умолчанию StartDefaultTask исправим IP-адрес сервера

 

IP4_ADDR(&ServerIPaddr, 192, 168, 1, 191);

 

Порт клиента будет также другим

 

err = netconn_bind(conn, NULL, 1555);

 

Также изменится и порт сервера

 

err = netconn_connect(conn, &ServerIPaddr, 80);

 

 

Перейдём в функцию задачи отправки пакетов send_thread и удалим вот эту часть кода

 

if(syscnt>50000)

{

  netconn_close(conn);

  netconn_delete(conn);

  qstruct = osMailAlloc(strout_Queue, osWaitForever);

  qstruct->y_pos = 160;

  strcpy(qstruct->str,"Connection was closed!");

  osMailPut(strout_Queue, qstruct);

  osMailFree(strout_Queue, qstruct);

  osDelay(2);

  break;

}

sprintf(buf,"%lu\r\n",syscnt);

 

Строковый буфер нам здесь также будет не нужен

 

uint32_t syscnt = 0;

char buf[15] = {};

 

Исправим аргументы в вызове функции отправки данных

 

sent_err = netconn_write(conn, (void *) &syscnt, 4, NETCONN_COPY);

 

Удалим вот это

 

buf[strlen(buf)-2]=0;

strcpy(qstruct->str,buf);

 

Вместо этого строку для дисплея сформируем вот так

 

qstruct->y_pos = 60;

sprintf(qstruct->str,"%10lu",syscnt);

 

Мы уже можем проверить как у нас идёт передача с клиента на сервер.

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

 

 

Отлично!

Данные передаются, также данные уже принимаются клиентом с сервера, просто некорректно отображаются в нижней строке.

Сейчас мы это исправим.

Перейдём в функцию задачи приёма пакетов recv_thread и объявим там также 32-битную переменную

 

u16_t buflen;

uint32_t syscnt = 0;

 

В теле условия вменяемости величины буфера заберём данные из локального буфера в нашу переменную

if(buflen>1)

{

  syscnt = *(uint32_t*) buf;

 

Удалим в этом же теле всё вот это

 

strncpy(str_buf,(char*)buf,buflen);

str_buf[buflen-1]=0;

sprintf(qstruct->str,"%-20s", str_buf);

 

И вместо этого сформируем строку для дисплея вот так

qstruct->y_pos = 100;

sprintf(qstruct->str,"%10lu",syscnt);

 

Вроде бы всё.

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

 

 

Всё передаётся и принимается.

Итак, в данном уроке нам удалось соединить между собой два контроллера по сети LAN посредством использования интерфейса NETCONN стека протоколов LWIP, а также организовать между ними обмен данными.

Всем спасибо за внимание!

 

 

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

 

Исходный код сервера

Исходный код клиента

 

 

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

 

 

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

 

STM LAN8742A. LWIP. NETCONN. TCP. Соединяем два контролера

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

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

*