一、 概述 U-boot中的TFTP用于發(fā)送較小的文件。下層使用UDP協(xié)議,發(fā)送使用UDP 69端口,每次發(fā)送的最大分組為512 Bytes。發(fā)送雙方采用超時重傳機制。數(shù)據(jù)傳輸模式為octet模式( 二進制模式?。?/span> 在U-boot中使用tftp功能可以使用如下命令: tftp MemoryAddress FileName 其中MemoryAddress為放入文件的內存首地址,FileName為傳送文件的文件名(文件需放在tftp默認目錄下)。 二、 使用TFTP 使用TFTP傳送文件的步驟: 1 使用時已經(jīng)初始化以下變量: NetOurIP (本機IP地址,定義在Net.c文件) NetServerIP(TFTP服務器的IP地址,定義在Net.c文件) BootFile (需要傳送文件的文件名,定于在Tftp.c) NetOurGatewayIP (本機的網(wǎng)關地址) NetOurSubnetMask (本機子網(wǎng)掩碼) 2 調用TftpStart 函數(shù)開始文件傳送。 三、 TFTP實現(xiàn) (1)客戶端狀態(tài) TFTP使用一個變量TftpState來描述TFTP客戶端可能的5種狀態(tài):
(2)包類型 使用TFTP傳送的包分為6種類型:
(3)各種包結構 TFTP協(xié)議中各種包的結構:
具體到U-boot中客戶端發(fā)送的各種包的結構: RRQ(請求讀的包的結構):
ACK(確認幀)結構:
(4)主要函數(shù)及作用 U-boot中與tftp協(xié)議有關的文件有tftp.c與tftp.h文件,主要函數(shù)包括:
static __inline__ void store_block (unsigned block, uchar * src, unsigned len); /* 根據(jù)預先設定的地址load_addr決定將首地址為src,長度為len的block個數(shù)據(jù)塊寫入flash 或寫入內存*/
static void TftpSend (void) ; /* 根據(jù)TftpState變量的不同值發(fā)送不同的 Tftp包 (使用UDP協(xié)議發(fā)送) */
static void TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) ; /* 處理收到的Tftp包 */
static void TftpTimeout (void); /* 超時處理函數(shù) */
void TftpStart (void); /* 初始化各個需要的數(shù)據(jù) 然后開始發(fā)送TFTP讀請求 */
(5) 流程 TFTP總體流程: 首先客戶端發(fā)出讀寫請求。如果服務器批準此請求,則打開連接,并第一個數(shù)據(jù)包??蛻舳耸盏綌?shù)據(jù)包后發(fā)回確認,而服務器發(fā)出下一個數(shù)據(jù)包以前必須得到客戶對上一個數(shù)據(jù)包的確認。如果數(shù)據(jù)包在傳輸過程中丟失,服務器方會在超時后重新傳輸最后一個未被確認的數(shù)據(jù)包。
發(fā)送的數(shù)據(jù)包一般為512字節(jié),如果一個數(shù)據(jù)包小于 512 字節(jié),則表示這個包是最后一個包,如果發(fā)送的數(shù)據(jù)正好是 512 的整數(shù)倍,發(fā)送完后再發(fā)一個空包。 客戶端程序流程: <1>客戶端設定NetOurIP 、NetServerIP、BootFile 變量的值。 <2>調用TftpStart函數(shù),TftpStart函數(shù)完成如下的6步工作: 1若BootFile為空,則使用默認文件名;否則使用BootFile為傳送的文件名。 2比較客戶端和服務器的子網(wǎng)地址,判斷兩者是否在同一個子網(wǎng)內。 3設定超時處理函數(shù)為TftpTimeout 。 4設置處理接收到的TFTP包的函數(shù)為TftpHandler。 5初始化服務器端口、本機端口、超時次數(shù)為0、初始狀態(tài)為RRQ 6調用TftpSend函數(shù)發(fā)送TFTP讀取請求。 <3> TftpSend函數(shù)根據(jù)TftpState 發(fā)送不同的包,同時TftpHandler函數(shù)根據(jù)包的類型和當前客戶端的狀態(tài)(TftpState) 處理接收到的包。
|
|