Ryan-CW 3 лет назад
Родитель
Сommit
0ebf817ecb

+ 21 - 39
W5500Client/RyanW5500.c

@@ -16,27 +16,9 @@ void RyanW5500IRQCallback(void *argument)
     rt_event_send(RyanW5500Entry.W5500EventHandle, RyanW5500IRQBit);
 }
 
-/**
- * @brief 获取当前SPI总线资源
- *
- */
-void RyanW5500CriticalEnter(void)
-{
-    rt_mutex_take(RyanW5500Entry.W5500SpiMutexHandle, RT_WAITING_FOREVER);
-}
-
-/**
- * @brief 释放当前SPI总线资源
- *
- */
-void RyanW5500CriticalExit(void)
-{
-    rt_mutex_release(RyanW5500Entry.W5500SpiMutexHandle);
-}
-
 void RyanW5500NetDevInfoUpdate(struct netdev *netdev)
 {
-    uint8_t linkState;
+    uint8_t linkState = 0;
     wiz_NetInfo netinfo = {0};
     ctlnetwork(CN_GET_NETINFO, (void *)&netinfo);                                // 获取网络信息
     netdev_low_level_set_ipaddr(netdev, (const ip_addr_t *)&netinfo.ip);         // 设置网络接口设备 IP 地址。
@@ -45,10 +27,10 @@ void RyanW5500NetDevInfoUpdate(struct netdev *netdev)
     netdev_low_level_set_dns_server(netdev, 0, (const ip_addr_t *)&netinfo.dns); // 设置网络接口设备DNS服务器地址
     memcpy(netdev->hwaddr, (const void *)&netinfo.mac, netdev->hwaddr_len);      // 设置mac地址
 
-    netdev_low_level_set_dhcp_status(netdev, (gWIZNETINFO.dhcp == NETINFO_DHCP) ? RT_TRUE : RT_FALSE);
+    netdev_low_level_set_dhcp_status(netdev, (NETINFO_DHCP == gWIZNETINFO.dhcp) ? RT_TRUE : RT_FALSE);
 
     ctlwizchip(CW_GET_PHYLINK, &linkState);
-    netdev_low_level_set_link_status(netdev, PHY_LINK_ON == linkState ? RT_TRUE : RT_FALSE);
+    netdev_low_level_set_link_status(netdev, (PHY_LINK_ON == linkState) ? RT_TRUE : RT_FALSE);
 }
 
 /**
@@ -141,7 +123,7 @@ next:
         ctlwizchip(CW_GET_PHYLINK, &linkState);
         if (PHY_LINK_ON == linkState)
             break;
-        delay(20);
+        delay(10);
     }
 
     RyanW5500NetDevInfoUpdate(netdev);
@@ -191,13 +173,14 @@ static void wizIntDataTask(void *parameter)
 
         while (1)
         {
+            intr = 0;
             ctlwizchip(CW_GET_INTERRUPT, (void *)&intr);
             ir = (uint8_t)intr;
             sir = (uint8_t)(intr >> 8);
 
             setIR(ir); // 没有使用IR中断,保险起见进行清空
 
-            if (0 == sir)
+            if (0 == sir) // 所有socket都没有中断就退出循环
                 break;
 
             for (uint8_t socket = 0; socket < RyanW5500MaxSocketNum; socket++)
@@ -207,6 +190,7 @@ static void wizIntDataTask(void *parameter)
 
                 // setSIR(socket); // 清除当前socket中断  setSn_IR时w5500内部会自动清除
                 // Sn_IR_SENDOK Sn_IR_TIMEOUT wiz官方库有使用,这里不使用
+                sn_ir = 0;
                 sn_ir = getSn_IR(socket);         // 获取中断类型消息
                 setSn_IR(socket, RyanW5500SnIMR); // 清除中断类型消息
 
@@ -225,15 +209,15 @@ static void wizIntDataTask(void *parameter)
                 if (sn_ir & Sn_IR_CON) // 成功与对方建立连接
                 {
                     LOG_D("连接成功");
-                    RyanW5500Socket *sock = RyanW5500GetSock(socket);
-                    if (-1 == sock->serviceSocket)
+                    RyanW5500Socket *clientSock = RyanW5500GetSock(socket);
+                    if (-1 == clientSock->serviceSocket)
                         continue;
 
-                    RyanW5500Socket *serviceSock = RyanW5500GetSock(sock->serviceSocket);
-                    if (RyanW5500SocketListen != serviceSock->state || sock->port != serviceSock->port)
+                    RyanW5500Socket *serviceSock = RyanW5500GetSock(clientSock->serviceSocket);
+                    if (RyanW5500SocketListen != serviceSock->state || clientSock->port != serviceSock->port)
                         continue;
 
-                    RyanListenServiceAddClient(serviceSock, sock);
+                    RyanListenServiceAddClient(serviceSock, clientSock);
                 }
             }
         }
@@ -248,7 +232,6 @@ static void wizIntDataTask(void *parameter)
  */
 int RyanW5500Init(wiz_NetInfo *netInfo)
 {
-
     struct netdev *netdev = NULL;
     memcpy(&gWIZNETINFO, netInfo, sizeof(wiz_NetInfo));
     memset(&RyanW5500Entry, 0, sizeof(RyanW5500Entry));
@@ -261,24 +244,23 @@ int RyanW5500Init(wiz_NetInfo *netInfo)
 
     RyanW5500Reset(); // 重启w5500
 
-    RyanW5500Entry.W5500SpiMutexHandle = rt_mutex_create("RyanW5500SpiMutex", RT_IPC_FLAG_FIFO);
     RyanW5500Entry.socketMutexHandle = rt_mutex_create("RyanW5500SocketMutex", RT_IPC_FLAG_FIFO);
     RyanW5500Entry.W5500EventHandle = rt_event_create("RyanW5500Event", RT_IPC_FLAG_PRIO);
     RyanW5500AttachIRQ(RyanW5500IRQCallback); // 绑定w5500中断回调函数
 
-    // 超时中断触发为retry_cnt * time_100us * 100us
-    struct wiz_NetTimeout_t net_timeout = {
-        .retry_cnt = 5,      // 重试次数
-        .time_100us = 2000}; // 200ms认为失败
-    ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout);
-
     // 检查w5500连接是否正常
-    memset(&net_timeout, 0, sizeof(struct wiz_NetTimeout_t));
-
     while (1)
     {
+        // 超时中断触发为retry_cnt * time_100us * 100us
+        struct wiz_NetTimeout_t net_timeout = {
+            .retry_cnt = 5,      // 重试次数
+            .time_100us = 2000}; // 200ms认为失败
+        ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout);
+
+        memset(&net_timeout, 0, sizeof(struct wiz_NetTimeout_t));
+
         ctlnetwork(CN_GET_TIMEOUT, (void *)&net_timeout);
-        if (0 != net_timeout.retry_cnt || 0 != net_timeout.time_100us)
+        if (5 == net_timeout.retry_cnt && 2000 == net_timeout.time_100us)
             break;
 
         LOG_E("Wiznet chip not detected");

+ 15 - 11
W5500Client/RyanW5500Ping.c

@@ -37,8 +37,11 @@ struct wiz_ping_msg
  */
 static uint16_t wiz_checksum(uint8_t *src, uint32_t len)
 {
-    uint16_t sum, tsum, i, j;
-    uint32_t lsum;
+    uint16_t sum = 0,
+             tsum = 0,
+             i = 0,
+             j = 0;
+    uint32_t lsum = 0;
 
     j = len >> 1;
     lsum = 0;
@@ -64,9 +67,10 @@ static uint16_t wiz_checksum(uint8_t *src, uint32_t len)
 
 static int wiz_ping_request(int socket)
 {
-    int idx, send_len;
-    uint16_t tmp_checksum;
-    struct wiz_ping_msg ping_req;
+    uint16_t tmp_checksum = 0;
+    int idx = 0,
+        send_len = 0;
+    struct wiz_ping_msg ping_req = {0};
 
     // 设置请求ping消息对象
     ping_req.type = WIZ_PING_REQUEST;
@@ -91,14 +95,14 @@ static int wiz_ping_request(int socket)
 
 static int wiz_ping_reply(int socket, struct sockaddr *from)
 {
-    uint16_t tmp_checksum;
-    uint8_t recv_buf[WIZ_PING_HEAD_LEN + WIZ_PING_DATA_LEN + 1];
-    struct wiz_ping_msg ping_rep;
-
-    int recv_len;
-    int idx;
 
+    uint8_t recv_buf[WIZ_PING_HEAD_LEN + WIZ_PING_DATA_LEN + 1] = {0};
+    uint16_t tmp_checksum = 0;
+    int recv_len = 0,
+        idx = 0;
+    struct wiz_ping_msg ping_rep = {0};
     platformTimer_t pingReplyTimer = {0};
+
     platformTimerCutdown(&pingReplyTimer, WIZ_PING_TIMEOUT);
     while (1)
     {

+ 145 - 137
W5500Client/RyanW5500Socket.c

@@ -33,7 +33,6 @@ int RyanW5500RecvDataCallback(int socket)
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; });
 
     rt_event_send(RyanW5500Entry.W5500EventHandle, 1 << sock->socket);
-
     return 0;
 }
 
@@ -52,7 +51,6 @@ int RyanW5500CloseCallback(int socket)
 
     sock->state = RyanW5500SocketClose;
     rt_event_send(RyanW5500Entry.W5500EventHandle, 1 << sock->socket);
-
     return 0;
 }
 
@@ -83,7 +81,6 @@ void inAddrToipStrArr(in_addr_t *s_addr, uint8_t *ipStrArr)
  */
 in_addr_t ipStrArrToinAddr(uint8_t *ipStrArr)
 {
-
     assert(NULL != ipStrArr);
 
     // 效率有点低
@@ -118,6 +115,85 @@ RyanW5500Socket *RyanW5500GetSock(int socket)
     return &RyanW5500Sockets[socket];
 }
 
+/**
+ * @brief 给listen服务器套接字创建client客户端
+ *
+ * @param serviceSock
+ * @return RyanW5500Socket*
+ */
+RyanW5500Socket *RyanW5500CreateListenClient(RyanW5500Socket *serviceSock)
+{
+    assert(NULL != serviceSock);
+
+    RyanW5500Socket *clientSock = NULL;
+    RyanW5500ClientInfo *clientInfo = NULL;
+    clientSock = RyanW5500SocketCreate(serviceSock->type, serviceSock->port);
+    RyanW5500CheckCode(NULL != clientSock, EMFILE, { goto err; });
+
+    clientSock->serviceSocket = serviceSock->socket;
+
+    // 创建客户端信息并将客户端添加到服务器clientList
+    clientInfo = (RyanW5500ClientInfo *)malloc(sizeof(RyanW5500ClientInfo));
+    RyanW5500CheckCode(NULL != clientInfo, ENOMEM, { goto err; });
+    memset(clientInfo, 0, sizeof(RyanW5500ClientInfo));
+
+    clientInfo->sock = clientSock;
+    RyanListAddTail(&clientInfo->list, &serviceSock->serviceInfo->clientList);
+
+    RyanW5500CheckCode(SOCK_OK == wizchip_listen(clientSock->socket), EPROTO, {wiz_closesocket(clientSock->socket); goto err; });
+    clientSock->state = RyanW5500SocketListen;
+
+    return clientSock;
+
+err:
+    if (NULL != clientInfo)
+        wiz_closesocket(clientSock->socket);
+
+    if (NULL != clientInfo)
+        free(clientInfo);
+    return NULL;
+}
+
+static void RyanW5500ListenSocketDestory(RyanW5500Socket *sock)
+{
+
+    RyanW5500Socket *serviceSock = RyanW5500GetSock(sock->serviceSocket);
+    assert(NULL != serviceSock);
+    assert(NULL != serviceSock->serviceInfo && sock->port == serviceSock->port);
+
+    // 分配并初始化新的客户端套接字
+    RyanList_t *curr = NULL,
+               *next = NULL;
+    RyanW5500ClientInfo *clientInfo = NULL;
+
+    RyanListForEachSafe(curr, next, &serviceSock->serviceInfo->clientList)
+    {
+        // 获取此节点的结构体
+        clientInfo = RyanListEntry(curr, RyanW5500ClientInfo, list);
+        assert(NULL != clientInfo);
+        if (clientInfo->sock->socket != sock->socket)
+            continue;
+
+        RyanListDel(&clientInfo->list);
+
+        // 增加listen客户端数
+        if (0 == serviceSock->serviceInfo->backlog)
+        {
+            RyanW5500Socket *sock = RyanW5500CreateListenClient(serviceSock);
+            if (NULL == sock)
+            {
+                int8_t socket = -1;
+                rt_mq_send(serviceSock->serviceInfo->clientInfoQueueHandle, &socket, sizeof(int8_t));
+            }
+        }
+
+        // 添加服务器套接字监听数
+        serviceSock->serviceInfo->backlog++;
+        free(clientInfo);
+        break;
+    }
+}
+
 static int RyanW5500SocketDestory(RyanW5500Socket *sock)
 {
 
@@ -127,8 +203,11 @@ static int RyanW5500SocketDestory(RyanW5500Socket *sock)
     if (sock->remoteAddr)
         free(sock->remoteAddr);
 
-    // 是服务器套接字,释放服务器信息并关闭所有客户端套接字clientList
-    if (sock->serviceInfo)
+    if (-1 != sock->serviceSocket) // 根据记录的serviceSocket判断是否为listen客户端
+        RyanW5500ListenSocketDestory(sock);
+
+    // listen服务器套接字,释放服务器信息并关闭所有客户端套接字clientList
+    else if (NULL != sock->serviceInfo)
     {
         RyanW5500ClientInfo *clientInfo = NULL;
 
@@ -154,33 +233,6 @@ static int RyanW5500SocketDestory(RyanW5500Socket *sock)
         if (sock->serviceInfo)
             free(sock->serviceInfo);
     }
-    else if (-1 != sock->serviceSocket) // 可能是listen客户端套接字,根据记录的serviceSocket判断是否为listen客户端
-    {
-        RyanW5500Socket *serviceSock = RyanW5500GetSock(sock->serviceSocket);
-        if (NULL != serviceSock->serviceInfo && sock->port == serviceSock->port)
-        {
-
-            // 分配并初始化新的客户端套接字
-            RyanList_t *curr = NULL,
-                       *next = NULL;
-            RyanW5500ClientInfo *clientInfo = NULL;
-
-            RyanListForEachSafe(curr, next, &serviceSock->serviceInfo->clientList)
-            {
-                // 获取此节点的结构体
-                clientInfo = RyanListEntry(curr, RyanW5500ClientInfo, list);
-                if (NULL == clientInfo || clientInfo->sock->socket != sock->socket)
-                    continue;
-
-                RyanListDel(&clientInfo->list);
-
-                // 添加服务器套接字监听数
-                serviceSock->serviceInfo->backlog++;
-                free(clientInfo);
-                break;
-            }
-        }
-    }
 
     setSn_IR(sock->socket, 0xff); // 清空套接字中断
     setSn_IMR(sock->socket, 0);   // 设置套接字ISR状态支持
@@ -243,45 +295,6 @@ err:
     return NULL;
 }
 
-/**
- * @brief 给listen服务器套接字创建client客户端
- *
- * @param serviceSock
- * @return RyanW5500Socket*
- */
-RyanW5500Socket *RyanW5500CreateListenClient(RyanW5500Socket *serviceSock)
-{
-    assert(NULL != serviceSock);
-
-    RyanW5500Socket *clientSock = NULL;
-    RyanW5500ClientInfo *clientInfo = NULL;
-    clientSock = RyanW5500SocketCreate(serviceSock->type, serviceSock->port);
-    RyanW5500CheckCode(NULL != clientSock, EMFILE, { goto err; });
-
-    clientSock->serviceSocket = serviceSock->socket;
-
-    // 创建客户端信息并将客户端添加到服务器clientList
-    clientInfo = (RyanW5500ClientInfo *)malloc(sizeof(RyanW5500ClientInfo));
-    RyanW5500CheckCode(NULL != clientInfo, ENOMEM, { goto err; });
-    memset(clientInfo, 0, sizeof(RyanW5500ClientInfo));
-
-    clientInfo->sock = clientSock;
-    RyanListAddTail(&clientInfo->list, &serviceSock->serviceInfo->clientList);
-
-    RyanW5500CheckCode(SOCK_OK == wizchip_listen(clientSock->socket), EPROTO, {wiz_closesocket(clientSock->socket); goto err; });
-    clientSock->state = RyanW5500SocketListen;
-
-    return clientSock;
-
-err:
-    if (NULL != clientInfo)
-        wiz_closesocket(clientSock->socket);
-
-    if (NULL != clientInfo)
-        free(clientInfo);
-    return NULL;
-}
-
 /**
  * @brief 新的listen客户端连接
  *
@@ -293,29 +306,25 @@ void RyanListenServiceAddClient(RyanW5500Socket *serviceSock, RyanW5500Socket *c
 
     assert(NULL != serviceSock);
     assert(NULL != clientSock);
+    assert(serviceSock->serviceInfo->backlog > 0);
 
     int8_t socket = -1;
 
-    // 检查服务器侦听积压工作编号
-    if (serviceSock->serviceInfo->backlog <= 0)
-        goto err;
-
     serviceSock->serviceInfo->backlog--;
     clientSock->state = RyanW5500SocketEstablished;
 
-    // 发送客户端套接字连接消息和事件
     socket = clientSock->socket;
     rt_mq_send(serviceSock->serviceInfo->clientInfoQueueHandle, &socket, sizeof(int8_t));
 
-    RyanW5500Socket *sock = RyanW5500CreateListenClient(serviceSock);
-    if (NULL == sock)
-        goto err;
-
-    return;
-
-err:
-    socket = -1;
-    rt_mq_send(serviceSock->serviceInfo->clientInfoQueueHandle, &socket, sizeof(int8_t));
+    if (serviceSock->serviceInfo->backlog > 0)
+    {
+        RyanW5500Socket *sock = RyanW5500CreateListenClient(serviceSock);
+        if (NULL == sock)
+        {
+            socket = -1;
+            rt_mq_send(serviceSock->serviceInfo->clientInfoQueueHandle, &socket, sizeof(int8_t));
+        }
+    }
 }
 
 /**
@@ -436,7 +445,6 @@ int wiz_connect(int socket, const struct sockaddr *name, socklen_t namelen)
         break;
 
     case SOCK_INIT: // tcp
-                    // 通过套接字结构获取 IP 地址和端口
     {
         uint8_t ipStrArr[4] = {0};
         struct sockaddr_in *sin = (struct sockaddr_in *)name;
@@ -473,8 +481,7 @@ int wiz_listen(int socket, int backlog)
 {
     RyanW5500LinkCheck(-1);
 
-    RyanW5500Socket *sock = NULL;
-    sock = RyanW5500GetSock(socket);
+    RyanW5500Socket *sock = RyanW5500GetSock(socket);
 
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; });                               // 套接字参数不是有效的文件描述符。
     RyanW5500CheckCode(RyanW5500SocketEstablished != sock->state, EINVAL, { return -1; }); // 套接字已连接
@@ -485,19 +492,20 @@ int wiz_listen(int socket, int backlog)
     RyanW5500CheckCode(NULL != sock->serviceInfo, ENOMEM, { goto err; });
     memset(sock->serviceInfo, 0, sizeof(RyanW5500ServiceInfo));
 
-    // 创建客户端套接字连接事件邮箱
+    // 创建listen客户端连接消息队列
     char name[32] = {0};
     snprintf(name, 32, "wiz_mb%d", sock->socket);
     sock->serviceInfo->backlog = backlog > 0 ? backlog : 0;
 
-    // BSD socket允许listen队列为0,这里消息队列创建1大小,为了appect可以阻塞
+    // BSD socket允许listen为0,这里消息队列创建1大小,为了appect可以阻塞
     sock->serviceInfo->clientInfoQueueHandle = rt_mq_create(name, sizeof(int8_t), backlog > 0 ? backlog : 1, RT_IPC_FLAG_FIFO);
     RyanW5500CheckCode(NULL != sock->serviceInfo->clientInfoQueueHandle, ENOMEM, { goto err; });
 
     RyanListInit(&sock->serviceInfo->clientList);
     sock->state = RyanW5500SocketListen;
 
-    RyanW5500CreateListenClient(sock);
+    if (NULL == RyanW5500CreateListenClient(sock))
+        goto err;
 
     return 0;
 
@@ -524,12 +532,9 @@ err:
 int wiz_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
 {
     RyanW5500LinkCheck(-1);
-    RyanW5500Socket *serviceSock = NULL;
-    int8_t clientSocket = -1;
-
     RyanW5500CheckCode(NULL != addr && 0 != addrlen, EAFNOSUPPORT, { return -1; }); // 非法地址
 
-    serviceSock = RyanW5500GetSock(socket);
+    RyanW5500Socket *serviceSock = RyanW5500GetSock(socket);
 
     RyanW5500CheckCode(NULL != serviceSock, EBADF, { return -1; });                          // 套接字参数不是有效的文件描述符。
     RyanW5500CheckCode(RyanW5500SocketListen == serviceSock->state, EINVAL, { return -1; }); // 套接字不接受连接,没有listen
@@ -537,6 +542,7 @@ int wiz_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
 
     while (1)
     {
+        int8_t clientSocket = -1;
         // 接收客户端连接消息
         if (rt_mq_recv(serviceSock->serviceInfo->clientInfoQueueHandle, (void *)&clientSocket, sizeof(int8_t), RT_WAITING_FOREVER) != RT_EOK)
             continue;
@@ -562,7 +568,7 @@ int wiz_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
         sin->sin_addr.s_addr = ipStrArrToinAddr(ipStrArr);
 
         *addrlen = sizeof(struct sockaddr);
-        LOG_D("remote ip: %s, remote port: %d", inet_ntoa(sin->sin_addr.s_addr), remotePort);
+        LOG_D("accept remote ip: %s, remote port: %d", inet_ntoa(sin->sin_addr.s_addr), remotePort);
 
         return clientSocket;
     }
@@ -582,13 +588,13 @@ int wiz_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
 int wiz_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
 {
     RyanW5500LinkCheck(-1);
+    RyanW5500CheckCode(NULL != data && 0 != size, EFAULT, { return -1; });
+
     RyanW5500Socket *sock = NULL;
     uint8_t socketState = 0;
     int32_t sendLen = 0,
             timeout = 0;
 
-    RyanW5500CheckCode(NULL != data && 0 != size, EFAULT, { return -1; });
-
     sock = RyanW5500GetSock(socket);
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; });
 
@@ -608,17 +614,17 @@ int wiz_sendto(int socket, const void *data, size_t size, int flags, const struc
 
         // 如果发送数据比剩余缓冲区大,则分片发送,否则缓冲区数据会被清空
         sendLen = getSn_TX_FSR(sock->socket);
-        RyanW5500CheckCode(0 <= sendLen, EWOULDBLOCK, { return -1; }); // 发送缓冲区已满
+        RyanW5500CheckCode(sendLen > 0, EWOULDBLOCK, { return -1; }); // 发送缓冲区已满
 
-        sendLen = sendLen > size ? size : sendLen;
+        if (sendLen > size)
+            sendLen = size;
         sendLen = wizchip_send(socket, (uint8_t *)data, sendLen);
-        RyanW5500CheckCode(sendLen >= 0, EINTR, { return -1; }); // 发送失败,一般不会,所以将错误设置为信号中断
-        break;
+        RyanW5500CheckCode(sendLen > 0, EINTR, { return -1; }); // 发送失败,一般不会,所以将错误设置为信号中断
+        return sendLen;
 
     case Sn_MR_UDP:
     case Sn_MR_IPRAW:
     {
-
         socketState = getSn_SR(socket);
         RyanW5500CheckCode(SOCK_UDP == socketState || SOCK_IPRAW == socketState, EDESTADDRREQ, { return -1; });
 
@@ -640,26 +646,25 @@ int wiz_sendto(int socket, const void *data, size_t size, int flags, const struc
 
         // 如果发送数据比剩余缓冲区大,则分片发送,否则缓冲区数据会被清空
         sendLen = getSn_TX_FSR(sock->socket);
-        RyanW5500CheckCode(0 <= sendLen, EWOULDBLOCK, { return -1; }); // 发送缓冲区已满
+        RyanW5500CheckCode(sendLen > 0, EWOULDBLOCK, { return -1; }); // 发送缓冲区已满
 
-        sendLen = sendLen > size ? size : sendLen;
+        if (sendLen > size)
+            sendLen = size;
         sendLen = wizchip_sendto(sock->socket, (uint8_t *)data, sendLen, ipStrArr, htons(sin->sin_port));
-        if (sendLen < 0)
+        if (sendLen <= 0)
         {
             RyanW5500CheckCode(SOCKERR_SOCKCLOSED == sendLen, EPIPE, { return -1; }); // 套接字被关闭
             LOG_E("udp send fail, result: %d", sendLen);
             return -1;
         }
 
-        break;
+        return sendLen;
     }
 
     default:
         LOG_E("socket (%d) type %d is not support.", socket, sock->type);
         return -1;
     }
-
-    return sendLen;
 }
 
 /**
@@ -676,6 +681,7 @@ int wiz_sendto(int socket, const void *data, size_t size, int flags, const struc
 int wiz_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
 {
     RyanW5500LinkCheck(-1);
+    RyanW5500CheckCode(NULL != mem && 0 != len, EFAULT, { return -1; });
 
     RyanW5500Socket *sock = NULL;
     uint8_t socketState = 0;
@@ -684,8 +690,6 @@ int wiz_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *
             result = 0;
     platformTimer_t recvTimer = {0};
 
-    RyanW5500CheckCode(NULL != mem && 0 != len, EFAULT, { return -1; });
-
     sock = RyanW5500GetSock(socket);
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; });
 
@@ -704,7 +708,6 @@ again:
     {
     case Sn_MR_TCP:
     {
-
         socketState = getSn_SR(socket);
         RyanW5500CheckCode(SOCK_ESTABLISHED == socketState, ENOTCONN, { return -1; }); // 在未连接的连接模式套接字上尝试接收。
 
@@ -719,16 +722,18 @@ again:
         if (recvLen <= 0)
             goto again;
 
-        // 接收数据到用户缓冲区
-        recvLen = recvLen > len ? len : recvLen; // 如果数据比缓冲区大,则调整至缓冲区大小
+        // 如果数据比缓冲区大,则调整至缓冲区大小
+        if (recvLen > len)
+            recvLen = len;
+
         recvLen = wizchip_recv(socket, mem, recvLen);
-        if (recvLen < 0)
+        if (recvLen <= 0)
         {
             LOG_E("recv error, result: %d", recvLen);
             return -1;
         }
 
-        break;
+        return recvLen;
     }
 
     case Sn_MR_UDP:
@@ -751,9 +756,12 @@ again:
         uint16_t remotePort = 0;
         uint8_t remoteIp[4] = {0};
 
-        recvLen = recvLen > len ? len : recvLen;
+        // 如果数据比缓冲区大,则调整至缓冲区大小
+        if (recvLen > len)
+            recvLen = len;
+
         recvLen = wizchip_recvfrom(socket, mem, recvLen, remoteIp, &remotePort);
-        if (recvLen < 0)
+        if (recvLen <= 0)
         {
             LOG_E("recvfrom error, result: %d", recvLen);
             return -1;
@@ -766,15 +774,13 @@ again:
 
         sin->sin_port = htons(remotePort);
         sin->sin_addr.s_addr = ipStrArrToinAddr(remoteIp);
-        break;
+        return recvLen;
     }
 
     default:
         LOG_E("socket (%d) type %d is not support.", socket, sock->type);
         return -1;
     }
-
-    return recvLen;
 }
 
 int wiz_send(int socket, const void *data, size_t size, int flags)
@@ -816,7 +822,8 @@ int wiz_closesocket(int socket)
     }
 
     int8_t result = SOCK_FATAL;
-    if (Sn_MR_TCP == sock->type && NULL == sock->serviceInfo)
+    // 属于tcp套接字,但又不是listen服务器套接字
+    if (Sn_MR_TCP == sock->type && RyanW5500SocketEstablished == sock->state && NULL == sock->serviceInfo)
         result = wizchip_disconnect(sock->socket);
 
     if (SOCK_OK != result)
@@ -874,11 +881,10 @@ int wiz_shutdown(int socket, int how)
 int wiz_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
 {
     RyanW5500LinkCheck(-1);
+    RyanW5500CheckCode(NULL != optval && 0 != optlen, EFAULT, { return -1; });
 
     RyanW5500Socket *sock = NULL;
 
-    RyanW5500CheckCode(NULL != optval && 0 != optlen, EFAULT, { return -1; });
-
     sock = RyanW5500GetSock(socket);
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; }); // 指定的选项在指定的套接字级别无效或套接字已关闭。
 
@@ -1019,11 +1025,12 @@ int wiz_setsockopt(int socket, int level, int optname, const void *optval, sockl
  */
 int wiz_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
 {
-    RyanW5500Socket *sock = NULL;
 
     RyanW5500LinkCheck(-1);
     RyanW5500CheckCode(NULL != optval && NULL != optlen, EFAULT, { return -1; });
 
+    RyanW5500Socket *sock = NULL;
+
     sock = RyanW5500GetSock(socket);
     RyanW5500CheckCode(NULL != sock, EBADF, { return -1; });
 
@@ -1154,6 +1161,7 @@ int wiz_getsockopt(int socket, int level, int optname, void *optval, socklen_t *
 
 int RyanW5500_gethostbyname(const char *name, ip_addr_t *addr)
 {
+
     int idx = 0;
     int nameLen = strlen(name);
     char ipStrArr[16] = {0};
@@ -1212,7 +1220,7 @@ struct hostent *wiz_gethostbyname(const char *name)
     // 检查WIZnet初始化状态
     RyanW5500LinkCheck(NULL);
 
-    ip_addr_t addr;
+    ip_addr_t addr = {0};
     int err = 0;
 
     // 用于 gethostbyname() 的缓冲区变量
@@ -1284,11 +1292,11 @@ int wiz_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t
         char *aliases;
     };
 
-    int err;
-    struct gethostbyname_r_helper *h;
-    char *hostname;
-    size_t namelen;
-    int lh_errno;
+    char *hostname = NULL;
+    int lh_errno = 0,
+        err = 0;
+    size_t namelen = 0;
+    struct gethostbyname_r_helper *h = NULL;
 
     if (h_errnop == NULL)
         h_errnop = &lh_errno; // 确保 h_errnop 永远不会为 NULL
@@ -1362,14 +1370,14 @@ int wiz_getaddrinfo(const char *nodename, const char *servname, const struct add
     // 检查WIZnet初始化状态
     RyanW5500LinkCheck(-1);
 
-    int err = 0;
-    int port_nr = 0;
-    ip_addr_t addr;
-    struct addrinfo *ai = NULL;
-    struct sockaddr_storage *sa = NULL;
+    int err = 0,
+        port_nr = 0,
+        ai_family = 0;
     size_t total_size = 0;
     size_t namelen = 0;
-    int ai_family = 0;
+    ip_addr_t addr = {0};
+    struct addrinfo *ai = NULL;
+    struct sockaddr_storage *sa = NULL;
 
     if (NULL == res)
         return EAI_FAIL;

+ 0 - 1
W5500Client/RyanW5500Store.h

@@ -92,7 +92,6 @@ extern "C"
         rt_timer_t W5500TimerHandle;
         rt_event_t W5500EventHandle;    // 事件标志组,用于中断通知和socket状态通知
         rt_mutex_t socketMutexHandle;   // socket锁
-        rt_mutex_t W5500SpiMutexHandle; // spi锁
         rt_thread_t w5500TaskHandle;    // W5500线程
     } RyanW5500Entry_t;
 

+ 10 - 9
example/RyanW5500Test.c

@@ -34,6 +34,7 @@ int w5500Start(int argc, char *argv[])
     if (NULL != RyanNetdev)
     {
         ulog_w(TAG, "w5500已经启动,不要重复选择");
+        return -1;
     }
 
     wiz_NetInfo netInfo = {0};
@@ -158,7 +159,7 @@ void tcpEchoTask(void *argument)
         bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
 
         // 使用listen创建连接队列 主动变被动
-        listen(sockfd, 4);
+        listen(sockfd, 2);
 
         while (1)
         {
@@ -282,7 +283,7 @@ void multicastEchoServiceTask(void *argument)
         ulog_i(TAG, "multicast, 消息来自: %s, port: %hu", inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));
         ulog_i(TAG, "multicast, len: %d, msg: %s", len, buf);
 
-        // 默认只会发送给多播组,这是w5500硬件限制的,如果想单播回复组播收到的信息,需要重新创建socket
+        // socket加入多播组后,sendto消息只能发送给多播组,这是w5500硬件限制的,如果想单播回复组播收到的信息,需要重新创建socket
         // sendto(sockfd, "hellow", strlen("hellow"), 0, (struct sockaddr *)&from_addr, sizeof(from_addr));
 
         int sockfd2 = socket(AF_INET, SOCK_DGRAM, 0);
@@ -535,9 +536,10 @@ static int w5500Broadcast(int argc, char *argv[])
 
 /**
  * @brief
- * !注意:RyanW5500组播实现不支持加入多个组播组,这是由W5500硬件限制的,和tcp服务器一样。
- * !虽然可以通过申请多个socket, 再将数据合并实现,但考虑多组播功能并不常用,且实现较为复杂占资源,暂时没有实现多组播
+ * !注意:RyanW5500 socket组播实现不支持加入多个组播组,这是由W5500硬件限制的.
+ * !这和tcp服务器一样,虽然可以像tcp listen一样实现多组播,但考虑多组播功能并不常用,且实现较为复杂占资源,暂时没有实现多组播
  * !目前如果需要加入多个组播的话,就申请多个socket分别加入组播组吧
+ * !socket加入多播组后,sendto消息只能发送给多播组,这是w5500硬件限制的,如果想单播回复组播收到的信息,需要重新创建socket
  *
  * @param argc
  * @param argv
@@ -629,7 +631,6 @@ static int w5500GetHostByName(int argc, char *argv[])
 
     if (0 == choice)
     {
-
         struct hostent *hent;
         hent = gethostbyname(nameStr);
 
@@ -652,7 +653,7 @@ static int w5500GetHostByName(int argc, char *argv[])
 
     else
     {
-        char buf[1024];
+        char buf[512];
         int ret;
         struct hostent hostinfo, *phost;
 
@@ -732,8 +733,8 @@ static int w5500Help(int argc, char *argv[]);
 static const struct RyanMqttCmdDes cmdTab[] = {
     {"help", "打印帮助信息", w5500Help},
     {"start", "打印帮助信息", w5500Start},
-    {"static", "netdev设置w5500静态地址,启动echo服务器后不要调用,调用会关闭所有socket", w5500Static},
-    {"dhcp", "netdev设置w5500 dhcp,启动echo服务器后不要调用,调用会关闭所有socket", w5500Dhcp},
+    {"static", "netdev设置w5500静态地址,如果触发了ip变化,会关闭所有已连接socket", w5500Static},
+    {"dhcp", "netdev设置w5500 dhcp,如果触发了ip变化,会关闭所有已连接socket", w5500Dhcp},
     {"udpClient", "w5500 udp客户端 param: ip, port", w5500UdpClient},
     {"udpService", "w5500 udp echo服务器 param: port", w5500UdpService},
     {"tcpClient", "w5500 tcp客户端 param: ip, port", w5500TcpClient},
@@ -801,7 +802,7 @@ static int RyanW5500SpiArrach(void)
 
     return result;
 }
-INIT_DEVICE_EXPORT(RyanW5500SpiArrach); // 导出到自动初始化
+INIT_DEVICE_EXPORT(RyanW5500SpiArrach); // spi总线挂载
 
 #if defined(RT_USING_MSH)
 MSH_CMD_EXPORT_ALIAS(RyanMqttMsh, w5500, RyanMqtt command);

+ 13 - 6
ioLibrary/DHCP/wizchip_dhcp.c

@@ -589,42 +589,49 @@ int8_t check_DHCP_leasedIP(void)
 uint8_t DHCP_run(uint8_t flag)
 {
     uint8_t type = 0;
+    uint8_t dhcp_retry_count = 0;
+    platformTimer_t recvTimer = {0};
+    RyanW5500Socket *sock = NULL;
 
     setSHAR(gWIZNETINFO.mac); // 设置w5500 mac
 
-    RyanW5500Socket *sock = RyanW5500SocketCreate(Sn_MR_UDP, DHCP_CLIENT_PORT);
+    sock = RyanW5500SocketCreate(Sn_MR_UDP, DHCP_CLIENT_PORT);
     if (NULL == sock)
     {
         LOG_W("dhcp socket失败");
         return -1;
     }
 
+    // 申请dhcp报文空间
     uint8_t *dhcpDataBuf = (uint8_t *)rt_malloc(RIP_MSG_SIZE);
+    if (NULL == dhcpDataBuf)
+    {
+        wiz_closesocket(sock->socket);
+        return -1;
+    }
 
-    DHCP_SOCKET = sock->socket; // SOCK_DHCP
+    DHCP_SOCKET = sock->socket;
     pDHCPMSG = (RIP_MSG *)dhcpDataBuf;
 
     if (1 != flag) // flag 1表示处于续租状态
     {
         // 生成唯一事务id
-        DHCP_XID = 0x12345678;
+        DHCP_XID = platformUptimeMs();
         DHCP_XID += gWIZNETINFO.mac[3];
         DHCP_XID += gWIZNETINFO.mac[4];
         DHCP_XID += gWIZNETINFO.mac[5];
-        DHCP_XID += (gWIZNETINFO.mac[3] ^ gWIZNETINFO.mac[4] ^ gWIZNETINFO.mac[5]);
 
         dhcp_state = STATE_DHCP_INIT;
         platformTimerInit(&dhcp_lease_time);
     }
 
-    uint8_t dhcp_retry_count = 0;
-    platformTimer_t recvTimer = {0};
     platformTimerCutdown(&recvTimer, DHCP_WAIT_TIME);
 
     while (1)
     {
         type = parseDHCPMSG();
 
+        // 根据dhcp_state发送不同报文
         switch (dhcp_state)
         {
         case STATE_DHCP_INIT: // dhcp初始化状态

+ 2 - 2
ioLibrary/DHCP/wizchip_dhcp.h

@@ -7,8 +7,8 @@ extern "C"
 {
 #endif
 
-#define MAX_DHCP_RETRY 6    // 最大重试计数
-#define DHCP_WAIT_TIME 3000 // 等待时间
+#define MAX_DHCP_RETRY 8    // 最大重试计数
+#define DHCP_WAIT_TIME 1000 // 等待时间
 
 #define DHCP_SERVER_PORT 67 // DHCP 服务器端口号
 #define DHCP_CLIENT_PORT 68 // DHCP 客户端端口号

+ 7 - 6
ioLibrary/DNS/wizchip_dns.c

@@ -444,15 +444,16 @@ int16_t dns_makequery(uint16_t op, char *name, uint8_t *buf, uint16_t len)
  */
 int8_t DNS_run(uint8_t *dns_ip, uint8_t *name, uint8_t *ip_from_dns, uint8_t *buf)
 {
-    int8_t ret;
-    struct dhdr dhp;
-    uint8_t ip[4];
+    int8_t ret = 0;
     uint8_t retry_count = 0;
-    uint16_t len, port;
-
+    uint16_t len = 0,
+             port = 0;
+    uint8_t ip[4] = {0};
+    struct dhdr dhp = {0};
     platformTimer_t recvTimer = {0};
+    RyanW5500Socket *sock = NULL;
 
-    RyanW5500Socket *sock = RyanW5500SocketCreate(SOCK_DGRAM, IPPORT_DOMAIN);
+    sock = RyanW5500SocketCreate(SOCK_DGRAM, IPPORT_DOMAIN);
     if (NULL == sock)
     {
         LOG_W("dns socket失败");

+ 20 - 0
platform/RT-Thread/platformW5500Hardware.c

@@ -102,6 +102,26 @@ void RyanW5500ReadBurst(uint8_t *pbuf, uint16_t len)
     rt_spi_transfer_message(RyanW5500SpiDevice, &spiMsg);
 }
 
+/**
+ * @brief 获取当前SPI总线资源
+ * spi只挂载一个设备时可以忽略
+ *
+ */
+void RyanW5500CriticalEnter(void)
+{
+    rt_spi_take_bus(RyanW5500SpiDevice);
+}
+
+/**
+ * @brief 释放当前SPI总线资源
+ * spi只挂载一个设备时可以忽略
+ *
+ */
+void RyanW5500CriticalExit(void)
+{
+    rt_spi_release_bus(RyanW5500SpiDevice);
+}
+
 /**
  * @brief 片选使能
  *