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幀,不管這個週期內有無數據

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