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

来源:互联网 发布:最新网络兼职 编辑:程序博客网 时间:2024/05/17 01:55

由于公司需要,最近接触了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、解决通讯线问题后更新完程序,将板子用网线通过一个分线盒和电脑连接上,此时电脑连接的是路由器,IP192.168.31.166,板子本地IP设置为192.168.123进行测试发现不能ping通,

解决办法,直接用网线将电脑和板子连接,关闭路由器,社本地IP192.168.0.101,设置板子IP192.168.0.100,再次进行测试,可以ping通了。完善程序中的端口配置,打开pctcpIP客户端,设置为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;
}

 

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

 

 

0 0
原创粉丝点击