stm32F429 DP83848K LWIP 调试笔记 快速发送

这几条,使用F429 和DP83848K 调试lwip
期间踩了一些坑,记录一下,防止自己再踩

  1. 代码是cubemx生成的,具体的方法,参考这篇文章,代码自动生成后,修改芯片的复位引脚,并在初始化时对DP83848复位。
  2. ping通后,把单片机端配置成客户端,IP和端口号设置成需要的。
void tcp_Client_Task(void)
{
    err_t ret;
    u32 tcp_client_timer = 0;
    u8 res=0;	

    /* 将目标服务器的IP写入一个结构体,为pc机本地连接IP地址 */
    IP4_ADDR(&s_ipaddr, 192, 168, 1, 100);

    /* 为tcp客户端分配一个tcp_pcb结构体	*/
    tcp_client_pcb = tcp_new();

    /* 绑定本地端号和IP地址 */
    tcp_bind(tcp_client_pcb, IP_ADDR_ANY, 8000);

    if (tcp_client_pcb != NULL)
    {
        /* 与目标服务器进行连接,参数包括了目标端口和目标IP */
        ret = tcp_connect(tcp_client_pcb, &s_ipaddr, 8000, tcp_client_connected);
        printf("connect\r\n");
    }
    else
        res = 1;

    while(0 == res)
    {
        MX_LWIP_Process();  
        if(sndflag)
        {
            sndflag = 0;
            tcp_client_usersent(tcp_client_pcb,s_netSndbuf, s_netSndlen);
        }
        
//tcp_client_usersent(tcp_client_pcb,s_netSndbuf, 1024);
        
        myRunStateStruct.netConnectState = tcp_client_pcb->state;


        if(++tcp_client_timer > 100000){
            tcp_client_timer = 0;  
            
            if(ESTABLISHED != myRunStateStruct.netConnectState)
            {
                res = 1;
            }
        }
    }
    myRunStateStruct.tim5_StartState = 0;

    tcp_client_connection_close(tcp_client_pcb,0);//关闭TCP Client连接

}
  1. 建立通信,我这把电脑设置成服务器端。 先把服务器的端口打开,后给单片机上电,这样就可以建立起来连接,但是不是每次都能成功,偶尔会连接不上。后续未来确保每一次都没问题,增加了一个状态判断的代码,如果一定时间内状态不对,则退出来,关闭tcp后再重新进入该任务重新连接。
		if(++tcp_client_timer > 100000){
            tcp_client_timer = 0;  
            
            if(ESTABLISHED != myRunStateStruct.netConnectState)
            {
                res = 1;
            }
        }
  1. 展示出来tcp_client_connected 的代码,期间,遇到了一些困难,因为也是才调试lwip和dp83848,卡在这个位置卡了3天,速度一直上不去。
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
    err_t ret;
    struct tcp_client_struct *es=NULL;  
	if(err==ERR_OK)   
	{
		es=(struct tcp_client_struct*)mem_malloc(sizeof(struct tcp_client_struct));  //申请内存
		if(es) //内存申请成功
		{
 			es->state=ES_TCPCLIENT_CONNECTED;//状态为连接成功
			es->pcb=tpcb;  
			es->p=NULL; 
			tcp_arg(tpcb,es);        			//使用es更新tpcb的callback_arg      
//            tcp_nagle_disable(tpcb);          
			tcp_recv(tpcb,tcp_client_recv);  	//初始化LwIP的tcp_recv回调功能   
			tcp_err(tpcb,tcp_client_error); 	//初始化tcp_err()回调函数
			tcp_sent(tpcb,tcp_client_sent);		//初始化LwIP的tcp_sent回调功能
			tcp_poll(tpcb,tcp_client_poll,1); 	//初始化LwIP的tcp_poll回调功能             
			err=ERR_OK;
		}
        else
		{ 
			tcp_client_connection_close(tpcb,es);//关闭连接
			err=ERR_MEM;	//返回内存分配错误
		}
	}
    else
	{
		tcp_client_connection_close(tpcb,0);//关闭连接
	}
	return err;
}

函数是参考的正点原子的例程和官方的例程。其中注释掉了tcp_nagle_disable(tpcb); 这个函数是关闭nagle算法,可以立马发送,但是在这里测试我感觉没啥影响就给注释了。
开始我的速度一直发送不上去,非常不稳定,只有十多K,还会报错
Assertion “pbuf_free: p->ref > 0” failed at line 753 in …/Middlewares/Third_Party/LwIP/src/core/pbuf.c
给我就整糊涂了。一直没有弄明白,就打算参考一下大佬们的例程来直接测试速度。
参考了正点原子代码和野火的代码,但是他们的代码都是用的LNA8720的芯片,和我的有所区别,所以也需要移植,还在野火的LWIP的文档里面有一个关于lwip速度的测试,都是带OS的,其中文档中描述发送可以达到11.5MB/S,接收也能达到11.5MB/S,这给了我很大的鼓舞,至少速度要上的去。
copy其代码过来,修改复位脚,发现接收我能跑到7-8MB/S的速度,但是发送的速度一样的上不去,只有十多K并且也不稳定,这就让我很疑惑。
后来经过同事提醒,让我看看DP83848的例程,我发现除了在设置eth的地址的时候,需要设置成1之外,还有要修改的 地方,下方是野火的

/* Section 4: Extended PHY Registers */
#define PHY_SR                          ((uint16_t)0x1FU)    /*!< PHY status register Offset                      */
#define PHY_SPEED_STATUS                ((uint16_t)0x0004U)  /*!< PHY Speed mask                                  */
#define PHY_DUPLEX_STATUS               ((uint16_t)0x0010U)  /*!< PHY Duplex mask                                 */

这里和cubemx生成的不一样,下面的是cubemx生成的。

/* Section 4: Extended PHY Registers */
#define PHY_SR                          ((uint16_t)0x10U)    /*!< PHY status register Offset                      */
#define PHY_MICR                        ((uint16_t)0x11U)    /*!< MII Interrupt Control Register                  */
#define PHY_MISR                        ((uint16_t)0x12U)    /*!< MII Interrupt Status and Misc. Control Register */

#define PHY_LINK_STATUS                 ((uint16_t)0x0001U)  /*!< PHY Link mask                                   */
#define PHY_SPEED_STATUS                ((uint16_t)0x0002U)  /*!< PHY Speed mask                                  */
#define PHY_DUPLEX_STATUS               ((uint16_t)0x0004U)  /*!< PHY Duplex mask                                 */

修改完后编译,发送,居然真的跑到了10-11MB/S,简直完美!给与了我信心,我至少能开始移植到我的代码里面去了。lwipop.h的配置是参考的野火的配置
6. 后经过对比,发现是我在10ms定时器里面调用了发送的函数,这直接影响了速度,后修改成定时器中改标志位,在while中调用发送函数。 就完美了。
7. 在定时器中发送,经常会打印如此类别的错误代码
Assertion “pbuf_free: p->ref > 0” failed at line 753 in …/Middlewares/Third_Party/LwIP/src/core/pbuf.c
应该是发送的时候,还没发完,又再次进发送函数,导致free的时候没得两次free之类的错误。

  1. 附录上 发送测试代码,可达10MB/S
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值