Есть несколько разных методов, обычно используемых для отладки lwIP, стиля printf и с использованием внешнего отладчика.
[Внешний отладчик]
Возможно самый очевидный метод поиска проблем, связанных с сетевым стеком - с помощью отладчика / точки останова начать пошаговую отладку выполняемого кода. Однако поскольку lwIP обычно используется для встраиваемых платформ (микроконтроллеров) с ограниченным объемом ресурсов, то в случае включенной оптимизации запустить отладку по исходному коду может быть затруднительно. Кроме того, должен быть специально реализован способ соединения отладчика с отлаживаемой системой. Часто это решается через сетевое соединение, когда работает сетевой стек и сервер GDB, или какой-то другой демон, позволяющий отладчику общаться с целевой системой.
Поскольку отлаживается сам сетевой стек, то очевидно, что отладчик не сможет работать через то же самое сетевое соединение, и нужен какой-то другой способ обмена данными. Для этого есть несколько решений. Для самой лучшей производительности хорошей идеей будет запустить другой стабильный экземпляр lwIP, или другой сетевой стек, рядом с отлаживаемым стеком lwIP. Это может быть довольно замысловатым способом отладки, в зависимости от определенной архитектуры целевой системы, однако вполне выполнимо и полезно для устранения проблем, возникающих с начальным портированием. Когда стек запущен и заработал, отладчик становится гораздо менее полезен, поскольку большинство проблем создают уже внешние компоненты (чаще всего это компонент, блокирующий выполнение на слишком большое время). Здесь уже поможет старый, традиционный метод вывода отладочных printf-сообщений.
[Встроенная отладка в стиле printf]
Стек lwIP разработан с хорошей поддержкой вывода различных отладочных сообщений, с богатыми опциями настройки этого вывода. Опции отладки разрешаются во время сборки. Это различные xxx_DEBUG опции, которые перечислены в файле opt.h. Измените настройки по умолчанию (в которых отладка выключена) файла opts.h путем добавления в файл lwipopts.h:
#define LWIP_DEBUG 1
#define xxx_DEBUG LWIP_DBG_ON
...
Здесь xxx обозначает отлаживаемую подсистему стека - например, IP_DEBUG, DHCP_DEBUG и т. д.
Пример вывода отлдочных сообщений с включенной опцией NETIF_DEBUG:
netif: netmask of interface netif: GW address of interface
netif_set_ipaddr: netif address being changed
netif: IP address of interface netif: added interface st
IP addr 192.168.0.208 netmask 255.255.255.0 gw 192.168.0.1
netif: setting default interface st
В следующей таблице перечислены все отлаживаемые подсистемы стека, краткая информация по этим опциям приведена также в файле opt.h.
Опция
Какие отладочные сообщения разрешает
ETHARP_DEBUG
Протокол ARP (модуль etharp.c).
NETIF_DEBUG
Работа с сетевым интерфейсом (модуль netif.c).
PBUF_DEBUG
Буферы стека (модуль pbuf.c).
API_LIB_DEBUG
Вызовы библиотечных функций (модуль api_lib.c).
API_MSG_DEBUG
API сообщений (модуль api_msg.c).
SOCKETS_DEBUG
Работа с сетевыми сокетами (модуль sockets.c).
ICMP_DEBUG
Протокол ICMP, поддержка ping (модуль icmp.c).
IGMP_DEBUG
Протокол IGMP (модуль igmp.c).
INET_DEBUG
Функции, общие для всех модулей TCP/IPv4, такие как функции обеспечения нужного порядка следования байт (модуль inet.c).
IP_DEBUG
Протокол IP.
IP_REASS_DEBUG
Разрешение отладки ip_frag.c для фрагментов и пересборки пакетов.
RAW_DEBUG
Низкоуровневая реализация PCB (Protocol Control Blocks, модуль raw.c).
MEM_DEBUG
Облегченная реализация malloc (модуль mem.c).
MEMP_DEBUG
Менеджер динамических пулов памяти (модуль memp.c).
SYS_DEBUG
Слой абстракции операционной системы (модуль sys.c).
Чтобы разрешить отладочный код в LWIP, нужно определить флаг (макрос) LWIP_DEBUG в момент компиляции кода LWIP. Флаги компиляции обычно передаются с опцией "-D" как один из аргументов командной строки компилятора.
[Keil]
Например, при компиляции средствами разработки Keil можно добавить целевые опции компилятора на закладке "define C/C++" целевых опций проекта.
Чтобы разрешить определенные отладочные сообщения LWIP, просто установите соответствующее значение для макросов *_DEBUG в " LWIP_DBG_ON". Выполните копию необходимых для отладки опций, и вставьте их в файл lwipopts.h. Например:
// Строки, добавленные в lwipopts.h:
#define TCP_DEBUG LWIP_DBG_ON
#define ETHARP_DEBUG LWIP_DBG_ON
#define PBUF_DEBUG LWIP_DBG_ON
[IAR]
Зайдите в свойства проекта, раздел C/C++ Compiler, и на закладке Preprocessor в поле ввода "Defined symbols: (one per line)" добавьте строку LWIP_DEBUG:
После этого в файл lwipopts.h включите опции xxx_DEBUG, необходимые для отладки.
[Конфигурирование типов отладочных сообщений]
Стек lwIP поддерживает разные типы отладочных сообщений. Символическая константа LWIP_DBG_TYPES_ON (находится в файле lwipopts.h) может быть изменена, чтобы разрешить или запретить некоторые виды сообщений. Следующие 4 значения могут быть объединены операцией ИЛИ, и назначены для константы LWIP_DBG_TYPES_ON:
/* Флаг для LWIP_DEBUGF, показывающий сообщение трассировки
* (для выполняющихся операций программы): */
#define LWIP_DBG_TRACE 0x40U
/* Флаг для LWIP_DEBUGF, показывающий состояние отладочного сообщения
* (для отслеживания состояний модуля): */
#define LWIP_DBG_STATE 0x20U
/* Флаг для LWIP_DEBUGF, показывающий только что добавленный код,
* это пока еще тщательно не протестировано: */
#define LWIP_DBG_FRESH 0x10U
/* Флаг для LWIP_DEBUGF, вызывающий остановку выполнения после
* вывода на печать этого отладочного сообщения: */
#define LWIP_DBG_HALT 0x08U
[Реализация LWIP_DEBUGF]
Код, который выводит отладочные сообщения, реализован макросом LWIP_DEBUGF. По умолчанию он использует стандартный вывод printf:
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
Ниже приведен кусок кода, где реализован вывод отладочных сообщений в USART1 микроконтроллера STM32F429 (плата 32F429IDISCAVERY). Функцию uprintf можно использовать вместо printf в макросе LWIP_PLATFORM_DIAG(x):
//#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
#define LWIP_PLATFORM_DIAG(x) do {uprintf x;} while(0)
Важный момент: аргумент x в вызове функции uprintf макроса LWIP_PLATFORM_DIAG не надо заключать в скобки, иначе компилятор будет выдавать ошибку "... argument of type "u16_t" is incompatible with parameter of type 'char const *'".
// Вернет ошибку, если формат является указателем NULL:if (!fmt) { return-1; }
// Вернет ошибку, если строка превышает размер буфера, с учетом// необходимых дополнительных 2 символов: CR и нулевой терминатор ASCIIZ:if (UPRINTF_BUF_SIZE-2 < strlen(fmt)) { return-1; }
1. Enabling debug output in LWIP site:community.nxp.com. 2. Debugging lwIP site:lwip.fandom.com. 3. 191113TestUSART1-tx-USART1-with-semaphore.zip - проект IAR 8.30, где демонстрируется отладочный вывод в USART1 под управлением FreeRTOS.
Комментарии
RSS лента комментариев этой записи