Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Cетевые протоколы и технологии

Cетевые протоколы и технологии TCP/IP стек

Ответ
 
Опции темы Опции просмотра
Старый 06.03.2017, 16:45   #1
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Конфигурация LwIP стека

Уважаемые знатоки LwIP стека!
Пользуюсь LwIP стеком v1.4.1 для микроконтроллеров STM32F4. Тип API - Netconn. Операционная система - FreeRTOS.
Задача: данные "пакуются" в пакеты по 1460 байт (равны максимальному размеру кадра Ethernet минус заголовки IP и TCP). В секунду требуется передать 4 пакета (на самом деле чуть чаще). Устройство передающее пакеты - сервер, приложение на ПК - клиент. При использовании транспортного уровня UDP пакеты не теряются. При использовании TCP тоже не теряются, если со стороны ПК загрузка небольшая. Если на ПК выполняется какая нибудь ресурсоемкая задача, 1-5% пакетов теряется.
Приложение со стороны ПК написано в Visual C++, для работы с сокетами используются API winsock2. Я не очень уверенно чувствую себя в программировании под Windows, и скорей всего не очень эффективно пользуюсь API для управления сокетами winsock2. В Windows приложении я организовал таймер, и в обработчике событий от таймера проверяю наличие новых данных. Соответственно в эти обработчики я попадаю крайне нерегулярно, в зависимости от загрузки CPU.
В TCP протоколе, когда клиент (приложение на ПК) не успевает читать из сокета пакет, не выдается сигнал подтверждения (ACK) и сервер (мое устройство) должен повторить пакет (или несколько пакетов, в зависимости от размера плавающего окна). Работает ли этот алгоритм (повторная передача пакетов при отсутствии ACK) на стороне сервера (на стороне моего устройства)? В файле конфигурации LwIP мне некоторые автоподстановки не совсем понятны. Приведу некоторые из них, поправьте, пожалуйста, если я неправильно их закомментировал или какие то настройки Вам покажутся нелепыми (понимаю, что все зависит от конкретной задачи, но все же...).
Код:
// Размер SRAM который может быть использован стеком LwIP
#define MEM_SIZE		(15*1024)
// Максимальное колличество используемых в проекте структур pbuf, использующих динамически выделяемую память
#define MEMP_NUM_PBUF           16
// Максимальное колличество управляющих структур TCP соединений (колличество возможных одновременно
// открытых соединений)
#define MEMP_NUM_TCP_PCB        1
// Максимальное колличество сокетов, которые предполагается одновременно слушать
#define MEMP_NUM_TCP_PCB_LISTEN 1
// Максимальное колличество TCP сегментов, одновременно находящихся в очереди для передачи. Это число
// связано с автоподстановками TCP_SND_BUF и TCP_SND_QUEUELEN
#define MEMP_NUM_TCP_SEG        16
// Максимальное колличество одновременных подсчетов таймаута. Непонятно с какой настройкой связать 
// эту автоподстановку. Возможно с колличеством одновременно возможных соединений. На всякий случай 
// не делаю эту автоподстановку равной 1.
#define MEMP_NUM_SYS_TIMEOUT    5
// Максимальное колличество используемых в проекте структур pbuf, используемых память POOL
#define PBUF_POOL_SIZE          16
// Размер POOL буфера. Я считаю рациональным использовать такой же размер POOL как и максимальный 
// размер полезной нагрузки
#define PBUF_POOL_BUFSIZE       (1500-40)
// Определяется, если требуется контроль очереди сегментов
#define TCP_QUEUE_OOSEQ         1
// Максимальный размер полезной нагрузки (1500 - размер заголовка TP - размер заголовка TCP)
#define TCP_MSS                 (1500-40)
// Максимальное колличество байт, которые могут быть поставлены в очередь для отправки 
// по TCP соединению при выполнении функции  tcp_write
#define TCP_SND_BUF             (8*TCP_MSS)
// Эта автоподстановка мне непонятна. Какая то еще одна очередь. Может быть очередь уже FreeRTOS для задачи
// передачи данных. Она должна быть как минимум (2*TCP_SND_BUF/TCP_MSS)
#define TCP_SND_QUEUELEN        (2* TCP_SND_BUF/TCP_MSS)
// Максимальный размер окна (в байтах) для приема данных. Рекомендуется использовать такой же размер окна
// как в автоподстановке TCP_SND_BUF
#define TCP_WND                 (8*TCP_MSS)
Очень сомневаюсь я в правильности понимания настроек MEMP_NUM_TCP_SEG, TCP_SND_BUF и TCP_SND_QUEUELEN.
Я так понимаю, что для моей проблемы актуальна настройка TCP_QUEUE_OOSEQ, которую надо установить в 1. На самом деле разницы нет. Пакеты теряются.
У меня принципиальное непонимание: вот я вызываю функцию netconn_write(), она всегда возвращает 0. Даже когда клиент "висит" и не принимает данные.
Какой то ведь флаг должен установиться, когда переполняется область TCP_SND_BUF? Заранее спасибо всем, кто захочет помочь.
Pasha_Bi вне форума   Ответить с цитированием
Старый 07.03.2017, 11:41   #2
Рак
Senior Member
 
Регистрация: 02.04.2008
Адрес: Кременчуг
Возраст: 31
Сообщений: 1,290
Вес репутации: 2246/70
Рак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond repute
По умолчанию Re: Конфигурация LwIP стека

Думаю, нужно "допиливать" прием данных. К тому же, отправка подтверждения на принятый пакет - это не дело приложения, а немного глубже в ОС. Приложению маякнули, что принято, а что с этим делать уже дело пользовательской программы.
Рак вне форума   Ответить с цитированием
Старый 07.03.2017, 21:58   #3
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Re: Конфигурация LwIP стека

Спасибо. Да, дело в приложении. Сегодня убедился, что даже если в приложении вообще не читать данные из сокета, ACK пакеты отправляются (смотрел Wireshark). Опрашивать принятые данные в прерываниях таймера - неудачный подход. Выделил отдельный поток, назначил ему приоритет повыше. Сокет - в блокирующий режим (режим по умолчанию). Вроде не пропадают пакеты. Еще раз спасибо. А с настройками LwIP все равно не очень прозрачно у меня пока. Буду искать, эксперементировать (по возможности). Если разберусь, отпишусь в этой же теме.
Pasha_Bi вне форума   Ответить с цитированием
Старый 10.11.2017, 14:46   #4
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Re: Конфигурация LwIP стека

Поразбирался немного, некоторые настройки стали понятнее:
MEMP_NUM_PBUF - Максимальное колличество используемых в проекте структур pbuf, использующих PBUF_ROM и PBUF_REF. Если приложение отправляет много данных из ПЗУ, это значение должно быть установлено высоким. По умолчанию - 16.
MEMP_NUM_SYS_TIMEOUT - Максимальное колличество подсчетов таймаута. Если не определить, то автоматически расчитывается по колличеству используемых в проекте процессов, требующих этого ресурса: MEMP_NUM_SYS_TIMEOUT=(LWIP_TCP+IP_REASSEMBLY+LWIP_ ARP+(2*LWIP_DHCP)+LWIP_AUTOIP+LWIP_IGMP+LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB)+(LWIP_IPV6?(1+LWI P_IPV6_REASS+LWIP_IPV6_MLD):0))
PBUF_POOL_BUFSIZE - Размер POOL буфера, по умолчанию задан так: LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULA TION_HLEN+PBUF_LINK_HLEN), т.е. по умолчанию этот буфер будет вмещать полезную нагрузку (TCP_MSS), заголовки транспортного и сетевого уорвня (40), Ethernet заголовок (PBUF_LINK_HLEN=14=6+6+2)
TCP_SND_QUEUELEN - Определяет какое колличество буферов pbuf может быть в очереди для передачи данных. Это значение должно быть по крайней мере (2*TCP_SND_BUF/TCP_MSS) - значение по умолчанию. Это ограничение - всего лишь проверка безопасности, что одно соединение не потребляет слишком много pbufs.
Для большинства из участников форума это очевидно и понятно. Обещал отписаться....
Pasha_Bi вне форума   Ответить с цитированием
Старый 10.11.2017, 15:03   #5
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Re: Конфигурация LwIP стека

Очень непросто мне далась настройка вывода диагностических сообщений. То же в файле lwipopts.h.
При использовании функции printf() в IAR по умолчанию (в опциях проекта) данные передаются (через отладчик) в окно терминала. Довольно медленно. Решил использовать доступный в моем устройстве порт RS-232. Не понравился сам принцип: инструмент вывода диагностического сообщения (#define LWIP_PLATFORM_DIAG(message)) приходится переопределять в файле cc.h (\LwIP\system\arch\). Мне как то править файл из библиотеки неприятно. Как обойти этот момент?
Pasha_Bi вне форума   Ответить с цитированием
Старый 11.11.2017, 02:31   #6
siarzhuk
Senior Member
 
Аватар для siarzhuk
 
Регистрация: 08.11.2014
Возраст: 47
Сообщений: 114
Вес репутации: 1058/23
siarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud of
По умолчанию Re: Конфигурация LwIP стека

Цитата:
Сообщение от Pasha_Bi Посмотреть сообщение
Не понравился сам принцип: инструмент вывода диагностического сообщения (#define LWIP_PLATFORM_DIAG(message)) приходится переопределять в файле cc.h (\LwIP\system\arch\). Мне как то править файл из библиотеки неприятно. Как обойти этот момент?
В lwipopts.h не пробовали добавлять? Он из всех модулей библиотеки виден - для настройки под конкретный проект и придуман.

У нас прописано буквально так:

Код:
 /*
   -----------------------------------
   ---------- DEBUG options ----------
   -----------------------------------
*/

#define LWIP_DEBUG                      0

#if LWIP_DEBUG

#include <TargetDebug.h>

#  define LWIP_PLATFORM_DIAG(_arg)      DebugOutString _arg
#  define LWIP_ASSERT(x,y)                   do { if(!(y)) DebugAssert(x); } while(0)

[...]

#else // LWIP_DEBUG

#  define LWIP_PLATFORM_DIAG(_arg)
//#  define LWIP_ASSERT(x,y)

#endif // LWIP_DEBUG
siarzhuk вне форума   Ответить с цитированием
Старый 11.11.2017, 08:26   #7
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Re: Конфигурация LwIP стека

С этого и начал ( с добавления в lwipopts.h). "Ругань" пошла на двойное определение.
Pasha_Bi вне форума   Ответить с цитированием
Старый 11.11.2017, 11:13   #8
siarzhuk
Senior Member
 
Аватар для siarzhuk
 
Регистрация: 08.11.2014
Возраст: 47
Сообщений: 114
Вес репутации: 1058/23
siarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud ofsiarzhuk has much to be proud of
По умолчанию Re: Конфигурация LwIP стека

Цитата:
Сообщение от Pasha_Bi Посмотреть сообщение
С этого и начал ( с добавления в lwipopts.h). "Ругань" пошла на двойное определение.
Как во всяком случае, когда чувствуется, что вас что-то съело - не забывайте, что есть как минимум два выхода. ;-) Первый "выход" - нанести препроцессору апперкот #undef LWIP_PLATFORM_DIAG или на что он там ругался, второй - разбираться где затесалось (и почему) предыдущее определение. И поскольку lwipopts.h задуман как конфигуратор библиотеки - то и препроцессор при обработке любого с-шника из lwIP библиотеки должен быть первоoчерёдно отсылаем именно к lwipopts.h. В вашем случае есть подозрение, что некие .h-файлы из lwIP библиотеки были включены до [и в обход] lwipopts.h. Ну или в дереве проекта есть два разных lwipopts.h (без header guard-ов причём).
Встать на точку зрения препроцессора можно заглянув в .pre файлы в build папочке вашего проекта - это практически с-файлы с развёрнутыми директивами препроцессора (#include, макросы и т.п) и аннотациями что и откуда вставлено.
Бороться с разгулом #include-ов можно разве что рекомендацией оформлять их секцию в порядке "уменьшения глобальности" .h-файла - т.е. простыми словами - сначала платформа, затем - [через отбивку пустой строчкой] - стандартная библиотека - [через отбивку] - третьесторонние библиотеки (lwIP сюда) - [через отбивку] - .h-файлы других модулей нашего проекта. Единственное исключение - самым первым должен быть .h-файл текущего модуля - поскольку если он зависит от чего-то, что волею случая включено перед ним - это не есть хорошо и красиво - всё своё он должен подключать лично и явно - тогда и подключение его самого куда-то ещё обойдётся одной единственной #include директивой.
siarzhuk вне форума   Ответить с цитированием
Старый 13.11.2017, 09:55   #9
Pasha_Bi
Senior Member
 
Регистрация: 24.07.2009
Адрес: г. Иваново
Возраст: 43
Сообщений: 269
Вес репутации: 617/39
Pasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to allPasha_Bi is a name known to all
По умолчанию Re: Конфигурация LwIP стека

Разработчики LwIP стека рекомендуют определять инструмент для вывода сообщений диагностики именно в файле cc.h. Программные модули сначала видят мою автоподстановку из файла lwipopts.h, например:
Код:
#define LWIP_PLATFORM_DIAG(message)		do{send_debug_msg message;}while(0)
а потом (в такой последовательности стоят диррективы #include) автоподстановку из файла cc.h:
Код:
#define LWIP_PLATFORM_DIAG(message)
Т.о. чтобы LWIP_PLATFORM_DIAG определялась в файле lwipopts.h, а не в cc.h (на мой взгляд это логичней), в файле cc.h пришлось "обрамить" эту автоподстановку в конструкцию
Код:
#ifndef LWIP_PLATFORM_DIAG 
#define LWIP_PLATFORM_DIAG(message)
#endif
Да, я все таки подправил библиотечный файл, но для всех проектов он останется один и тот же.
siarzhuk, спасибо, про pre файлы не знал. Пригодится.
Pasha_Bi вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Снова проблема ожидания ACK в LwIP с другого боку. Petr Cетевые протоколы и технологии 9 30.12.2016 10:47
Android VS LwIP Petr Cетевые протоколы и технологии 96 29.12.2016 12:40
структура TCP/IP стека LwIP v1.3.2 Pridnya Cетевые протоколы и технологии 42 13.12.2016 15:26
C18 и размер програмного стека. Как померять? FlashBack Продукция MICROCHIP 11 09.07.2014 14:03
Как отследить момент переполнения стека 123ksn Вопросы начинающих 27 13.10.2012 00:36


Часовой пояс GMT +3, время: 17:56.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd. Перевод: zCarot