28140|18

918

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

关于开启lwIP协议栈的调试输出LWIP_DEBUGF [复制链接]

我们在分析lwIP协议栈的时候,会经常看到LWIP_DEBUGF()这个函数的身影。我想lwIP的作者可能为了便于人们去学习和使用lwIP而花了不少时间添加的。
其实对于初学者来说,要把lwIP协议栈分析清楚不是一件容易的事情,尤其是对TCP/IP协议原理不是很了解的人。文件较多,函数较多,宏较多,调用关系相比一般的C程序来说较复杂。
我个人认为,有些时候开启一下lwIP的调试信息输出功能,无论是对于我们学习还是查找以太网通信中的故障都是有帮助的。它能够lwIP协议栈中的一些内部函数调用关系,变量值,追踪信息等通过串口输出来。
总之,
1.可以查看函数的调用关系,跟踪程序流程。
2.查看各种协议的调试信息,关键变量的值。
3.通过以上掌握的很有针对性调试信息,我们可以以此为依据进一步地去优化我们的工程,保证各种资源的分配合理,了解到底是通信过程中的哪一个环节限制了网络的性能,然后加以改善。
 其实,我觉得lwIP协议栈的调试上,作者也是花了不少心思的。把要输出地调试信息分为按协议类型(TCP,UDP,ICMP,ARP....),调试信息类型(LWIP_DBG_TRACE,LWIP_DBG_STATE,LWIP_DBG_FRESH),调试信息级别(LWIP_DBG_LEVEL_OFF,LWIP_DBG_LEVEL_WARNING,LWIP_DBG_LEVEL_SERIOUS,LWIP_DBG_LEVEL_SEVERE)
之所以要这么做,其实就是对要输出的调试信息有一个更好的管理,当我们开启调试功能后,只输出相关的调试信息,无关的信息就不要输出了。
接下来以一个简单的例子,说一下,如何开启lwIP的调试功能。
1.找到debug.h,添加下面这个define。
#define LWIP_DEBUG
#ifdef LWIP_DEBUG
/** print debug message only if debug message type is enabled...
 *  AND is of correct type AND is at least LWIP_DBG_LEVEL
 */
#define LWIP_DEBUGF(debug, message) do { \
                               if ( \
                                   ((debug) & LWIP_DBG_ON) && \
                                   ((debug) & LWIP_DBG_TYPES_ON) && \
                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
                                 LWIP_PLATFORM_DIAG(message); \
                                 if ((debug) & LWIP_DBG_HALT) { \
                                   while(1); \
                                 } \
                               } \
                             } while(0)

#else  /* LWIP_DEBUG */
#define LWIP_DEBUGF(debug, message) 
#endif /* LWIP_DEBUG */

#endif /* __LWIP_DEBUG_H__ */


2.在lwIPopts.h的debug options部分,按如下设置,要调试什么就把前边的“//”注释去掉即可。
//*****************************************************************************
//
// ---------- Debugging options ----------
//
//*****************************************************************************
#if 1
#define U8_F "c"
#define S8_F "c"
#define X8_F "x"
#define U16_F "u"
#define S16_F "d"
#define X16_F "x"
#define U32_F "u"
#define S32_F "d"
#define X32_F "x"
extern void UARTprintf(const char *pcString, ...);
#define LWIP_PLATFORM_DIAG(x) {UARTprintf x;}
#define LWIP_DEBUG
#endif


#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_OFF
//#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_WARNING
//#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_SERIOUS
//#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_SEVERE

//#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
#define LWIP_DBG_TYPES_ON               (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH)

//#define ETHARP_DEBUG                    LWIP_DBG_ON     
//#define NETIF_DEBUG                     LWIP_DBG_ON     
//#define PBUF_DEBUG                      LWIP_DBG_ON
//#define API_LIB_DEBUG                   LWIP_DBG_ON
//#define API_MSG_DEBUG                   LWIP_DBG_ON
//#define SOCKETS_DEBUG                   LWIP_DBG_ON
//#define ICMP_DEBUG                      LWIP_DBG_ON
//#define IGMP_DEBUG                      LWIP_DBG_ON
//#define INET_DEBUG                      LWIP_DBG_ON
#define IP_DEBUG                        LWIP_DBG_ON     
//#define IP_REASS_DEBUG                  LWIP_DBG_ON
//#define RAW_DEBUG                       LWIP_DBG_ON
//#define MEM_DEBUG                       LWIP_DBG_ON
//#define MEMP_DEBUG                      LWIP_DBG_ON
//#define SYS_DEBUG                       LWIP_DBG_ON
#define TCP_DEBUG                       LWIP_DBG_ON
//#define TCP_INPUT_DEBUG                 LWIP_DBG_ON
//#define TCP_FR_DEBUG                    LWIP_DBG_ON
//#define TCP_RTO_DEBUG                   LWIP_DBG_ON
//#define TCP_CWND_DEBUG                  LWIP_DBG_ON
//#define TCP_WND_DEBUG                   LWIP_DBG_ON
#define TCP_OUTPUT_DEBUG                LWIP_DBG_ON
//#define TCP_RST_DEBUG                   LWIP_DBG_ON
//#define TCP_QLEN_DEBUG                  LWIP_DBG_ON
//#define UDP_DEBUG                       LWIP_DBG_ON     
//#define TCPIP_DEBUG                     LWIP_DBG_ON
//#define PPP_DEBUG                       LWIP_DBG_ON
//#define SLIP_DEBUG                      LWIP_DBG_ON
//#define DHCP_DEBUG                      LWIP_DBG_ON     
//#define AUTOIP_DEBUG                    LWIP_DBG_ON
//#define SNMP_MSG_DEBUG                  LWIP_DBG_ON
//#define SNMP_MIB_DEBUG                  LWIP_DBG_ON
//#define DNS_DEBUG                       LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */


3.当然通过串口输出的话,在main()函数里边还要初始化串口。
4.通过以上三步基本就可以了,如果没有,看是否在用到>LWIP_DEBUGF()函数的C文件中,#include "lwip/debug.h",或者是include了包含此头文件的其它头文件,如opt.h。这是我调试打开一个网页时输出的调试信息:
[ 本帖最后由 academic 于 2011-3-14 17:12 编辑 ]

1.jpg (73.07 KB, 下载次数: 9)

1.jpg

最新回复

这个帖子很好   详情 回复 发表于 2022-7-14 23:42
 
点赞(1) 关注(1)

回复
举报

2639

帖子

0

TA的资源

五彩晶圆(中级)

沙发
 
写得非常好,我也是摸索了很久才搞懂的:D
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

板凳
 

回复 沙发 fengzhang2002 的帖子

 这个可以用来检查协议栈中的内存分配情况,输出地调试信息可在配置lwipopts.h时作为参考。调试配置完成之后,

可通过注释debug.h中的#define LWIP_DEBUG和lwipopts.h中的if 1改为if 0来关闭调试的输出。当然最后如果不用到串口的话,也可把串口的初始化相关代码去掉。

[ 本帖最后由 academic 于 2010-12-15 09:28 编辑 ]
 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

4
 

回复 楼主 academic 的帖子

通过上面的这个图片,不难看到,Http发送网页数据的一个过程:

处理get请求

寻找网页文件

打开网页文件

读取网页文件到文件缓冲区

复制网页文件到RAM中的PBUF(如果网页不是存储在ROM中的话):tcp_write()

把刚复制到RAM中的网页数据依据设置的MSS大小分成分段(segment),放入到发送队列:tcp_enqueue()

输出segmes:tcp_output,tcp_output_segment,(依照窗口大小)。

调用tcp_sent()指定的http_sent()检查一下是否还有读取的文件数据未发送完。

若都发送完了,关闭文件,关闭连接。

在配置lwIP协议栈发送数据的时候,涉及到总内存大小的配置,发送缓冲区的大小,窗口的大小,队列的长度等等,如何更好地在这几个参数之间保持一个平衡,实现较快地速度,希望高手能指点一下。

因为,我发现,这些参数并不是越大越好。

还有,tcp_enqueue()把好几个segment排到了队列,tcp_output_segment却并不及时的发送出去,是拥塞窗口限制了吗?这要怎么改善呢?

 

[[i] 本帖最后由 academic 于 2010-12-15 18:38 编辑 [/i]]
 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

5
 
顶一下,盼高手指点一下。
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(中级)

6
 

回复 5楼 academic 的帖子

:$ 你就已经是高手了
 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

7
 

回复 6楼 zhangyao 的帖子

还有很多问题没搞明白呢。:(
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(初级)

8
 

LZ你好,我按照你写的设置了,串口也设置了,但是LWIP_DEBUG没起作用,串口上没有你图片所示的东西,不知道还漏了什么?

 

 

 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

9
 

回复 8楼 qwertyer2010 的帖子

呵呵,我修正了一下,你再试试。
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(初级)

10
 

回复 9楼 academic 的帖子

还是不行,一开这个DEBUG,以太网都通信不上了。
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

11
 
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);

UARTStdioInit(0);

我用上面的 代码初始化 串口 然后在每个C文件里包含了 #include "utils/uartstdio.h" 可以输出调试信息的 , 默认波特率是115200 也可以在UARTStdioInit(); 函数里面修改 ...

[ 本帖最后由 tt383 于 2011-3-16 11:59 编辑 ]
 
 
 

回复

33

帖子

0

TA的资源

一粒金砂(中级)

12
 
看了这个  感觉有点懂了
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

13
 

使用Lwip一定要用到操作系统吗?

请问一下使用Lwip一定要用到操作系统吗?
不用的话会有什么问题吗?
 
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

14
 

回复 13楼 sky151 的帖子

Lwip 不一定要用到操作系统。
不用操作系统,开发起来会复杂一些。如果任务量比较多的话,实时性不能得到保证。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(初级)

15
 
mark 一下。。。
 
 
 

回复

29

帖子

0

TA的资源

一粒金砂(中级)

16
 
关键是怎么把数据打包发送出去,而且不是用定义静态的数组。
 
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

17
 
看看 lwip 相关内存分配的资料,用动态内存分配和回收,malloc
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

18
 
mark
 
 
 

回复

428

帖子

7

TA的资源

纯净的硅(初级)

19
 

这个帖子很好

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表