rt-thread-packages / wiznet Goto Github PK
View Code? Open in Web Editor NEWWIZnet TCP/IP chips (such as W5500/W5100..) SAL framework implement.
License: Apache License 2.0
WIZnet TCP/IP chips (such as W5500/W5100..) SAL framework implement.
License: Apache License 2.0
wizchip_socket.c 中的ctlsocket
应该改成wizchip_ctlsocket
使用了最新的RT-thread 4.1.0系统,总是报错如上。请教两个问题:
1.不清楚最新的wiznet2.0.0的代码中修改的头文件部分
#ifdef RT_USING_SAL
#include <sal_netdb.h>
#include <sal_low_lvl.h>
#endif /* RT_USING_SAL */
增加的sal_low_lvl.h
文件在哪里?在rt-thread studio软件中添加软件包后无法自动下载下来,且wiznet2.0.0的代码中也么有这个。
2.咱们更新记录中说的适配5.0.0,是指适配什么组件的5.0.0?
目前的wiznet没有适配 tcp server是吗?
我在配置好wiznet组件后,使用命令行测试ping命令时发现ping命令ping完一次就卡住,命令行也无响应,debug后发现报NMI_Handle
研究下报错的地方发现是wiz_do_event_changes中的sock没有正常初始化
导致后续rt_wqueue_wakeup调用的时候程序跑飞
我在所有调用了wiz_do_event_changes添加了调试信息,输出如下:
大概可以判断,wiz_do_event_changes被调用之前socket被关闭了,sock变量也被置零,在调用wiz_do_event_changes之前的wiz_recv_notice_cb函数里,有个释放信号量的地方:
rt在执行rt_sem_release的时候会调用rt_schedule重新进行进程调度,而我的shell进程优先级比wiznet接收进程的优先级高:
这导致shell执行的ping命令会抢占,而ping命令执行后会有wiz_closesocket关闭socket,执行完后再回到wiznet的接收线程里执行wiz_do_event_changes就报错,wiz_do_event_changes没有预防socket被关闭的操作,也就容易导致程序跑飞
我参考AT_Socket的方法,在wiz_closesocket加以延时:
让wiz_do_event_changes在socket没被关闭前执行完,再执行ping命令就不报错了,算是简单解决了这个问题,但总感觉指标不治本
这个问题应该只会在shell进程优先级或者其他会执行closesocket的进程优先级大于wiz接收进程优先级的时候发生
比如发生“WIZnet recvfrom failed, get socket(%d) register state(%d) error.”和“WIZnet recvfrom input data or length error!”等错误都是返回-1。
系统都是静态IP方式:
1.1 如果接到路由器上或者路由器带的交换机上系统没有问题,wiz_socket.c中的wiz_socket函数中的socket_state = getSn_SR(sock->socket)正常为0;
1.2但如果直接接交换机上则创建socket会失败,跟踪发现socket_state =0x22,所以会-1返回,查手册ox22是socket_udp,此时按udp放行可以发送udp信息;但是tcp因0x22会一直失败。
在不接路由只接交换机的情况下:
2.1 如果按照:拔掉网线->上电->插入网线,则系统先失败后自动恢复正常;
2.2 如果按照:插入网线->上电->拔掉网线->再插入网线,则系统始终失败
万一中间断电,我总不能一根根去按1来操作吧?请问这个问题怎么解决,急急急
1 RTT的SAL说明里面“目前 SAL 组件支持的协议栈或网络实现类型有:lwIP 协议栈、AT Socket 协议栈、WIZnet 硬件 TCP/IP 协议栈。”,但是关于怎么具体对接没有说明。
2 经过自己一些痛苦摸索,程序可以进行mdobusTCP采集,但过一段时间就出现无法再连接上。各种方法都试了还不行,和libmodbus作者也沟通了,人家说人家的系统已经跑了几个月了没任何问题。
3 那么这块究竟是什么问题?希望wiznet软件包作者看到能沟通一下,不然这个项目真要黄了,项目进入小批,发现这个大一个bug,真不知道该咋弄了,看到请联系我,谢谢18100336192或2730122869
问题:
当在创建socket时,wiz_socket函数会去调用WIZ_INIT_STATUS_CHECK来检查物理上是否link up,并且accept函数里面也是,这就导致我不插网线时,无法创建socket。这种做法不符合通用的使用方法。
环境:
RT-Thread Studio 2.1.2
wiznet latest
测试的时候发现调用select函数会导致系统崩溃,要如何解决这个问题?非常感谢!!
wiznet/ioLibrary/Ethernet/wizchip_socket.c
Line 533 in 6cf871a
建议写成循环分包发送 比如用户要发送5k数据 那么分三包发送 2K 2K 1K 这样顶层api调用才不会出问题,WEBNET顶层发送数据缓存4k 调用该wiznet 数据发送API时永远发送不成功 浏览器等待后续的数据导致卡死
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size. 超过了缓存大小就分包发送
希望能修复加入工程后的错误和在使用 sscanf 函数时的警告。
在执行ping指令后,从启动到send都正常,只有在recv的时候,因为收不到中断回调,导致获取信号量失败,超时退出。这个你们有遇到过吗,怎么解决呢
我在应用中发现,当我应用检测到网线被拔掉之后,我调用wiz_closesocket去关闭被打开的端口,发现无法关闭,导致重插网线后连接异常的问题出现,目前的解决办法是注释掉WIZ_INIT_STATUS_CHECK,但不知会不会引发其他异常
Hi
Could you add SO_REUSEADDR on wiz_setsockopt?
Regards
wizchip_socket.c
int8_t wizchip_connect(uint8_t sn, uint8_t * addr, uint16_t port)之中
while (getSn_SR(sn) != SOCK_ESTABLISHED)
{
if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT;
}
if (getSn_SR(sn) == SOCK_CLOSED)
{
return SOCKERR_SOCKCLOSED;
}
}
我仔细看了Wiznet的源码,没有发现源码使用rt_spi_bus_attach_device()函数将W5500挂载至SPI总线上,请问程序是如何实现挂载的?或者就没有挂载,要用户自己挂载?谢谢!
wiz_socket函数中,调用
if (wizchip_socket(sock->socket, sock->type, wiz_port++, Sn_MR_ND) != sock->socket)
该函数生成W5500实际可用的socket,如果作为TCP服务器,accept的时候会又分配一个W5500实际可用的socket,这两个socket就冲突了。
问题:
TCP通信,当使用单独的线程去收数据时,并且线程里只使用read函数,不使用select函数配合,代码如下:
while (1)
{
ret = read(sock, buf, 64);
if (ret <= 0)
{
break;
}
rt_ringbuffer_put(rx_ring_buf, buf, ret);
}
如果此时对方只发了一次数据,那么线程会一直执行,不会阻塞,导致低优先级线程无法调度。
原因是wiz_recvfrom函数里面有这样一段代码,
uint16_t recvsize = getSn_RX_RSR(socket);
/* receive last transmission of remaining data */
if (recvsize > 0)
{
rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
recv_len = wizchip_recv(socket, mem, len);
if (recv_len > 0)
{
rt_mutex_release(sock->recv_lock);
goto __exit;
}
rt_mutex_release(sock->recv_lock);
}
if (socket_state == SOCK_CLOSED)
{
return 0;
}
else if (socket_state != SOCK_ESTABLISHED)
{
LOG_E("WIZnet receive failed, get socket(%d) register state(%d) error.", socket, socket_state);
result = -1;
goto __exit;
}
while (1)
{
/* wait the receive semaphore */
if (rt_sem_take(sock->recv_notice, timeout) < 0)
{
result = -1;
/* blocking mode will prints an error and non-blocking mode exits directly */
if ((flags & MSG_DONTWAIT) == 0)
{
LOG_E("WIZnet socket (%d) receive timeout (%d)!", socket, timeout);
errno = EAGAIN;
}
goto __exit;
}
else
{
if (sock->state == SOCK_ESTABLISHED)
{
/* get receive buffer to receiver ring buffer */
rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
recv_len = wizchip_recv(socket, mem, len);
if (recv_len < 0)
{
LOG_E("WIZnet socket(%d) receive data failed(%d).", socket, recv_len);
rt_mutex_release(sock->recv_lock);
result = -1;
goto __exit;
}
rt_mutex_release(sock->recv_lock);
}
else if (sock->state == SOCK_CLOSED)
{
result = 0;
goto __exit;
}
break;
}
}
break;
}
这段代码先通过getSn_RX_RSR判断是否有数据,有的话就返回,这就导致第二次read时,getSn_RX_RSR判断到无数据,就到下面的 if (rt_sem_take(sock->recv_notice, timeout) < 0)这,因为这里信号量已经在中断里面释放过了,所以这里是不会阻塞的,从而进入到wizchip_recv函数,而这个函数里面就一直在判断getSn_RX_RSR是否有数,因为对端只发了一次,第一次已经读走了,因此getSn_RX_RSR一直返回0,从而形成无阻赛的死循环。
所以wiz_recvfrom函数应该改进,通过注释(/* receive last transmission of remaining data */)可以看出,是否防止数据读不干净,而这样做的。那么为啥不在wizchip_recv执行完后,再去判断getSn_RX_RSR是否有数,如果有,再释放一次信号量即可
环境:
RT-Thread Studio 2.1.2
wiznet latest
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.