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

关于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也显示超时,请问格纹大佬,有遇到过这个问题么?还望大佬指教一二,小弟不胜感激!!!!!


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

举报

17个回答
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

查看全部评分

_whf 回答时间:2020-7-2 10:13:34
你好,我最近使用lwip协议栈碰到个问题想请教一下,lwip运行一段时间会进不去ETH中断,程序也是在运行的,跟楼主使用的环境差不多,,freertos1.6+lwip2.1,我复位lan8720芯片引脚没有用,wireshark抓包中间是没有断连现象的,最后却突然断掉连不上了,觉得应该是内存的问题,但不太清楚如何处理,求助,谢谢
shenxiaolin_mai 回答时间:2019-1-30 11:36:01
fjasio 发表于 2019-1-29 10:16
tcp连接有长连接和短连接:长连接的话,建立一次连接就行,以后只发送数据;短连接,每次数据发送完,都需 ...

我是使用的长连接模式,建立连接之后就不再侦听端口了,然后就是每次读取完了之后我都释放了接受的缓存了的。但是还是这个样子,
fjasio 回答时间:2019-1-29 10:11:54
断开连接,然后释放内存 试试
fjasio 回答时间:2019-1-29 10:16:55
tcp连接有长连接和短连接:长连接的话,建立一次连接就行,以后只发送数据;短连接,每次数据发送完,都需要释放内存(控制块)

评分

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

查看全部评分

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地址之外,还需要修改中断向量表对应的地址。
shenxiaolin_mai 回答时间:2019-4-16 09:01:09

这个是在C文件定义RAM空间导致的,ETH的接受和发送缓存都是在固定RAM地址区间进行的。
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中断优先级配置有问题
lb852 回答时间:2024-7-19 14:49:44
_whf 发表于 2020-7-8 11:38
问题原因是由于ETH中断优先级配置有问题

请问您是怎么更改的优先级呢?我现在出现的问题跟您一样,正常跑着突然ETH中断就进不去了
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版