请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于STM32+LWIP通信12次无法再次通信的问题【已解决】

[复制链接]
shenxiaolin_mai 提问时间:2019-1-28 10:01 /
本帖最后由 xiaoshen-372360 于 2019-4-19 13:45 编辑

各位大佬,小弟在尝试移植LWIP+FREERTOS的时候出现了如下问题,请各位大佬帮忙看看是哪里的问题,我用了FreeRTOS+LWIP做ModbusTCP时出现了链接出现通信12次然后通信中断,并且再也没法ping 通的问题,表现的现象是进不去以太网中断,导致 ethernetif_input()接收不到数据
移植过程是这样的:(STM32F407+DP83848)

1:首先移植RTOS+固件库,移植成功,并且跑了几个串口通信的任务,测试大概两三天的样子,并没有出现问题。
2:移植LWIP1.4.1 (从ST官网下载的那个网页的例程,修改引脚定义后跑在板子上没问题,确认硬件没问题)
3:将ST官网的LWIP1.4.1 的例子(关于LWIP的部分)移植到步骤1 的FreeRTOS 系统的工程里面,只是添加LWIP初始化的任务,并没有调用任何接口的情况下可以Ping 通 而且长时间Ping 也没问题。
4:调用一个连接,编写函数,将受到的数据发送回去,出现了通信12次就没法在通信的问题(发12次,收12次,通信数据包无论长短,都是12次)而且ping 也ping 不通了。
5:自己写了Modbus-TCP的代码,也是同样的通信12次,也没法通信了,
请教各位大佬,有遇到过类似的情况吗?

查了寄存器,发现PHY寄存器所有状态正常,查看DMA的寄存器,发现以太网DMA状态寄存器存在以下问题
1.png

然后查了ST的参考手册,手册的解释是这样的,
2.png 3.png





尝试解决方法:
1:关于LWIP  ethernetif_input 的问题,网上的解决方式已经尝试过了,这个地方也修改了,

  1. void ethernetif_input( void * pvParameters )
  2. {
  3. struct pbuf *p;

  4. for( ;; )
  5. {
  6. if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
  7. {
  8. TRY_GET_NEXT_FRAGMENT:
  9. p = low_level_input( s_pxNetIf );
  10. if(p!=NULL)
  11. {
  12. if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
  13. {
  14. pbuf_free(p);
  15. p=NULL;
  16. }
  17. else
  18. {
  19. xSemaphoreTake(s_xSemaphore,0);
  20. goto TRY_GET_NEXT_FRAGMENT;
  21. }
  22. }
  23. }
  24. }
  25. }
复制代码
主程序代码是这个样子的
  1. void Modbus_TCP_Tasks(void * pvParameters)
  2. {

  3. struct netconn *conn, *newconn;
  4. int i=0;
  5. err_t err, accept_err;
  6. struct netbuf *buf;
  7. void *data;
  8. u16_t len;
  9. unsigned char *tmpP=NULL;
  10. err_t recv_err;
  11. //--初始化---LWIP协议栈---
  12. ETH_BSP_Config();
  13. LwIP_Init();
  14. MB_TCP_Data_Init();//--协议栈初始化--
  15. // LWIP_UNUSED_ARG(arg);
  16. /* Create a new connection identifier. */
  17. conn = netconn_new(NETCONN_TCP);
  18. err = netconn_bind(conn, NULL, 502);
  19. netconn_listen(conn);
  20. accept_err = netconn_accept(conn, &newconn);
  21. netconn_delete(conn); //删除侦听的连接。
  22. while (1)
  23. {
  24. recv_err = netconn_recv(newconn, &buf);
  25. if ( recv_err == ERR_OK)
  26. {
  27. do
  28. {
  29. netbuf_data(buf, &data, &len);
  30. //--netconn_write(newconn, data, len, NETCONN_COPY);
  31. }
  32. while (netbuf_next(buf) >= 0);
  33. //--拷贝数计--以及数据长度
  34. for(i=0;buf->p!=NULL;buf->p=buf->p->next)//--非空则继续--
  35. {
  36. memcpy((unsigned char *)&TCP_Data[i],buf->p->payload,buf->p->len);
  37. i=i+buf->p->len;
  38. }
  39. netbuf_delete(buf);
  40. {
  41. //--正式开始处理Modbus-TCP 数据--
  42. if((TCP_Data[2]==0)&&(TCP_Data[3]==0))//--查看该数据帧是否为Modbus-TCP数据--
  43. {
  44. MB_TCP_Struct.MB_TCP_Rx_Len=len;//--获取数据长度--
  45. for(i=0;i<6;i++)
  46. {
  47. MB_TCP_Struct.MB_MBAP_Data[i]=TCP_Data[i];
  48. }
  49. //--开始数据拷贝的工作 拷贝的数据应当从第7个数据开始,
  50. for(i=0;i<(MB_TCP_Struct.MB_TCP_Rx_Len-6);i++)
  51. {
  52. MB_TCP_Struct.MB_RxData[i]=TCP_Data[i+6];
  53. }
  54. MB_TCP_Struct.MB_TCP_Rx_Len=i;
  55. //--开始计算CRC
  56. MB_TCP_Struct.CRC_Data=usMBCRC16(MB_TCP_Struct.MB_RxData,MB_TCP_Struct.MB_TCP_Rx_Len );
  57. MB_TCP_Struct.MB_RxData[MB_TCP_Struct.MB_TCP_Rx_Len] = (MB_TCP_Struct.CRC_Data&0xff);
  58. MB_TCP_Struct.MB_RxData[MB_TCP_Struct.MB_TCP_Rx_Len+1] = ((MB_TCP_Struct.CRC_Data>>8)&0xff);
  59. MB_TCP_Struct.MB_RxData_Len=MB_TCP_Struct.MB_TCP_Rx_Len+2;//--加上CRC的数据长度--

  60. MB_TCP_Process(&MB_TCP_Struct);
  61. //--然后完成TCP的组包工作---最后发送--需要消除CRC校验-2-
  62. //--待添加---
  63. //--填充TCP的MBAP数据--按照协议标准是需要直接复制前 4位
  64. for(i=0;i<6;i++)
  65. {
  66. MB_TCP_Struct.MB_TCP_TxData[i]=MB_TCP_Struct.MB_MBAP_Data[i];
  67. }
  68. MB_TCP_Struct.MB_TCP_TxData[4]=((MB_TCP_Struct.MB_TxData_Len>>8)&0xff);
  69. MB_TCP_Struct.MB_TCP_TxData[5]=(MB_TCP_Struct.MB_TxData_Len&0xff);
  70. //--开始复制数据--
  71. for(i=0;i<MB_TCP_Struct.MB_TxData_Len-2;i++)
  72. {
  73. MB_TCP_Struct.MB_TCP_TxData[i+6]=MB_TCP_Struct.MB_TxData[i];
  74. }
  75. //--修改TCP的数据发送长度--需要减去CRC的数据--
  76. MB_TCP_Struct.MB_TCP_Tx_Len=MB_TCP_Struct.MB_TxData_Len+4;
  77. //--TCP 发送---
  78. netconn_write(newconn, MB_TCP_Struct.MB_TCP_TxData, MB_TCP_Struct.MB_TCP_Tx_Len, NETCONN_COPY);
  79. }
  80. else//--释放内存--
  81. {
  82. free(TCP_Data);
  83. }
  84. }


  85. }
  86. /* Close connection and discard connection identifier. */
  87. // netconn_close(newconn);
  88. // netconn_delete(newconn);
  89. }
  90. }
复制代码

通信现象:
1:没有使用Modbus-PULL 链接之前 Ping通没问题(不是都在1ms以内,不止是否有问题)偶尔ping的时间会比较长,但是从来没掉过包。
1-正常ping.png

2:使用Modbus-Pull链接,通信12次之后无法Ping通,
2P.png


无论是使用Modbus-Pull 还是开始说的只是来回发送数据都是这个样子,都是通信12次都没法在通信了,而且Ping也显示超时,请问格纹大佬,有遇到过这个问题么?还望大佬指教一二,小弟不胜感激!!!!!


收藏 评论13 发布时间:2019-1-28 10:01

举报

13个回答
fjasio 回答时间:2019-1-29 10:11:54
断开连接,然后释放内存 试试
fjasio 回答时间:2019-1-29 10:16:55
tcp连接有长连接和短连接:长连接的话,建立一次连接就行,以后只发送数据;短连接,每次数据发送完,都需要释放内存(控制块)

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

shenxiaolin_mai 回答时间:2019-1-30 11:36:01
fjasio 发表于 2019-1-29 10:16
tcp连接有长连接和短连接:长连接的话,建立一次连接就行,以后只发送数据;短连接,每次数据发送完,都需 ...

我是使用的长连接模式,建立连接之后就不再侦听端口了,然后就是每次读取完了之后我都释放了接受的缓存了的。但是还是这个样子,
fjasio 回答时间:2019-1-31 10:44:48
xiaoshen-372360 发表于 2019-1-30 11:36
我是使用的长连接模式,建立连接之后就不再侦听端口了,然后就是每次读取完了之后我都释放了接受的缓存了 ...

460189483,可以加到这个群问问,记得代码贴出来
shenxiaolin_mai 回答时间:2019-4-9 11:08:46
自己顶一下,还是没解决啊!!!
wofei1314 回答时间:2019-4-15 16:13:51
xiaoshen-372360 发表于 2019-4-9 11:08
自己顶一下,还是没解决啊!!!

自己移植的吗?(section(".RxDecripSection")有没有设置sct文件中对应的地方
shenxiaolin_mai 回答时间:2019-4-15 16:46:39
wofei1314 发表于 2019-4-15 16:13
自己移植的吗?(section(".RxDecripSection")有没有设置sct文件中对应的地方

这个只是移植了LWIP加RTOS系统的东西,也没有涉及到改SCT文件,除非你需要做IAP,需要修改Flash地址之外,还需要修改中断向量表对应的地址。
wofei1314 回答时间:2019-4-15 21:57:15
xiaoshen-372360 发表于 2019-4-15 16:46
这个只是移植了LWIP加RTOS系统的东西,也没有涉及到改SCT文件,除非你需要做IAP,需要修改Flash地址之外 ...
  1.   RW_IRAM2 0x24000000 0x00080000  {  ; RW data
  2.    .ANY (+RW +ZI)
  3.   }
  4.   RW_DMARxDscrTab 0x30040000 0x60 {
  5.   *(.RxDecripSection)
  6.   }
  7.   RW_DMATxDscrTab 0x30040060 0x140 {
  8.   *(.TxDecripSection)
  9.   }
  10.   RW_Rx_Buffb 0x30040200 0x1800 {
  11.   *(.RxArraySection)
  12.   }
复制代码

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

shenxiaolin_mai 回答时间:2019-4-16 09:01:09

这个是在C文件定义RAM空间导致的,ETH的接受和发送缓存都是在固定RAM地址区间进行的。
_whf 回答时间:2020-7-2 10:13:34
你好,我最近使用lwip协议栈碰到个问题想请教一下,lwip运行一段时间会进不去ETH中断,程序也是在运行的,跟楼主使用的环境差不多,,freertos1.6+lwip2.1,我复位lan8720芯片引脚没有用,wireshark抓包中间是没有断连现象的,最后却突然断掉连不上了,觉得应该是内存的问题,但不太清楚如何处理,求助,谢谢
shenxiaolin_mai 回答时间:2020-7-2 10:19:09
dreamtalewhf 发表于 2020-7-2 10:13
你好,我最近使用lwip协议栈碰到个问题想请教一下,lwip运行一段时间会进不去ETH中断,程序也是在运行的, ...

它们说的需要改lowlevelInput那个函数,你可以搜一下。
_whf 回答时间:2020-7-4 11:30:55
xiaoshen-372360 发表于 2020-7-2 10:19
它们说的需要改lowlevelInput那个函数,你可以搜一下。

感谢你的回复,重新移植了一套驱动,暂时测试没有问题,有时间在具体比对一下有哪些不同
_whf 回答时间:2020-7-8 11:38:56
dreamtalewhf 发表于 2020-7-2 10:13
你好,我最近使用lwip协议栈碰到个问题想请教一下,lwip运行一段时间会进不去ETH中断,程序也是在运行的, ...

问题原因是由于ETH中断优先级配置有问题

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版