您的位置:首页 > 理论基础 > 计算机网络

关于w5500客户端和服务器的调试心得

2016-09-24 17:25 330 查看
由于公司需要,最近接触了w5500这款嵌入式以太网控制器

TS-W5500模块特点:

1、尺寸小:5CM*3CM
2、4层板设计并了TVS等保护IC,差分走线,保障了良好的EMC兼容性
3、5V、3V单片机都兼容
W5500
W5500是一款全硬件TCP/IP嵌入式以太网控制器,为嵌入式系统提供了更加简易
的互联网连接方案。W5500集成了TCP/IP协议栈,10/100M以太网数据链路层(MAC)
及物理层(PHY),使得用户使用单芯片就能够在他们的应用中拓展网络连接。
久经市场考验的WIZnet全硬件TCP/IP协议栈支持TCP,UDP,IPv4,ICMP,ARP,IGMP 以
及PPPoE协议。W5500内嵌32K字节片上缓存以供以太网包处理。如果你使用W5500,
你只需要一些简单的Socket编程就能实现以太网应用。这将会比其他嵌入式以太网方案
更加快捷、简便。用户可以同时使用8个硬件Socket独立通讯。
W5500提供了SPI(外设串行接口)从而能够更加容易与外设MCU整合。而且,
W5500的使用了新的高效SPI协议支持80MHz速率,从而能够更好的实现高速网络通讯。

为了减少系统能耗,W5500提供了网络唤醒模式(WOL)及掉电模式供客户选择使用。

参考资源:http://bbs.21ic.com/icview-825510-1-1.html

程序是参考飞鸿踏雪的例程,在这里我分享下跟人开发中遇到的问题及解决办法。

1、将飞鸿踏雪的文件加入到自己的工程后,初始化会死机在

/* PHY link status check */
do{
if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){
printf("Unknown PHY Link stauts.\r\n");
}
}while(tmp == PHY_LINK_OFF);

这个地方。

解决办法:

检查SPI驱动程序是否配置正确,片选引脚、复位引脚是否正确配置并和实际硬件对应,这个地方出问题属于物理链路层的问题检查软件驱动和硬件接线,应该可以解决问题。

2、移植飞鸿踏雪的服务器程序进行测试,发现网络接口处的两个指示灯并未亮或闪烁,服务器程序肯定没跑通。

问题原因,公司同事在做pcb板时忘记将5500的通讯引脚和接口的通信引脚相连,经过一番周折,用导线将引脚一个一个连接上,在进行测试,指示灯终于亮了,信心大增。

3、解决通讯线问题后更新完程序,将板子用网线通过一个分线盒和电脑连接上,此时电脑连接的是路由器,IP为192.168.31.166,板子本地IP设置为192.168.123进行测试发现不能ping通,

解决办法,直接用网线将电脑和板子连接,关闭路由器,社本地IP为192.168.0.101,设置板子IP为192.168.0.100,再次进行测试,可以ping通了。完善程序中的端口配置,打开pc端tcpIP客户端,设置为tcpclient,测试连接目标板IP,可以连接上并能进行通信。

/**

  * @brief  TCP服务器

  * @retval None

  */

int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)

{

   int32_t ret;

   uint16_t size = 0, sentsize=0;

   switch(getSn_SR(sn))

   {

       case SOCK_ESTABLISHED :

         if(getSn_IR(sn) & Sn_IR_CON)

         {

            printf("%d:Connected\r\n",sn);

            setSn_IR(sn,Sn_IR_CON);

         }

         if((size = getSn_RX_RSR(sn)) > 0)

         {

            if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;

            ret = recv(sn,buf,size);

            if(ret <= 0) return ret;

            sentsize = 0;

            while(size != sentsize)

            {

               ret = send(sn,buf+sentsize,size-sentsize);

               if(ret < 0)

               {

                  close(sn);

                  return ret;

               }

               sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.

            }
         }

         break;

      case SOCK_CLOSE_WAIT :

         printf("%d:CloseWait\r\n",sn);

         if((ret=disconnect(sn)) != SOCK_OK) return ret;

         printf("%d:Closed\r\n",sn);

         break;

      case SOCK_INIT :

       printf("%d:Listen, port [%d]\r\n",sn, port);

         if( (ret = listen(sn)) != SOCK_OK) return ret;

         break;

      case SOCK_CLOSED:

         printf("%d:LBTStart\r\n",sn);

         if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)

            return ret;

         printf("%d:Opened\r\n",sn);

         break;

      default:

         break;

   }

   return 1;

}

 

4、测试将板子作为客户端,PC为服务器,移植飞鸿踏雪的例程,配置好服务器客户端端口,发现老是timeout,程序卡在

经过一顿百度,卡在此处是本地发出请求,没有应答,所以socket不会处于就绪状态。

解决办法是关闭电脑的防火墙,再次进行测试就ok了。

int32_t loopback_tcpclient(uint8_t sn, uint8_t* buf, uint16_t port)

{

   int32_t ret;

   uint16_t size = 0, sentsize=0;

   switch(getSn_SR(sn))

   {

   case SOCK_INIT :

       printf("%d:connect [%d]\r\n",sn, Server_Port);

         if(connect(sn,Server_IP,Server_Port) != SOCK_OK)

 {

disconnect(sn);

 }

         break;

       case SOCK_ESTABLISHED ://socket0Á¬½Ó½¨Á¢

         if(getSn_IR(sn) & Sn_IR_CON)

         {

            printf("%d:Connected\r\n",sn);

            setSn_IR(sn,Sn_IR_CON);

         }

         if((size = getSn_RX_RSR(sn)) > 0)

         {

            if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;

            ret = recv(sn,buf,size);

            if(ret <= 0) return ret;

            sentsize = 0;

            while(size != sentsize)

            {

               ret = send(sn,buf+sentsize,size-sentsize);

               if(ret < 0)

               {

                  close(sn);

                  return ret;

               }

               sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.

            }

         }

         break;

      case SOCK_CLOSE_WAIT ://socket0µÈ´ý¹Ø±Õ

         printf("%d:CloseWait\r\n",sn);

         if((disconnect(sn)) != SOCK_OK) 

      break;

      case SOCK_CLOSED://socket0¹Ø±Õ£¬´ò¿ªsocket0µÄÒ»¸ö¶Ë¿Ú

         printf("%d:ClientStart\r\n",sn);

         socket(sn,Sn_MR_TCP,anyport++,0);

 if(anyport > 5000)

{

anyport=3000;

}

         printf("%d:Opened port[%d]\r\n",sn,anyport-1);

         break;

      default:

         break;

   }

   return 1;

}

 

至此,整个移植测试过程结束,谢谢大家交流和讨论。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息