OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4833|回复: 3

如何实现STM32F207+DP83848热插拔功能(基于STM32CUBEIDE)

[复制链接]

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
发表于 2021-2-25 09:20:44 | 显示全部楼层 |阅读模式
50金钱
本帖最后由 jiangyy 于 2021-2-25 09:21 编辑

最近一直在开发STM32F207+DP83848+freertos,通讯模式是NETCONN_TCP 客户端。不多说了,先分享一下我的开发经验。目前已经调试OK,可以正常通讯。老化测试24H,没出现死机现象,可以正常运转。我使用的是动态IP自协商,配一个WIFI路由器,客户端和服务端均以网线连接到WIFI路由器,这样可以动态分配IP地址,同一个网关上运行。现在棘手的问题是,客户端网线短时间可以实现热插拔,但是长时间断开再连接网线,无法链接通讯。其次就是拔掉服务端网线再插上网线,必然无法链接通讯。求助资深网络高手指点迷津。下面是我STM32CUBE配置图:1.DP83848配置图1
DP83848配置图.jpg
2.DP83848配置图2
DP83848配置图2.jpg

3.自协商开启
自协商开启.jpg
这个是使用动态分配地址
4.链接回调开启
链接回调开启.jpg
这个是连接回调函数,能识别网线断开或者连接状态,你也可以理解为网线外部中断回调函数,这个是能实现热插拔的重要函数。
  1. _Bool ethConnectedFlag;
  2. extern struct netif gnetif;
  3. /* USER CODE END Header_StartETHConnectTask */
  4. void ethernetif_notify_conn_changed(struct netif *netif)
  5. {
  6.           if(netif_is_link_up(netif))
  7.                 {
  8.                         netif_set_up(netif);
  9.                         dhcp_start(&gnetif);//如果使用静态IP地址,这个需要屏蔽掉
  10.                 }
  11.                 else
  12.                 {
  13.                         netif_set_down(netif);
  14.                         ethConnectedFlag = 0;
  15.                 }
  16. }
复制代码
void ethernetif_notify_conn_changed(struct netif *netif)这个回调函数在ethernetif.c文件里面,因为是弱函数,所以可以调用到 freertos.c文件使用。

5.创建网络连接任务
  1. void StartETHConnectTask(void const * argument)
  2. {
  3.   /* USER CODE BEGIN StartETHConnectTask */
  4.   /* Infinite loop */
  5.         //        struct netconn *conn;
  6.         ip_addr_t serverIP;
  7.         uint16_t serverPort = 8080;

  8.         IP4_ADDR(&serverIP, 192, 168, 2, 8);
  9.         conn = netconn_new(NETCONN_TCP);
  10.         osDelay(2000);
  11.         myerr = netconn_connect(conn, &serverIP, serverPort);
  12.   for(;;)
  13.   {
  14.                 if(myerr == ERR_OK)
  15.                 {
  16.                         ethConnectedFlag = 1;
  17.                 }
  18.                 else
  19.                 {
  20.                         ethConnectedFlag = 0;
  21.                         netconn_delete(conn);
  22.                         conn = netconn_new(NETCONN_TCP);
  23.                         myerr = netconn_connect(conn, &serverIP, serverPort);
  24.                 }
  25.                 osDelay(1000);
  26.   }
复制代码
6.创建网络接收发送任务
  1. /* USER CODE BEGIN Header_StartETH_Task */
  2. /**
  3. * @brief Function implementing the ETH_Task thread.
  4. * [url=home.php?mod=space&uid=271674]@param[/url] argument: Not used
  5. * @retval None
  6. */
  7. /* USER CODE END Header_StartETH_Task */
  8. void StartETH_Task(void const * argument)
  9. {
  10.   /* USER CODE BEGIN StartETH_Task */
  11.   /* Infinite loop */
  12.         struct netbuf *recvPack;
  13.         uint8_t recvBuf[32] = {0};
  14.         //  uint8_t sendBuf[32] = {0};
  15.         uint8_t len;
  16.   for(;;)
  17.   {
  18.           if(ethConnectedFlag == 1)
  19.           {
  20.                   if((myerr=netconn_recv(conn, &recvPack))==ERR_OK)
  21.                   {
  22.                           LED7_debug_Toggle();
  23.                           taskENTER_CRITICAL(); //关中断
  24.                           memset(recvBuf, 0, sizeof(recvBuf));
  25.                           if((recvPack->p->len) > 32)//超出缓存最大值
  26.                           {
  27.                                   netbuf_delete(recvPack);
  28.                           }
  29.                           else
  30.                           {
  31.                                   memcpy(recvBuf, recvPack->p->payload, recvPack->p->len);
  32.                                   len = recvPack->p->len;
  33.                                   netbuf_delete(recvPack);
  34.                                   myerr = netconn_write(conn, recvBuf, len, 0);
  35.                           }
  36.                          taskEXIT_CRITICAL();  //开中断
  37.                   }
  38.           }
  39.     osDelay(1);
  40.   }
  41.   /* USER CODE END StartETH_Task */
  42. }
复制代码


现在可以正常通讯,短时间拔插客户端网线可以实现热插拔,但是长时间拔插客户端网线,就无法通讯。拔掉服务端网线,必然无法通讯。请求网络高手指点迷津。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2021-2-26 01:52:49 | 显示全部楼层
回复

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2021-2-26 08:37:06 | 显示全部楼层
数据测试.jpg
分别在DP83848和LAN8720A两款PHY芯片跑通了,老化测试一个晚上,没发现死机现象。目前以实现客户端热插拔功能,但没实现服务端热插拔功能(这里我使用的是动态IP地址,自主协商),后期看看能不能实现服务端热插拔功能。如果使用静态IP地址,无法实现热插拔功能,这点也是后期看能否优化。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2021-2-27 01:11:27 | 显示全部楼层
帮顶
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 12:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表