IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> stm32F429 DP83848K LWIP 调试笔记 快速发送 -> 正文阅读

[嵌入式]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
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:47:09  更:2021-11-19 17:48:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:39:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码