一 實驗背景
之前一段時間專門研究了固件升級的方法,主要是通過網頁或者上位機軟件實現遠程固件升級。最近正好在研究 TFTP 簡單文件傳輸協議,於是我就嘗試給設備添加聯網功能,通過 TFTP 實現網絡更新固件,而後發現這種升級方式所佔設備內存小,可以穿越多數防火牆,並且不需要去設備現場,在辦公室通過網絡就能將成千上萬用戶或設備的固件升級,簡單高效。
其實現在很多設備都已經具有網絡固件升級功能,例如我們經常用到的電視機頂盒、家用無線路由器等設備。很多設備升級內核都是通過 TFTP 協議上傳的,因為 TFTP 實現非常的簡單,比如自己家裡用的路由器就可以通過 TFTP 協議升級。
二 TFTP 基礎普及
TFTP 是 TCP/IP 協議族中的一個用來在客戶機與服務器之間進行簡單文件傳輸的協議,基於 UDP 協議實現,端口號為 69。通過 TFTP 協議,可以實現網絡中兩台計算機之間的文件上傳與下載,如文件備份,為無盤工作站下載引導文件,下載初始化代碼到打印機、集線器和路由器。當然,還有就是我們本次用到的對設備進行固件升級。
TFTP 協議是專為小文件傳輸設計的,提供不復雜、開銷不大的文件傳輸服務,缺乏標准 FTP 協議的許多特征。TFTP 只能從遠程服務器上讀、寫文件(郵件)或者讀、寫文件傳送給遠程服務器。它不能列出目錄並且當前不提供用戶認證。當前 TFTP 有 3 種傳輸模式: netASCII 模式即 8 位 網絡 ASCII 碼 ;octet 即八位組模式;郵件模式,這種模式現在已經廢止不用了。主機雙方也可以自己定義其它模式。
TFTP 基於 UDP 協議實現,而 UDP 使用 IP。因此一個 TFTP 包中會有如圖 1 所示的以下幾段:本地媒介頭,IP 頭,UDP 數據報頭,TFTP 數據報。TFTP 在 IP頭中不指定任何數據,但是它使用 UDP 中的源和目標端口以及包長度域。由TFTP 使用的包標記(TID)在這裡被用做端口,因此 TID 必須介於 0 到 65,535 之間。圖中顯示了 5 種 TFTP 報文格式,每個報文格式 TFTP 報文的頭兩個字節表示操作碼。之後對於不同的報文格式存在差異。
圖1 TFTP 報文格式
下面分別對每個報文包進行分析:
RRQ 和 WRQ 包的報文格式如表1所示。
RRQ/WRQ 包
Opcode
Filename
0
Mode
0
2 bytes
string
1 byte
string
1 byte
表 1 RRQ 和 WRQ 包的報文格式
RRQ (讀請求)報文由客戶使用,用來建立一條從服務器讀數據的連接。WRQ(寫請求)報文由客戶使用,用來建立一條把數據寫到服務器的連接,它的格式與RRQ 相同,RRQ 包的操作碼為 1,WRQ 包的操作碼為 2。Filename(文件名字段)說明客戶要讀或寫的位於服務器上的文件,文件名是 NETASCII 碼字符,以 0 結束。Mode (模式字段)是一個 ASCII 碼串 netascii 或 octet(大小寫可任意組合),同樣以0字節結束。netascii 表示數據是以成行的ASCII碼字符組成,以兩個字節—回車字符後跟換行字符(稱為 CR / LF)作為行結束符。 OCTET 模式用於傳輸文件,這種文件在源機上以8位格式存儲。在使用MAIL模式時,用戶可以在 FILE 處使用接收人地址,這個地址可以是用戶名或用戶名 @ 主機的形式,如果是後一種形式,允許主機使用電子郵件傳輸此文件。如果使用MAIL類型,包必須以 WRQ 開始,否則它與NETASCII完全一樣。
DATA 包的報文格式如表2所示。
DATA 包
Opcode
Block
0
2 bytes
2 bytes
Data
表 2 DATA 包的報文格式
DATA 數據包的 opcode 為 3,它還包括有一個數據塊號和數據。數據塊號域從 1開始編碼,每個數據塊加 1,這樣接收方可以確定這個包是新數據還是已經接收過的數據。數據域從0字節到512字節。如果數據域是 512 字節則它不是最後一個包,如果小於 512 字節則表示這個包是最後一個包。如果最後一個包正好為 512字節,則再發送一個0字節的包用於表示結束。
ACK 包的報文格式如表3所示。
ACK 包
ACK 包
Opcode
Block
2 bytes
2 bytes
表 3 ACK 包的報文格式
ACK 包用於確認數據包已收到。ACK 包的操作碼為 4。當接收方收到一個數據包後,會向發送方發送一個ACK包;而發送方則會在收到一個 ACK 包後繼續發送下一個包。若發送完未能收到ACK包,則會使用超時機制,重新發送剛才的數據包。除了 ACK 和用於中斷的包外,其它的包均需得到確認。發出新的數據包等於確認上次的包。WRQ 和 DATA 包由 ACK 或 ERROR 數據包確認,而 RRQ 數據包由 DATA 或 ERROR 數據包確認。
ERROR 包的報文格式如表4所示。
ERROR 包
Opcode
ErrorCode
ErrMsg
0
2 bytes
2 bytes
string
1 byte
表 4 ERROR 包的報文格式
一個 ERROR 包的操作碼是 5。此包可以被其它任何類型的包確認,錯誤碼指定錯誤的類型。它用於服務器不能處理讀請求或寫請求的情況。在文件傳輸過程中的讀和寫差錯也會導致傳送這種報文,接著停止傳輸。差錯編號字段給出一個數字的差錯碼,跟著是一個 ASCII 表示的差錯報文字段,可能包含額外的操作系統說明的信息。錯誤的值和錯誤的意義如下:
0 未定義,請參閱錯誤信息
1.文件未找到
2.訪問非法
3.磁盤滿或超過分配的配額
4.非法的TFTP操作
5.未知的傳輸ID
6.文件已經存在
7.沒有類似的用戶
三 TFTP 嵌入式系統實現方法
TFTP 協議執行過程中,任何一個傳輸進程都以 WRQ(請求寫入遠程系統)或RRQ(請求讀取遠程系統)開始,收到一個確定應答並建立一個連接。創建連接時,通信雙方隨機選擇一個 TID,因為是隨機選擇的,因此兩次選擇同一個ID的可能性就很小了。每個包包括兩個 TID,發送者 ID 和接收者 ID。這些ID用於在UDP通信時選擇端口,在第一次請求的時候它會將請求發到 TID 69,也就是服務器的 69 端口上。應答時,服務器使用一個選擇好的 TID 作為源 TID,並用上一個包中的 TID 作為目的 ID 進行發送。這兩個被選擇的 ID 在隨後的通信中會被一直使用。
連接成功以後文件就以固定的 512 字節塊的長度進行傳送。每個數據包都包含一個數據塊,塊號從1開始而且是連續的。因此對於寫入請求的確定是一個比較特殊的情況,因此它的包的包號是 0。在發送下一個包之前,數據塊必須得到確認響應包的確認。如果一個數據包的大小小於 512 字節,則表明傳輸結束。如果包在網絡中丟失,接收端就會在超時以後重新傳輸最後一個未被確認的數據包(可能是數據也可能是確認響應),這就導致丟失包的發送者重新發送丟失包。通信的雙方都是數據的發出者與接收者,一方傳輸數據接收應答,另一方發出應答接收數據。發送者需要保留一個包在手頭用於重新發送,由 LOCK 確認響應保證所有過去的包都已經收到。大部分的錯誤會導致連接中斷,錯誤由一個錯誤的數據包引起。這個包不會被確認,也不會被重新發送,因此另一方無法接收到。如果錯誤包丟失,則使用超時機制。錯誤主要是由下面三種情況引起的:不能滿足請求,收到的數據包內容錯誤(不能由延時或重發解釋),對需要資源的訪問丟失(如硬盤滿)。TFTP 只在一種情況下不中斷連接,這種情況是源端口不正確,在這種情況下,指示錯誤的包會被發送到源機。這個協議限制很多,這都是為了實現起來比較方便而進行的。
TFTP的工作過程很像停止等待協議,發送完一個文件塊後就等待對方的確認,確認時應指明所確認的塊號。發送完數據後在規定時間內收不到確認就要重發數據PDU(協議數據單元),發送確認 PDU 的一方若在規定時間內收不到下一個文件塊,也要重發確認 PDU。這樣保證文件的傳送不致因某一個數據報的丟失而告失敗。通過下邊的圖片來了解 TFTP 協議的通信流程:
圖 2 TFTP通信流程
四 測試 TFTP 客戶端
了解了 TFTP 協議之後,下面就讓我們通過 WIZnet W5500EVB M3 做一個嵌入式 TFTP 客戶端的簡單實驗。
1.實驗目的:建立一個 TFTP 客戶端
2.硬件環境:板載 LED 燈
圖3 W5500EVB實物板
3.開發工具: MDK5(版本不一樣,需要稍加改動)
4.測試軟件:串口調試助手, TFTP32(可從網絡下載)
下面以 W5500 為 TFTP 客戶端,講述如何測試實現TFTP通信過程。
1. 在網上下載 Tftp32 軟件,不需安裝直接點擊 Tftpd32 軟件就可以應用。
2. 配置 TFTP 服務器信息。如圖3所示,Setting——>TFTP。接著在 Base Directory 選項設置需要下載文件路徑,本文測試代碼 bin 文件路徑為 E: 工作資料 TFTPLEDbin。一定注意需下載的文件路徑要與你的文件位置保持一致,否則服務器找不到文件而提示錯誤信息。
圖 4 TFTP 服務器設置
3. 接著用網線把 PC 和 W5500EVB 連接,打開串口軟件,選擇正確的 COM 口並打開串口,以獲取調試信息。
4. 下載編譯好的 TFTP 代碼並復位 W5500EVB,在串口輸入您需要下載 APP 文件的名字發送並點擊回車,可以看到如圖4所示文件下載過程。發送文件名為app.bin, 接著就是 TFTP 服務器與客戶端之間文件傳輸過程,如果傳輸成功會提示 TFTP SUCCEED 信息。
5. 然後觀察 TFTP32 軟件提示信息,如圖5所示。點擊 Show Dir 彈出 Tftp32 Directory 對話框,可以看到相關的文件下載信息。
6. 觀察 APP 應用程序是否成功下載並啟動,本次操作已LED流水燈為例。串口信息提示 TFTP SUCCEED,說明文件下載成功,之後又打印了APP的串口提示信息。說明 APP 更新成功,觀察開發板也發現LED燈在按照設定的要求進行閃爍。
圖5 串口監測信息
圖 6 TFTP Server 軟件監測信息
五 總結
本文主要實現了基於 STM32F103+W5500 的嵌入式系統 TFTP 的設計方案,並展示了如何用 TFTP32 軟件進行簡單文件的下載傳輸。雖然只是簡單討論 TFTP 協議的相關理論及實現,但稍微復雜一點的 FTP 協議,POP3 協議,SNMP 協議也都可以通過類似的分析來實現的。隨著物聯網事業的發展,越來越多的嵌入式設備都將擁有聯網功能,相信 TFTP 協議的作用將越來越重要。在當下物聯網時代,想必還有其他應用也會遇到類似問題,希望本文能對做網絡設備開發的朋友有所幫助。
源程序及程序工具包下載:http://pan.baidu.com/s/1i3CQen7