來自:http://blog.163.com/czblaze_3333/blog/static/208996228201272295236713/
Kermit協議
報文格式:
1. MARK,起始標記START_CHAR,為 0x01(CTRIL-A);
2. LEN,報文剩余部分的長度,取值范圍0~94,報文最大長度96,長度不包含換行符或者制表符;
3. SEQ,數據包編號,取模64,;
4. TYPE,k_state數據包類型
D |
數據報文 |
Y |
ACK報文(不能轉換編碼) |
N |
NAK,未收到 |
S |
發送初始化報文 |
B |
傳輸結束 |
F |
文件頭部 |
Z |
文件結束 |
E |
Error |
Q,T |
保留 |
NAK包用來說明等待的包沒有正常接收,它不提供別的信息,例如不提供請求的服務之類。它的數據域總是空的。T報文用於內部kermit程序說明超時。
5.DATA,0~31,127這33個控制字符需要進行轉換,前面加’#’,0~31之間加上64,127減去64處理。加過前綴的序列不要分散在不同的包。前綴字符也包含在計數之內。除S,I,A報文及其響應,都不能進行編碼。
6.CHECK,假如S是整個報文字符的算術和,只是校驗0~5位的和。
這是基本的默認塊校驗,所有的kermit都必須可以實施。
kermit報文發送過程
1.發送方首先發送一個初始化報文S(以0x01起始),確定報文長度,超時時間等;-->
<--接收方返回一個確認報文Y,在報文數據段存放自己的參數
2.發送方發送文件頭報文F,在數據段包含文件名-->(如果發送多個文件,重復此步驟即可)
<--返回ACK,數據段可以不包含數據
3.開始發送文件內容,數據報文D,不在可打印ascii碼范圍內的,需要被提前替換成等價的可打印字符,每個數據報文都會收到ACK。
4.文件數據發送結束后,發送方發送文件尾報文Z,收方接收后確認。
5.沒有文件需要發送時,發送傳輸結束報文B,並接收ACK,然后關閉連接,物理連接依然保留
每個報文都有編號,0~63之間。
XMODEM
這種古老的傳輸協議速度較慢,但由於使用了CRC錯誤偵測方法,傳輸的准確率可高達99.6%,傳輸信息單位是“包=128B”,傳輸速度慢,適合電話線路質量差的情況下使用。
Xmodem是最廣泛使用的文件傳輸協議之一。原始的Xmodem協議使用128字節的數據包和一個簡單的“校驗和”的錯誤檢測方法。隨后的版本XMODEM-CRC,使用了更安全的循環冗余校驗(CRC)錯誤檢測方法。 Xmodem協議始終首先嘗試使用CRC。如果發送者不響應CRC的請求,接收器轉移到校驗和模式,並繼續其請求傳輸。
1.Xmodem協議是什么?
XMODEM協議是一種串口通信中 廣泛用到的異步文件傳輸協議。分為標准Xmodem和1k-Xmodem兩種,前者以128字節塊的形式傳輸數據,后者字節塊為1k即1024字節,並且每個塊都使用一個校驗和過程來進行錯誤檢測。在校驗過程中如果接收方關於一個塊的校驗和與它在發送方的校驗和相同時,接收方就向發送方發送一個確認字節 (ACK)。由於Xmodem需要對每個塊都進行認可,這將導致性能有所下降,特別是延時比較長的場合,這種協議顯得效率更低。
除了Xmodem,還有Ymodem,Zmodem協議。他們的協議內容和Xmodem類似,不同的是Ymodem允許批處理文件傳輸,效率更高;Zmodem則是改進的了Xmodem,它只需要對損壞的塊進行重發,其它正確的塊不需要發送確認字節。減少了通信量。
2.Xmodem協議相關控制字符
SOH 0x01
STX 0x02
EOT 0x04
ACK 0x06
NAK 0x15
CAN 0x18
CTRLZ 0x1A
3.標准Xmodem協議(每個數據包含有128字節數據)幀格式
2-1
SOH |
信息包序號 |
信息包序號的補碼 |
數據區段 |
校驗和 |
4.1k-Xmodem(每個數據包含有1024字節數據)幀格式
2-2
STX |
信息包序號 |
信息包序號的補碼 |
數據區段 |
校驗和 |
5.數據包說明
對於標准Xmodem協議來說,如果傳送的文件不是128的整數倍,那么最后一個數據包的有效內容肯定小於幀長,不足的部分需要用CTRL- Z(0x1A)來填充。這里可能有人會問,如果我傳送的是bootloader工程生成的.bin文件,mcu收到后遇到0x1A字符會怎么處理?其實如 果傳送的是文本文件,那么接收方對於接收的內容是很容易識別的,因為CTRL-Z不是前128個ascii碼,不是通用可見字符,如果是二進制文件,mcu其實也不會把它當作代碼來執行。哪怕是excel文件等,由於其內部會有些結構表示各個字段長度等,所以不會讀取多余的填充字符。否則 Xmodem太弱了。對於1k-Xmodem,同上理。
6.如何啟動傳輸?
傳輸由接收方啟動,方法是向發送方發送"C"或者NAK(注意,這里提到的NAK是用來啟動傳輸的。以下我們會看到NAK還可以用來對數據產生重傳的機 制)。接收方發送NAK信號表示接收方打算用累加和校驗;發送字符"C"則表示接收方想打算使用CRC校驗(具體校驗規則下文Xmodem源碼,源碼勝於雄辯)。
7.傳輸過程
當接收方發送的第一個"C"或者NAK到達發送方,發送方認為可以發送第一個數據包,傳輸已經啟動。發送方接着應該將數據以每次128字節的數據加上包頭,包號,包號補碼,末尾加上校驗和,打包成幀格式傳送。
發送方發了第一包后就等待接收方的確認字節ACK,收到接收方傳來的ACK確認,就認為數據包被接收方正確接收,並且接收方要求發送方繼續發送下一個包; 如果發送方收到接收方傳來的NAK(這里,NAK用來告訴發送方重傳,不是用來啟動傳輸)字節,則表示接收方請求重發剛才的數據包;如果發送方收到接收方傳來的CAN字節,則表示接收方請求無條件停止傳輸。
8.如何結束傳輸?
如果發送方正常傳輸完全部數據,需要結束傳輸,正常結束需要發送方發送EOT 字節通知接收方。接收方回以ACK進行確認。當然接收方也可強制停止傳輸,當接收方發送CAN 字節給發送方,表示接收方想無條件停止傳輸,發送方收到CAN后,不需要再發送EOT確認(因為接收方已經不想理它了,呵呵)。
9.特殊處理
雖然數據包是以 SOH 來標志一個信息包的起始的,但在 SOH 位置上如果出現EOT則表示數據傳輸結束,再也沒有數據傳過來。
接收方首先應確認數據包序號的完整性,通過對數據包序號取補,然后和數據包序號的補碼異或,結果為0表示正確,結果不為0則發送NAK請求重傳。
接收方確認數據包序號正確后,然后檢查是否期望的序號。如果不是期望得到的數據包序號,說明發生嚴重錯誤,應該發送一個 CAN 來中止傳輸。
如果接收到的數據包的包序號和前一包相同,那么接收方會忽略這個重復包,向發送方發出 ACK ,准備接收下一個包。
接收方確認了信息包序號的完整性和是正確期望的后,只對 128 字節的數據區段進行算術和校驗,結果與幀中最后一個字節(算術校驗和)比較,相同發送 ACK,不同發送NAK。
10.校驗和的說明
Xmodem協議支持2種校驗和,它們是累加和與CRC校驗。
當接收方一開始啟動傳輸時發送的是NAK,表示它希望以累加和方式校驗。
當接收方一開始啟動傳輸時發送的是字符“C”,表示它希望以CRC方式校驗。
可能有人會問,接收方想怎么校驗發送方都得配合嗎,難道發送方必須都支持累加和校驗和CRC校驗?事實上Xmodem要求支持CRC的就必須同時支持累加和,如果發送方只支持累加和,而接收方用字符“C”來啟動,那么發送方只要不管它,當接收方繼續發送“C”,三次后都沒收到應答,就自動會改為發送 NAK,因為它已經明白發送方可能不支持CRC校驗,現在接收方改為累加和校驗和發送方通訊。發送方收到NAK就趕緊發送數據包響應。
YMODEM
由XMODEM演變來,效率可靠性高,包=128*8B;一次傳輸可發送或接受幾個文件。
XMODEM1K本質上是XMODEM CRC1K(1024字節)的數據包。在某些系統中,它也可以被稱為YMODEM。有些通信軟件程序,著名的Procomm的1.x版本中,也將XMODEM-1K 稱為YMODEM,但在Procomm的2.0版本中不再稱XMODEM-1K為 YMODEM。
YMODEM -G:YMODEM-G是一種YMODEM的變種。它被設計成用於支持錯誤控制的調制解調器。該協議不提供軟件糾錯或恢復,但預計調制解調器提供的服務。這是一個流媒體協議,在一個連續的數據流上發送和接收1K的數據包,直顯式停止。每塊被發送后,它不會等待肯定的確認,而是快速連續地發送塊。如果任何塊傳輸失敗,本次傳輸將會失敗退出。
文件傳輸過程的開啟:
(1)開啟是由接收方開啟傳輸,它發一個大寫字母C開啟傳輸。然后進入等待(SOH)狀態,如果沒有回應,就會超時退出。
(2)發送方開始時處於等待過程中,等待C。收到C以后,發送(SOH)數據包開始信號,發送序號(00),補碼(FF),“文件名”,“空格”“文件大小”“除去序號外,補滿128字節”,CRC校驗兩個字節。進入等待(ACK)狀態。
(3)接收方收到以后,CRC校驗滿足,則發送ACK。發送方接收到ACK,又進入等待“文件傳輸開啟”信號,即重新進入等待“C”的狀態。
(4)前面接收方只是收到了一個文件名,限制正式開啟文件傳輸,Ymodem支持128字節和1024字節一個數據包。128字節以(SOH)開始,1024字節以(STX)開始。
接收方又發出一個“C”信號,開始准備接收文件。進入等待“SOH”或者“STX”狀態。
(5)發送接收到“C”以后,發送數據包,(SOH)(01序號)(FE補碼)(128位數據)(CRC校驗),等待接收方“ACK”。
(6)文件發送完以后,發送方發出一個“EOT”信號,接收方也以“ACK”回應。
然后接收方會再次發出“C”開啟另一次傳輸,若接着發送方會發出一個“全0數據包”,接收方“ACK”以后,本次通信正式結束。
(7)當然YMODEM相對於XMODEM改進的地方就在於傳輸再次開啟以后,又可以發送另外一個文件,即一次傳輸允許發送多個文件。
所用到的符號
#define MODEM_SOH 0x01 //數據塊起始字符
#define MODEM_STX 0x02 //1028字節開始
#define MODEM_EOT 0x04 //文件傳輸結束
#define MODEM_ACK 0x06 //確認應答
#define MODEM_NAK 0x15 //出現錯誤
#define MODEM_CAN 0x18 //取消傳輸
#define MODEM_C 0x43 //大寫字母C
CRC計算方法
in_ptr = mblock->buf; //指向要計算CRC的緩沖區開頭
cksum = 0; //
for (stat=mblock->len ; stat>0; stat--) //len是所要計算的長度
{
cksum = cksum^(int)(*in_ptr++) << 8; //
for (i=8; i!=0; i--)
{
if (cksum & 0x8000)
cksum = cksum << 1 ^ 0x1021;
else
cksum = cksum << 1;
}
}
ZMODEM
與上兩種不同,可以連續的數據流發送數據,效率更高。Zmodem采用了串流式(streaming)傳輸方式,傳輸速度較快,而且還具有自動改變區段大小和斷點續傳、快速錯誤偵測等功能。這是目前最流行的文件傳輸協議。
在具體的環境中,通過多次采用的xmodem的傳輸可以發現,不管是直接傳輸,還是按照網上 的說法采用rz sz傳輸,都很難將文件正確傳輸到嵌入式設備上。當采用zmodem進行傳輸的時候卻發現傳輸的效率很高,幾乎沒有失敗。
Zmodem協議有兩個顯着的特點:它是非常有效的,它提供了類似於YMODEM-G的崩潰恢復機制,Zmodem協議不會等待肯定的確認后,每個塊被發送,而是快速連續地發送塊。Zmodem協議傳輸如果因任何原因被取消或中斷,恢復后,先前傳送的信息都需要重新發送。
【背景】
在串口中傳輸文件,所用到的協議,常常有Kermit,Xmodem,Ymodem,Zmodem等,對這些協議,單獨看名字,就很容易混淆,搞不懂都是啥意思。所以,寫此文,總結各自的特點,解釋他們之間的區別和聯系。
【常見的RS232串口中所用到的傳輸協議之間的區別和聯系】
此處主要討論RS232即串口應用中,用來傳輸數據或文件的協議,主要有這些:
Kermit,Xmodem,Xmodem-1K,Ymodem,Ymodem-G,Ymodem-1K,Zmodem
協議名稱 |
相同點 |
各自特性 |
說明 |
對應軟件或命令 |
||
Kermit |
都是常見的文件傳輸協議,主要應用於RS232串口應用中 |
計算機系統中的文件傳輸和管理協議。 特點: (1)文本文件和二進制文件傳輸 (2)全雙工,半雙工(8 -bit),7-bit的串行連接; (3)協議對底層介質不做限制,跨平台性很好。 (4)已在N多平台中實現了此協議,即用途相當地廣泛。 |
Kermit名字的來源是來自Kermit the Frog from The Muppets。 |
(1)Uboot中的loadb;
|
||
XYZModem |
Xmodem |
Xmodem |
一個簡單的文件傳輸協議。將文件拆分成很多個固定大小的數據包,數據包大小是128字節,然后以一個數據包,一個數據包的形式發送數據。中間會帶有一些額外信息,用於握手協議等方面,以保證得知接收方正確接收了數據包。
要點: (1)將文件拆分,以固定大小的數據包發送。 (2)數據包大小Packet size=128Byte |
(1)Xmodem最開始是在早期的BBS系統中很流行,因為其協議足夠簡單,很容易實現。 (2)由於效率太低,導致其他很多人在此基礎上去對其擴展,以提高性能。 (3)Chuck Forsberg收集了眾多的擴展功能,以此形成Ymodem,但是由於沒有很成功的實現,導致實際應用產生各種變體。 但是其后來設計了Zmodem,由於效果太好,導致完全取代了之前的各種Xmodem的變體,包括Ymodem。 |
(1)PC Linux中的rx/sx; (2)嵌入式Linux中lrzsz; |
|
Xmodem-1K |
即Ymodem-1K,詳情參見Ymode-1K |
|
||||
Ymodem |
Ymodem |
在Xmodem(和Modem7)的基礎上開發出來的,本身協議和Xmodem是一樣的,只是在文件傳輸開始之前,多加了個Block0,用於傳輸文件名,文件大小,時間戳等信息。 |
本來協議設計者Chuck Forsberg都設計了好多可選的特性,以便於此協議可以用到多種環境和平台中,然后再換個協議名稱的。但是實際上實現了Ymodem的應用中,都只是支持了1KB的包大小和CRC模式,除此之外的其他一些特性,都沒實現,所以后來就還是沿用了舊的Ymodem這一叫法。同時,也導致了現存的很多Ymodem互相不是很兼容。 |
(1)uboot中的loady命令; (2)PC Linux中的rb/sb; (3)嵌入式Linux中lrzsz; |
||
Ymodem-1K |
此協議是在,原先Ymodem的數據包大小是(同Xmodem協議相同的)128byte的基礎上,改成了 Packet size=1024byte=1KB。 |
原先Ymodem協議中,數據包大小為1KB,是個可選的設置項。此Ymodem-1K,作為Ymodem的變體,卻沒有實現Ymodem其他的一些特性,所以,最好是叫做XModem-1K |
||||
Ymodem-G |
Ymodem的變體,流數據傳輸,用於信號很好(error-free)的傳輸環境中。 其(1)取消了CR(2)取消了,在發送下一個數據包之前,必須等待接受者的ACK |
由於取消CRC和ACK等待,此協議理論上,速度會比Zmodem快,但是實際上用此此協議的很少。因為,在16550 UAT出現之前,很明顯,此協議有個嚴重的問題,那就是緩存溢出(buffer overrun),即接受者來不及處理數據,你就接着發下一個數據包了。 |
||||
Zmodem |
從Xmodem發展而來,取代了Ymodem,算是Ymodem的終結者。 核心改進在於,引入了滑動窗口(sliding window)以提高性能。 其支持很多特性: (1)可重傳機制; (2)發送者可自動開始傳輸; (3)擴展的32位的CRC校驗; (4)可傳輸控制字符; |
|
(1)PC Linux中的rz/sz; (2)嵌入式Linux中lrzsz; |
注釋:
1.常見的Ymodem的實際是Ymodem-1K
雖然嚴格意義上說,Ymodem,數據表示128字節,但是很多具體Ymodem的實現,實際上是把Ymodem認為是1KB的數據包,即這類Ymodem的實現,雖然也叫Ymodem,但是實際上是Ymodem-1K,即:
常見的Ymodem == Ymodem-1K
例子:
(1)Windows XP自帶的超級終端(Hyper Terminal)中的Ymodem,就是默認1KB的數據包大小。
(2)而SecureCRT中的Ymodem默認是數據包是128字節,可以設置為128B或1KB。
2. lrzsz是嵌入式中常用的通過串口傳輸文件的工具,是PC版Linux中的rz/sz的精簡版。
【引用】
1. XMODEM
http://en.wikipedia.org/wiki/XMODEM
2. Ymodem
http://en.wikipedia.org/wiki/YMODEM
3. Zmodem
http://en.wikipedia.org/wiki/ZMODEM
4. Kermit
http://en.wikipedia.org/wiki/Kermit_(protocol)
5. rz(1) – Linux man page
6. lrzsz: free x/y/zmodem implementation