sync
sync
This guy hasn't written anything yet

注册于 3 years ago

回答
151
文章
3
关注者
3

    本帖最后由 sync 于 2019-7-29 11:06 编辑


直接下载使用ENV配置后,keil工程下不会自己加入对应的网口eth的驱动文件,需要自己手动加入下,就ok了------------
我用的stm32f407-st-discovery目录下文件,没注意到楼主用的目录和我的不一样,有可能不是这个原因了

给自己的帖子 结个尾,上面的程序后面仍然工作不稳定,因工作原因,放置了好久了。
这几天有空重新下载了RtThread 后,重新测试这个tcpserv发现比之前运行好多了,对比文件发现,bsp\stm32\libraries\HAL_Drivers\drv_eth.c 文件更新过,之前
程序网口只能握手10Mbps还是半双工
[D/drv.emac] link up
[D/drv.emac] 10Mbps
[D/drv.emac] half-duplex
现在状态正常了如下:
[D/drv.emac] link up
[D/drv.emac] 100Mbps
[D/drv.emac] full-duplex
目前长时间测试tcpserv未发现线程有死机情况:)

关注下 ,也求个lwip 和rtt 能长时间稳定运行的例子

支持下,本来使用RT-Thread是因为,扩展插件多,结果里面还是有好多坑要跳,比自己用裸机跑省不了多少时间:(

小ARM菜菜 发表于 2015-5-30 22:43
我把TCPIP线程和网络的应用线程的优先级调整后OK。
这个问题可能就是之前有人说的TCPIP线程挂起在op_comple ...


我也遇到tcpip线程超时挂起问题,挂起后不会再继续执行,导致erx接收的数据,不停的申请内存,最后就是tcpip_inpkt函数里面的
 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
这句会申请内存失败
因为tcpip线程始终无法执行。
不知道如何处理了。。。。

    本帖最后由 sync 于 2019-2-27 17:01 编辑


删除重复信息

    本帖最后由 sync 于 2019-2-27 17:01 编辑


调试中发现eth_rx_thread_entry函数里面,判断接收到邮箱eth_rx_thread_mb以后,p仍然是null呢?
1551257604(1).png

串口打印信息如下:
rtx_mb_ok:0
r_p :Null
rtx_mb_ok:0
r_p :Null
rtx_mb_ok:0
r_p :Null
rtx_mb_ok:0
rtx: S_m_Ok // 注释:这个信息是device->netif->input(p, device->netif)打印出来的
r_p :Null
rtx_mb_ok:0
ethernetif_input: Input error
ethernetif_input: Input error
ethernetif_input: Input error
ethernetif_input: Input error
ethernetif_input: Input error
偶然性的一次,不影响通讯,如果像上面连续几次,就会出现故障,造成tcpserv通讯异常,无法ping通了

独角戏 发表于 2019-2-26 23:09
我用的是bsp/stm32/libraries/templates/stm32f10x的bsp,应该是新的吧
再说,这个问题和bsp没关系吧,主 ...


问题没有解决,自己对lwip也不是很熟悉,tcpserv只要是长时间测试,都会出现问题,我感觉是办公室路由器的问题,正常测试下,我发的数据包都不大,200ms数据发送间隔应该问题。出问题时,f407网口应该接收了比较多的数据,这个应该是路由器发的。

eth接收函数,之前裸机下 执行的是 HAL_ETH_GetReceivedFrame,RTT下使用中断,执行的是 HAL_ETH_GetReceivedFrame_IT(&EthHandle);
另外就是rtt使用了接收线程,根据邮箱来读取eth数据,
暂时测试发现LOG_D("receive frame faild")的原因是EthHandle.RxDesc.Status中的ETH_DMARXDESC_OWN一直为1.
年后再继续调了,暂时就到这里,多谢大家了

zhifou 发表于 2019-1-30 11:50
这种是否先找个完全已有BSP的开发板来验证比较好些?


不同开发板使用的驱动都是rt-thread-master\bsp\stm32\libraries\HAL_Drivers目录下的,使用的是同一个文件了,目前测试的情况是不稳定,也不是不能工作,很郁闷了。。。

    本帖最后由 sync 于 2019-1-30 11:35 编辑


rt_stm32_eth_rx里面的
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
这句话是啥意思呢?我将其注销掉的话,会有其他影响吗?
注销掉就没再发生receive frame faild错了。
    for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
{
// dmarxdesc->Status |= ETH_DMARXDESC_OWN;
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
}
注销掉,会有另外的错误
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 60
ethernetif_input: Input error
[D/drv.emac] receive frame len : 60
ethernetif_input: Input error
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 60
ethernetif_input: Input error
[D/drv.emac] receive frame len : 60
ethernetif_input: Input error
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 342
ethernetif_input: Input error
[D/drv.emac] receive frame len : 60
ethernetif_input: Input error





    本帖最后由 sync 于 2019-1-30 11:19 编辑


使用的drv_eth.c的版本
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-19 SummerGift first version
* 2018-12-25 zylx fix some bugs
*/

#include "board.h"
#include "drv_config.h"
#include
#include "lwipopts.h"
#include "drv_eth.h"
问题应该就 出在rt_stm32_eth_rx函数里面
struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
{

struct pbuf *p = NULL;
struct pbuf *q = NULL;
HAL_StatusTypeDef state;
uint16_t len = 0;
uint8_t *buffer;
__IO ETH_DMADescTypeDef *dmarxdesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i = 0;

/* Get received frame */
state = HAL_ETH_GetReceivedFrame_IT(&EthHandle);
if (state != HAL_OK)
{
printf("state = %d\r\n",state);
LOG_D("receive frame faild");
return NULL;
}

/* Obtain the size of the packet and put it into the "len" variable. */
len = EthHandle.RxFrameInfos.length;
buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;

LOG_D("receive frame len : %d", len);

if (len > 0)
{
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}

#ifdef ETH_RX_DUMP
dump_hex(buffer, p->tot_len);
#endif

if (p != NULL)
{
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
bufferoffset = 0;
for (q = p; q != NULL; q = q->next)
{
byteslefttocopy = q->len;
payloadoffset = 0;

/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
{
/* Copy data to pbuf */
memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));

/* Point to next descriptor */
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);

byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
memcpy((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
}
}

/* Release descriptors to DMA */
/* Point to first descriptor */
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
{
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
}

/* Clear Segment_Count */
EthHandle.RxFrameInfos.SegCount = 0;

/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
EthHandle.Instance->DMARPDR = 0;
}

return p;
}




调试发现每次发生 LOG_D("receive frame faild");错误的时候
HAL_ETH_GetReceivedFrame_IT中的heth->RxDesc->Status状态是 0x80400320
也就是((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) 不成立

使用的bsp目录是rt-thread-master\bsp\stm32\stm32f4xx RT-Thread版本是 4.0.0 build Jan 29 2019

    本帖最后由 sync 于 2019-1-30 10:00 编辑


这次只开机,只有默认线程,
thread   pri  status      sp     stack size max used left tick  error
-------- --- ------- ---------- ---------- ------ ---------- ---
tshell 20 running 0x00000084 0x00001000 12% 0x00000008 000
phy 30 suspend 0x00000094 0x00000400 21% 0x00000001 000
tcpip 10 suspend 0x000000c4 0x00000400 59% 0x00000001 000
etx 12 suspend 0x00000098 0x00000400 23% 0x0000000c 000
erx 12 suspend 0x00000098 0x00000400 56% 0x00000005 000
tidle0 31 ready 0x00000058 0x00000100 34% 0x00000012 000
main 10 suspend 0x00000094 0x00000800 34% 0x00000011 000

的情况下就会出现错误:receive frame faild
使用的是8720接口芯片
 \ | /
- RT - Thread Operating System
/ | \ 4.0.0 build Jan 29 2019
2006 - 2018 Copyright by rt-thread team
lwIP-2.0.2 initialized!
[D/drv.emac] initialize tx wait semaphore
netif: IP address of interface e0 set to 0.0.0.0
netif: netmask of interface e0 set to 0.0.0.0
netif: GW address of interface e0 set to 0.0.0.0
[D/drv.emac] eth hardware init success
[D/drv.emac] emac hardware start
netif: setting default interface e0
[D/drv.emac] transmit frame lenth :350
netif: added interface e0 IP addr 0.0.0.0 netmask 0.0.0.0 gw 0.0.0.0
[D/drv.emac] emac device init success
msh >[D/drv.emac] found a phy, address:0x00
[D/drv.emac] RESET PHY!
CPU : 0.0
[D/drv.emac] transmit frame lenth :350
CPU : 0.0
[D/drv.emac] PHY BASIC STATUS REG:0x7809
CPU : 0.6
[D/drv.emac] PHY BASIC STATUS REG:0x7809
CPU : 0.6
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
[D/drv.emac] link up
[D/drv.emac] 10Mbps
[D/drv.emac] half-duplex
[D/drv.emac] transmit frame lenth :350
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame len : 342
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] transmit frame lenth :350
[D/drv.emac] receive frame len : 342
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] transmit frame lenth :42
[D/drv.emac] transmit frame lenth :42
[D/drv.emac] transmit frame lenth :42
netif: netmask of interface e0 set to 255.255.255.0
netif: GW address of interface e0 set to 192.168.1.1
netif_set_ipaddr: netif address being changed
[D/drv.emac] transmit frame lenth :42
netif: IP address of interface e0 set to 192.168.1.95
CPU : 5.96
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
[D/drv.emac] transmit frame lenth :42
CPU : 0.36
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] transmit frame lenth :42
CPU : 0.0
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
[D/drv.emac] transmit frame lenth :42
CPU : 0.6
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
CPU : 0.0
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
CPU : 0.6
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
CPU : 0.6
[D/drv.emac] PHY BASIC STATUS REG:0x782D
[D/drv.emac] PHY Control/Status REG:0x0000
CPU : 0.0
而且有时,会连续出现错误RX err = -3,表示邮箱已满。



tcpip_thread: PACKET 2000280c
[D/drv.emac[E/drv.emac] RX err = -3
c]receive frame len : 60
t[E/drv.emac] RX err = -3
[0m
= -3emac] T 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2[E/drv.emac] RX err = -3
000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: [E/drv.emac] RX err = -3
ac] T 2000280c
[D/drv.emac] receive frame len : 60
tcpip[E/drv.emac] RX err = -3
= -3emac] T 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2[E/drv.emac] RX err = -3
000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_threa[E/drv.emac] RX err = -3
emac] T 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread[E/drv.emac] RX err = -3
emac] T 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
me faild 2000280c

[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame faild
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c
[D/drv.emac] receive frame len : 60
tcpip_thread: PACKET 2000280c

但正常时,邮箱使用如下:
mailbox entry size suspend thread
-------- ---- ---- --------------
mbox0 0000 0016 1:tcpip
etxmb 0000 0016 1:etx
erxmb 0000 0016 1:erx

ifconfig 如下:
network interface: e0 (Default)
MTU: 1500
MAC: 00 80 e1 07 33 47
FLAGS: UP LINK_UP ETHARP BROADCAST IGMP
ip address: 192.168.1.95
gw address: 192.168.1.1
net mask : 255.255.255.0
dns server #0: 192.168.1.1
dns server #1: 192.168.1.1
插上网线每次都是10M,半双工模式。。。
[D/drv.emac] link up
[D/drv.emac] 10Mbps
[D/drv.emac] half-duplex



    本帖最后由 sync 于 2019-1-29 17:05 编辑


lwip版本更换成2.1后也是一样的现象。。。。。
使用的程序就是这个例子https://www.rt-thread.org/docume ... cpserver/tcpserver/


我把tcp客户端数据的发送间隔调整为500ms。运行了快一个小时,又死了。。。
程序中就开一个5000端口,为啥会这样呢,数据量又不大。。。

基本每次都是连续工作半小时左右就死机了。。
这次打开NETIF_DEBUG后
能看到一个ethernetif_input: Input error 错误

lwip_recvfrom: netconn_recv err=0, netbuf=20009ccc
lwip_recvfrom: buflen=174 len=1024 off=0 sock->lastoffset=0
lwip_recvfrom(1): addr=192.168.1.141 port=49401 len=174
lwip_recvfrom: deleting netbuf=20009ccc
rlen = 1689192 ,16496
lwip_send(1, data=08020a5c, size=34, flags=0x0)
lwip_send(1) err=0 written=34
lwip_recvfrom(1, 20010d24, 1024, 0x0, ..)
lwip_recvfrom: top while sock->lastdata=00000000
tcpip_thread: PACKET 20002808
tcpip_thread: PACKET 20002808
lwip_recvfrom: netconn_recv err=0, netbuf=20009ccc
lwip_recvfrom: buflen=174 len=1024 off=0 sock->lastoffset=0
lwip_recvfrom(1): addr=192.168.1.141 port=49401 len=174
lwip_recvfrom: deleting netbuf=20009ccc
rlen = 1689366 ,16497
lwip_send(1, data=08020a5c, size=34, flags=0x0)
lwip_send(1) err=0 written=34
lwip_recvfrom(1, 20010d24, 1024, 0x0, ..)
lwip_recvfrom: top while sock->lastdata=00000000
tcpip_thread: PACKET 20002808
tcpip_thread: PACKET 20002808
lwip_recvfrom: netconn_recv err=0, netbuf=20009ccc
lwip_recvfrom: buflen=174 len=1024 off=0 sock->lastoffset=0
lwip_recvfrom(1): addr=192.168.1.141 port=49401 len=174
lwip_recvfrom: deleting netbuf=20009ccc
rlen = 1689540 ,16499
lwip_send(1, data=08020a5c, size=34, flags=0x0)
lwip_send(1) err=0 written=34
lwip_recvfrom(1, 20010d24, 1024, 0x0, ..)
lwip_recvfrom: top while sock->lastdata=00000000
tcpip_thread: PACKET 20002808
CPU : 0.0
CPU : 0.0
CPU : 0.60
CPU : 0.0
CPU : 0.0
CPU : 0.6
CPU : 0.0
CPU : 0.0
ethernetif_input: Input error
CPU : 0.6
CPU : 0.0
ethernetif_input: Input error
ethernetif_input: Input error
CPU : 0.0
ethernetif_input: Input error
CPU : 5.29
CPU : 0.6
CPU : 0.0

rtt版本 和bsp都是前几天刚下载的。
\ | /
- RT - Thread Operating System
/ | \ 4.0.0 build Jan 29 2019
2006 - 2018 Copyright by rt-thread team
lwIP-2.0.2 initialized!


开机线程如下:

thread pri status sp stack size max used left tick error
-------- --- ------- ---------- ---------- ------ ---------- ---
tshell 20 running 0x00000084 0x00001000 12% 0x00000003 000
phy 30 suspend 0x00000094 0x00000400 19% 0x00000002 000
tcpip 10 suspend 0x000000c4 0x00000400 59% 0x0000000c 000
etx 12 suspend 0x00000094 0x00000400 14% 0x0000000f 000
erx 12 suspend 0x00000094 0x00000400 55% 0x0000000c 000
tidle0 31 ready 0x00000054 0x00000100 32% 0x00000012 000
main 10 suspend 0x00000094 0x00000800 34% 0x0000000e 000

这问题应该是底层驱动问题吧?最终错误发生在 erx接收线程中。

死机后,拔下网线仍能出现link down ,插上网线就又出现错误ethernetif_input: Input error
ethernetif_input: Input error
CPU : 0.0
CPU : 0.6
CPU : 0.0
CPU : 0.0
CPU : 0.0
[I/drv.emac] link down
CPU : 0.0
CPU : 0.6
CPU : 0.0
CPU : 0.6
CPU : 0.0
ethernetif_input: Input error
CPU : 0.0
CPU : 0.0
CPU : 0.0
CPU : 0.0
CPU : 0.0
ethernetif_input: Input error
ethernetif_input: Input error
CPU : 0.0
ethernetif_input: Input error
ethernetif_input: Input error
CPU : 0.0
[I/drv.emac] link down
CPU : 0.0
CPU : 0.0
CPU : 0.6
CPU : 0.0
CPU : 0.6
CPU : 0.0
CPU : 0.6
CPU : 0.0
ethernetif_input: Input error
ethernetif_input: Input error
ethernetif_input: Input error

回到
顶部

发布
问题

投诉
建议