Code Monkey home page Code Monkey logo

wiznet's Issues

packages/wiznet-latest/src/wiz_af_inet.c:16:25: fatal error: sal_low_lvl.h: No such file or directory

使用了最新的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?

执行Ping命令的程序跑飞

我在配置好wiznet组件后,使用命令行测试ping命令时发现ping命令ping完一次就卡住,命令行也无响应,debug后发现报NMI_Handle
Snipaste_2021-06-10_16-11-45.png
研究下报错的地方发现是wiz_do_event_changes中的sock没有正常初始化
image.png
导致后续rt_wqueue_wakeup调用的时候程序跑飞
我在所有调用了wiz_do_event_changes添加了调试信息,输出如下:
image.png
大概可以判断,wiz_do_event_changes被调用之前socket被关闭了,sock变量也被置零,在调用wiz_do_event_changes之前的wiz_recv_notice_cb函数里,有个释放信号量的地方:
image.png
rt在执行rt_sem_release的时候会调用rt_schedule重新进行进程调度,而我的shell进程优先级比wiznet接收进程的优先级高:
image.png
这导致shell执行的ping命令会抢占,而ping命令执行后会有wiz_closesocket关闭socket,执行完后再回到wiznet的接收线程里执行wiz_do_event_changes就报错,wiz_do_event_changes没有预防socket被关闭的操作,也就容易导致程序跑飞
我参考AT_Socket的方法,在wiz_closesocket加以延时:
image.png
让wiz_do_event_changes在socket没被关闭前执行完,再执行ping命令就不报错了,算是简单解决了这个问题,但总感觉指标不治本

这个问题应该只会在shell进程优先级或者其他会执行closesocket的进程优先级大于wiz接收进程优先级的时候发生

编译错误,EAGAIN找不到定义

编译器:keil mdk default compiler version 5
报错信息:
packages\wiznet-latest\src\wiz_socket.c(1136): error: #20: identifier "EAGAIN" is undefined
见下图:
image

W5500前端没有路由器直接接网关会创建socket失败

系统都是静态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来操作吧?请问这个问题怎么解决,急急急

W5500+libmodbus系统不稳定,运行一段时间后断开就再也无法连接上了

1 RTT的SAL说明里面“目前 SAL 组件支持的协议栈或网络实现类型有:lwIP 协议栈、AT Socket 协议栈、WIZnet 硬件 TCP/IP 协议栈。”,但是关于怎么具体对接没有说明。
2 经过自己一些痛苦摸索,程序可以进行mdobusTCP采集,但过一段时间就出现无法再连接上。各种方法都试了还不行,和libmodbus作者也沟通了,人家说人家的系统已经跑了几个月了没任何问题。
3 那么这块究竟是什么问题?希望wiznet软件包作者看到能沟通一下,不然这个项目真要黄了,项目进入小批,发现这个大一个bug,真不知道该咋弄了,看到请联系我,谢谢18100336192或2730122869

socket创建必须要物理link up

问题:
当在创建socket时,wiz_socket函数会去调用WIZ_INIT_STATUS_CHECK来检查物理上是否link up,并且accept函数里面也是,这就导致我不插网线时,无法创建socket。这种做法不符合通用的使用方法。

环境:
RT-Thread Studio 2.1.2
wiznet latest

当发送数据超过发送缓存 应分包发送保证所有数据发送出去

if (len > freesize) len = freesize; // check size not to exceed MAX size.

建议写成循环分包发送 比如用户要发送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. 超过了缓存大小就分包发送

引脚中断回调没有被执行

在执行ping指令后,从启动到send都正常,只有在recv的时候,因为收不到中断回调,导致获取信号量失败,超时退出。这个你们有遇到过吗,怎么解决呢

wiz_socket函数封装有问题

wiz_socket函数中,调用
if (wizchip_socket(sock->socket, sock->type, wiz_port++, Sn_MR_ND) != sock->socket)
该函数生成W5500实际可用的socket,如果作为TCP服务器,accept的时候会又分配一个W5500实际可用的socket,这两个socket就冲突了。

read收数据时会导致线程一直执行

问题:
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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.