W5500 KeepAlive功能调试经验

1. 问题

        W5500在实际项目应用时遇到Client可能会异常中断和板卡的连接。软件程序控制断开连接,实际上由于种种原因未断开,使得板卡进入某种临界状态,且无法恢复。根本原因是驱动库的接收函数为阻塞型,在没有报文接收时会阻塞在该函数内部,当外部Client进行某种异常断开后,Socket的状态得不到及时更新,认为当前依然在established状态,依旧阻塞。而Client恢复后无法再次连接该端口,造成死锁。

2. 解决

解决办法是在程序内增加keepalive帧,异常阻塞超过一定时间后让w5500自动关闭该socket,跳出该阻塞W5500,使能KeepAlive功能分两种方式:自动发送和手动发送

  2.1 准备

        使用这种方式前都需要设置一个timeout的时间参数,setRCR()和setRTR()

   寄存器方式设置

  • setRTR()为设置超时时间,单位为5s,一般默认即可
  • setRCR()为设置超时次数,在检测到网络上无消息传送时发送keepalive报文,若无响应超过该次数则关闭socket,进而更新socket的状态

    函数接口方式设置

      直接调用ctlnetwork(CN_SET_TIMEOUT, (void *)&gWIZNetTimeout);这个函数,其中第二个参数为配置值,用户需指定。

位置:wizchip.c文件中 void network_init(void) line243
wiz_nettimeout.retry_cnt  = 5;     //1->5  
wiz_nettimeout.time_100us = 30000; //200-> 20000 3s
ctlnetwork(CN_SET_TIMEOUT, (void*)&wiz_nettimeout);

->
wizchip_settimeout((wiz_NetTimeout*)arg);

->
void wizchip_settimeout(wiz_NetTimeout* nettime)
{
   setRCR(nettime->retry_cnt);
   setRTR(nettime->time_100us);
}

2.2 自动模式

初始化时对应的Socket 用setSn_KPALVTR(sn, 0x01);  // 配置命令,可以放到系统初始化中

       此处W5500芯片有自动处理机制,若在设定时间内有数据收发,则默认不发送keepalive帧。若设置的超时时间为5s,重试次数为2次,只要在connect成功后我们保持10S以上不发数据就可以通过wireshark检测到keepalive帧

2.2 手动模式

手动模式需要设置两处

  • setSn_KPALVTR(sn, 0x00);   // 在初始化代码中放置,第二个参数必须为0
  • IINCHIP_WRITE(Sn_CR(sn),Sn_CR_SEND_KEEP);  // 在主循环或定时任务中

这个是手动发送的,只要执行第二条指令就会发送出 keepalive帧,不管这个周期内有无数据

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章