單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機
W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。
在封裝規格上,W55MH32提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業控制中多樣化的連接需求,無論是與各類傳感器、執行器的通信,還是對復雜工業協議的支持,都能游刃有余,成為復雜工控領域的理想選擇。同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網關模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。
此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網絡通信安全再添保障。
為助力開發者快速上手與深入開發,基于W55MH32L這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。
若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。
第十六章 W55MH32 PING示例
本篇文章,我們將詳細介紹如何在W55MH32芯片上面實現IPRAW功能,并通過實戰例程,為大家講解如何使用IPRAW模式實現ICMP協議中的PING命令進行網絡連通性測試。
該例程用到的其他網絡協議,例如DHCP請參考相關章節。有關W55MH32的初始化過程,請參考Network Install章節,這里將不再贅述。
1 IPRAW模式簡介
IPRAW模式是W55MH32 TOE提供的一種網絡通信模式。在這種模式下,用戶可以直接操作IP層數據包,對其進行底層細節的處理,從而支持IP層協議的實現,例如ICMP、IGMP等。
2 PING簡介
PING是一個用于測試網絡連接性和診斷網絡問題的命令。它通過使用ICMP即因特網控制報文協議(Internet Control Message Protocol)發送“回顯請求”消息(Echo Request)并等待“回顯應答”消息(Echo Reply),來檢查目標主機是否可達以及網絡的響應時間。PING命令是網絡診斷工具中最常見的工具之一,通常用于驗證網絡連通性、檢測網絡延遲、排查網絡故障等。
3 PING命令特點
1.簡單性:PING設計非常簡單,通常是基于請求-響應的模式。一個設備發送 PING請求包,另一個設備回應PING響應包。它的開銷較小,適合嵌入式設備的網絡通信需求。
2.低延遲:由于PING本身非常簡潔,因此網絡延遲很低,適用于需要實時檢測設備狀態或維持心跳的場景。
3.狀態監測與心跳:PING常用于設備間的心跳檢測。
4.無負載數據:PING傳輸的數據通常沒有負載或附加的數據,只有簡單的請求和響應字段,因此網絡負載非常小。
5.容錯性與重試機制:一些實現可能會有超時和重試機制,以確保 PING響應的可靠性。
4 PING應用場景
接下來,我們了解下在W55MH32上,可以使用PING完成哪些操作及應用呢?
網絡連通性測試:可以用于測試本地設備與目標設備之間的網絡是否連通。
網絡故障排查:當網絡出現問題,如無法訪問某個網站或無法與特定設備進行通信時,可以使用 PING命令來逐步定位問題所在。如果對目標設備的 PING請求超時或丟包嚴重,說明可能存在網絡連接中斷、路由器配置錯誤、防火墻阻擋等問題。
網絡設備狀態監測:在網絡管理中,需要實時監測網絡中各種設備(如服務器、路由器、交換機等)的狀態。可以定期使用 PING命令對這些設備進行檢測,根據是否能夠收到回復來判斷設備是否正常運行。
5 PING命令基本工作流程
1.發送請求
用戶在命令行輸入 PING命令及目標主機的 IP地址或域名后,系統開始構建 ICMP回顯請求數據包。此數據包包含 ICMP協議頭部和一定數據,默認 32字節。隨后,該數據包被交給 IP層。
IP層在數據包中添加源 IP地址和目標 IP地址等控制信息,組裝成完整的 IP數據包。接著,需獲取目標主機的 MAC地址。若目標主機與源主機在同一網段,IP層會查詢本地 ARP緩存表,若有對應映射則直接獲取 MAC地址;若沒有,則發送 ARP請求廣播來獲取。若目標主機與源主機不在同一網段,IP層會將數據包交給路由處理,由路由器依據路由表轉發,路由器同樣需獲取下一跳的 MAC地址。
數據鏈路層獲取目標 MAC地址后,構建數據幀,將 IP 數據包封裝其中,附上源和目的 MAC地址及控制信息,再將數據幀發送出去。
2.接收響應
目標主機接收到數據幀后,檢查目的 MAC地址,若相符則接收并提取 IP數據包,交給 IP層。IP層檢查無誤后,將其交給 ICMP協議。
ICMP協議構建 ICMP回顯應答數據包,把請求包中的數據復制過來,再交給 IP層。IP層封裝成 IP數據包,數據鏈路層構建新的數據幀,以源主機為目的地址發送出去。
3.結果處理
源主機收到應答數據包后,數據鏈路層和 IP層依次處理,將 ICMP應答包交給 ICMP協議。ICMP協議記錄當前時間,結合請求時的時間戳計算往返時間。若發送多個請求包,系統會統計未收到應答的數據包數量,計算丟包率。通過往返時間和丟包率,用戶可判斷網絡的連通性和質量。
6報文解析
ICMP(Internet Control Message Protocol,互聯網控制消息協議)是用于網絡設備間傳遞控制消息的協議,通常用于網絡診斷與錯誤報告。ICMP報文由類型字段、代碼字段、校驗和及數據部分構成。常見的 ICMP報文類型包括回顯請求(ping)和回顯應答、目的不可達、超時等。
以下是 ICMP回顯請求和應答報文的基本格式:
字段名稱 | 長度(字節) | 回顯請求值 | 回顯應答值 | 描述 |
類型(Type) | 1 | 8 | 0 | 標識ICMP報文的類型 |
代碼(Code) | 1 | 0 | 0 | 與類型字段一起決定ICMP報文具體種類 |
檢驗和(Checksum) | 2 | 計算得出 | 計算得出 | 用于校驗整個ICMP數據包的完整性 |
標識符(Identifier) | 2 | 發送進程ID | 與請求相同 | 用于標識發送端發送的報文 |
序列號 (Sequence Number) |
2 | 遞增序號 | 與請求相同 | 用于標識發送端發送的報文的順序號 |
數據(Data) | 可變 | 用戶定義 | 與請求相同 | 包含要返回給發送者的數據 |
|報文解析| Internet Control Message Protocol Type: 8 (Echo (ping) request) (ICMP類型字段為8,表示這是一個回顯請求(Ping請求)) Code: 0 (ICMP代碼字段為 0,表示回顯請求的正常類型) Checksum: 0xe1a7 [correct] (0xe1a7是校驗和值,狀態為 Good,表示報文有效) [Checksum Status: Good] Identifier (BE): 4661 (0x1235) (表示標識符以大端格式存儲,值為 4661(十進制)) Identifier (LE): 13586 (0x3512) (LE表示標識符以小端格式存儲,值為 13586) Sequence Number (BE): 17186 (0x4322) (序列號字段,用于標識回顯請求的序列) Sequence Number (LE): 8771 (0x2243) (序列號幫助配對請求與響應) [Response frame: 15] (此字段表示接收到的響應幀數量,通常用于指示響應的順序或超時) Data (128 bytes) (包括用于測試的實際數據或填充數據) |報文原文| 08 00 e1 a7 12 35 43 22
7實現過程
接下來,我們在W55MH32上實現PING命令。
注意:測試實例需要PC端和W55MH32處于同一網段。
do_ping()函數起到了控制PING操作流程的作用,它決定了是否繼續進行PING操作,以及在操作完成后關閉Socket連接。
這個函數需要主循環中調用,如下圖所示:
while (1) { do_ping(SOCKET_ID, dest_ip, ping_num); } void do_ping(uint8_t sn, uint8_t *remote_ip, uint8_t req_num) { if (req >= req_num) { close(sn); return; } else { ping_count(sn, req_num, remote_ip); } }
do_ping()函數需要傳入3個參數,分別是spcket號,目標主機IP,PING請求次數。
如果req大于req_num,說明已經達到了指定的 PING請求次數,此時調用close()函數關閉指定的 Socket連接,然后函數返回,結束本次 PING操作。
如果req小于req_num,則調用ping_count()函數。PING操作主要在ping_count()函數內進行,進入該函數之后會執行以下步驟。
ping_count()函數如下:
void ping_count(uint8_t s, uint16_t pCount, uint8_t *addr) { uint16_t rlen, cnt, i; cnt = 0; for (i = 0; i < pCount + 1; i++) { if (i != 0) { // 輸出計數編號 printf("No.%d ", i); } switch (getSn_SR(s)) { case SOCK_CLOSED: close(s); // 創建Socket IINCHIP_WRITE(WZTOE_Sn_PROTO(s), IPPROTO_ICMP); if (Socket(s, Sn_MR_IPRAW, 3000, 0) != 0) { // Socket創建失敗(此處可添加錯誤處理) } // 等待Socket注冊完成 while (getSn_SR(s) != SOCK_IPRAW); break; case SOCK_IPRAW: // 發送Ping請求 ping_request(s, addr); req++; // 請求計數遞增 // 等待Ping響應 while (1) { // 檢查是否有接收數據 if ((rlen = getSn_RX_RSR(s)) > 0) { // 處理Ping響應 ping_reply(s, addr, rlen); rep++; // 響應計數遞增 if (ping_reply_received) { break; // 收到響應后退出等待 } } // 超時判斷(cnt*5ms >= 5000ms時超時) if (cnt > 1000) { printf("Request Time outrnrn"); cnt = 0; break; } else { cnt++; delay_ms(5); // 5ms延遲 } } break; default: break; } // 當請求數達到設定值時,輸出統計結果 if (req >= pCount) { printf("Ping Request = %d, Ping Reply = %d, Lost = %drn", req, rep, req - rep); } } }
進入該函數后,程序會執行一個狀態機,首先初始化 cnt為 0并開啟 for循環。根據Socket的狀態進行不同操作,當Socket為 SOCK_CLOSED時,Socket關閉,設置協議,創建 Sn_MR_IPRAW模式的 Socket,并等待 Socket狀態變為 SOCK_IPRAW;當Socket為 SOCK_IPRAW時,發送 ping請求,進入內層 while循環,若接收長度大于 0則處理 ping回復,超過一定時間無回復則輸出超時信息,同時會根據 cnt進行計數和延遲處理;默認情況不做處理,滿足條件時輸出 ping請求、回復和丟失的統計信息。
步驟一:發送 PING請求
ping_request()函數在ping_count()函數中,當Socket狀態為SOCK_IPRAW時被調用,從而實現按照設定的次數發送 PING請求。
ping_request()函數如下:
void ping_request(uint8_t s, uint8_t *addr) { uint16_t i; ping_reply_received = 0; // 重置響應接收標志 // 初始化Ping請求包數據 PingRequest.Type = PING_REQUEST; // 設置類型為Ping請求 PingRequest.Code = CODE_ZERO; // 代碼字段置0 PingRequest.ID = htons(RandomID++); // 設置ID(網絡字節序),ID自增 PingRequest.SeqNum = htons(RandomSeqNum++); // 設置序列號(網絡字節序),序列號自增 // 填充數據區(簡單填充0-7循環值) for (i = 0; i < BUF_LEN; i++) { PingRequest.Data[i] = (i) % 8; } // 計算校驗和 PingRequest.CheckSum = 0; // 先清零校驗和字段 PingRequest.CheckSum = htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); // 計算并設置校驗和(網絡字節序) // 發送Ping請求 if (sendto(s, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, 3000) == 0) { printf("Fail to send ping-reply packetrn"); // 發送失敗提示 } else { // 發送成功,輸出目標IP printf("Ping:%d.%d.%d.%drn", (addr[0]), (addr[1]), (addr[2]), (addr[3])); } }
該函數ping_request的主要作用是發送一個Ping請求。首先初始化一些請求參數,包括請求類型、代碼、隨機生成的 ID和序列號,填充數據并計算校驗和。接著嘗試使用sendto()函數發送請求,根據發送結果輸出相應信息,包括失敗提示和請求目標的地址信息。
步驟二:接收并解析 PING回復:
ping_reply()函數在ping_count()函數中,當檢測到Socket收緩沖區有數據(rlen>0)時被調用,從而實現對接收到的 PING回復進行解析處理。ping_reply()函數負責接收和解析PING回復數據包,根據不同的數據包類型進行相應的處理,并在解析成功后打印相關信息。
ping_reply()函數如下:
void ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen) { uint16_t tmp_checksum; uint16_t len; uint16_t i; uint8_t data_buf[136]; uint16_t port = 3000; PINGMSGR PingReply; // 接收數據 len = recvfrom(s, data_buf, rlen, addr, &port); // 處理Ping響應包(ICMP Echo Reply) if (data_buf[0] == PING_REPLY) { // 解析Ping響應包數據 PingReply.Type = data_buf[0]; PingReply.Code = data_buf[1]; PingReply.CheckSum = (data_buf[3] < 8) + data_buf[2]; // 組合校驗和(高位+低位) PingReply.ID = (data_buf[5] < 8) + data_buf[4]; // 組合ID(高位+低位) PingReply.SeqNum = (data_buf[7] < 8) + data_buf[6]; // 組合序列號(高位+低位) // 復制數據部分 for (i = 0; i < len - 8; i++) { PingReply.Data[i] = data_buf[8 + i]; } // 校驗和驗證 tmp_checksum = ~checksum(data_buf, len); if (tmp_checksum != 0xffff) { printf("tmp_checksum = %xrn", tmp_checksum); // 校驗和不匹配提示 } else { // 校驗通過,輸出響應信息 printf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%drnrn", (addr[0]), (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); ping_reply_received = 1; // 標記已收到響應 } } // 處理Ping請求包(本地作為接收方時收到的ICMP Echo Request) else if (data_buf[0] == PING_REQUEST) { // 解析Ping請求包數據 PingReply.Code = data_buf[1]; PingReply.Type = data_buf[2]; PingReply.CheckSum = (data_buf[3] < 8) + data_buf[2]; PingReply.ID = (data_buf[5] < 8) + data_buf[4]; PingReply.SeqNum = (data_buf[7] < 8) + data_buf[6]; // 復制數據部分 for (i = 0; i < len - 8; i++) { PingReply.Data[i] = data_buf[8 + i]; } // 校驗和驗證 tmp_checksum = PingReply.CheckSum; PingReply.CheckSum = 0; if (tmp_checksum != PingReply.CheckSum) { printf(" n CheckSum is incorrect %x should be %x n", (tmp_checksum), htons(PingReply.CheckSum)); } else { // 校驗通過可在此添加處理邏輯 } // 輸出請求信息 printf(" Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytesrn", (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen + 6)); ping_reply_received = 1; // 標記已收到請求 } // 處理未知類型消息 else { printf(" Unknown msg. n"); // 修正原注釋拼寫錯誤(Unkonwn -?> Unknown) } }
ping_reply()函數主要用于處理接收的信息。它通過 recvfrom接收數據,根據數據包頭信息判斷是回復還是請求,提取并解析相關信息,計算校驗和并進行檢查,根據不同情況輸出信息,如錯誤提示、回復來源信息或請求來源信息等,并設置接收狀態標志。
8運行結果
燒錄例程運行后,首先進行了PHY鏈路檢測,然后打印設置網絡信息,最ping目標IP收到回復,如下圖所示:
9總結
本文講解了如何在 W55MH32芯片上通過 IPRAW模式實現 ICMP協議中的 PING命令,以進行網絡連通性測試,通過實戰例程展示了從發送 PING請求、接收并解析回復到統計結果的完整過程。文章詳細介紹了 IPRAW模式和 PING命令的概念、特點、應用場景、基本工作流程和報文解析,幫助讀者理解其在網絡測試和故障排查中的實際應用價值。
下一篇文章將聚焦 ARP協議,解析其核心原理及在網絡通信中的應用,同時講解如何在W55MH32上實現 ARP協議,敬請期待!
WIZnet是一家無晶圓廠半導體公司,成立于 1998年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU?面向各種應用中的嵌入式互聯網設備。
WIZnet在全球擁有 70多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。
香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
嵌入式
+關注
關注
5158文章
19730瀏覽量
318562 -
Ping
+關注
關注
0文章
70瀏覽量
16472
發布評論請先 登錄
即刻啟程,踏上W55MH32高性能以太網單片機學習之路!

WIZnet W55MH32以太網單片機開發教程 第十一章 通用定時器(上篇)

第二章 W55MH32 DHCP示例

第五章 W55MH32 UDP示例

第六章 W55MH32 UDP?Multicast示例

第九章 W55MH32 HTTP Server示例

第十章 W55MH32 SNTP示例

第十一章 W55MH32 SMTP示例

第十二章 W55MH32 NetBIOS示例

第十三章 W55MH32 UPnP端口轉發示例

第十四章 W55MH32 TFTP示例

第十五章 W55MH32 SNMP示例

第十七章 W55MH32 ARP示例

第十八章 W55MH32 FTP_Server示例

第二十六章 W55MH32?上位機搜索和配置示例

評論