本帖最后由 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状态寄存器存在以下问题
然后查了ST的参考手册,手册的解释是这样的,
尝试解决方法:
1:关于LWIP ethernetif_input 的问题,网上的解决方式已经尝试过了,这个地方也修改了,
- void ethernetif_input( void * pvParameters )
- {
- struct pbuf *p;
- for( ;; )
- {
- if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
- {
- TRY_GET_NEXT_FRAGMENT:
- p = low_level_input( s_pxNetIf );
- if(p!=NULL)
- {
- if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
- {
- pbuf_free(p);
- p=NULL;
- }
- else
- {
- xSemaphoreTake(s_xSemaphore,0);
- goto TRY_GET_NEXT_FRAGMENT;
- }
- }
- }
- }
- }
复制代码 主程序代码是这个样子的
- void Modbus_TCP_Tasks(void * pvParameters)
- {
- struct netconn *conn, *newconn;
- int i=0;
- err_t err, accept_err;
- struct netbuf *buf;
- void *data;
- u16_t len;
- unsigned char *tmpP=NULL;
- err_t recv_err;
- //--初始化---LWIP协议栈---
- ETH_BSP_Config();
- LwIP_Init();
- MB_TCP_Data_Init();//--协议栈初始化--
- // LWIP_UNUSED_ARG(arg);
- /* Create a new connection identifier. */
- conn = netconn_new(NETCONN_TCP);
- err = netconn_bind(conn, NULL, 502);
- netconn_listen(conn);
- accept_err = netconn_accept(conn, &newconn);
- netconn_delete(conn); //删除侦听的连接。
- while (1)
- {
- recv_err = netconn_recv(newconn, &buf);
- if ( recv_err == ERR_OK)
- {
- do
- {
- netbuf_data(buf, &data, &len);
- //--netconn_write(newconn, data, len, NETCONN_COPY);
- }
- while (netbuf_next(buf) >= 0);
- //--拷贝数计--以及数据长度
- for(i=0;buf->p!=NULL;buf->p=buf->p->next)//--非空则继续--
- {
- memcpy((unsigned char *)&TCP_Data[i],buf->p->payload,buf->p->len);
- i=i+buf->p->len;
- }
- netbuf_delete(buf);
- {
- //--正式开始处理Modbus-TCP 数据--
- if((TCP_Data[2]==0)&&(TCP_Data[3]==0))//--查看该数据帧是否为Modbus-TCP数据--
- {
- MB_TCP_Struct.MB_TCP_Rx_Len=len;//--获取数据长度--
- for(i=0;i<6;i++)
- {
- MB_TCP_Struct.MB_MBAP_Data[i]=TCP_Data[i];
- }
- //--开始数据拷贝的工作 拷贝的数据应当从第7个数据开始,
- for(i=0;i<(MB_TCP_Struct.MB_TCP_Rx_Len-6);i++)
- {
- MB_TCP_Struct.MB_RxData[i]=TCP_Data[i+6];
- }
- MB_TCP_Struct.MB_TCP_Rx_Len=i;
- //--开始计算CRC
- MB_TCP_Struct.CRC_Data=usMBCRC16(MB_TCP_Struct.MB_RxData,MB_TCP_Struct.MB_TCP_Rx_Len );
- MB_TCP_Struct.MB_RxData[MB_TCP_Struct.MB_TCP_Rx_Len] = (MB_TCP_Struct.CRC_Data&0xff);
- MB_TCP_Struct.MB_RxData[MB_TCP_Struct.MB_TCP_Rx_Len+1] = ((MB_TCP_Struct.CRC_Data>>8)&0xff);
- MB_TCP_Struct.MB_RxData_Len=MB_TCP_Struct.MB_TCP_Rx_Len+2;//--加上CRC的数据长度--
- MB_TCP_Process(&MB_TCP_Struct);
- //--然后完成TCP的组包工作---最后发送--需要消除CRC校验-2-
- //--待添加---
- //--填充TCP的MBAP数据--按照协议标准是需要直接复制前 4位
- for(i=0;i<6;i++)
- {
- MB_TCP_Struct.MB_TCP_TxData[i]=MB_TCP_Struct.MB_MBAP_Data[i];
- }
- MB_TCP_Struct.MB_TCP_TxData[4]=((MB_TCP_Struct.MB_TxData_Len>>8)&0xff);
- MB_TCP_Struct.MB_TCP_TxData[5]=(MB_TCP_Struct.MB_TxData_Len&0xff);
- //--开始复制数据--
- for(i=0;i<MB_TCP_Struct.MB_TxData_Len-2;i++)
- {
- MB_TCP_Struct.MB_TCP_TxData[i+6]=MB_TCP_Struct.MB_TxData[i];
- }
- //--修改TCP的数据发送长度--需要减去CRC的数据--
- MB_TCP_Struct.MB_TCP_Tx_Len=MB_TCP_Struct.MB_TxData_Len+4;
- //--TCP 发送---
- netconn_write(newconn, MB_TCP_Struct.MB_TCP_TxData, MB_TCP_Struct.MB_TCP_Tx_Len, NETCONN_COPY);
- }
- else//--释放内存--
- {
- free(TCP_Data);
- }
- }
- }
- /* Close connection and discard connection identifier. */
- // netconn_close(newconn);
- // netconn_delete(newconn);
- }
- }
复制代码
通信现象:
1:没有使用Modbus-PULL 链接之前 Ping通没问题(不是都在1ms以内,不止是否有问题)偶尔ping的时间会比较长,但是从来没掉过包。
2:使用Modbus-Pull链接,通信12次之后无法Ping通,
无论是使用Modbus-Pull 还是开始说的只是来回发送数据都是这个样子,都是通信12次都没法在通信了,而且Ping也显示超时,请问格纹大佬,有遇到过这个问题么?还望大佬指教一二,小弟不胜感激!!!!!
|
评分
查看全部评分
我是使用的长连接模式,建立连接之后就不再侦听端口了,然后就是每次读取完了之后我都释放了接受的缓存了的。但是还是这个样子,
460189483,可以加到这个群问问,记得代码贴出来
自己移植的吗?(section(".RxDecripSection")有没有设置sct文件中对应的地方
这个只是移植了LWIP加RTOS系统的东西,也没有涉及到改SCT文件,除非你需要做IAP,需要修改Flash地址之外,还需要修改中断向量表对应的地址。
评分
查看全部评分
这个是在C文件定义RAM空间导致的,ETH的接受和发送缓存都是在固定RAM地址区间进行的。