Xmodem協(xié)議詳解以及源代碼剖析_第1頁(yè)
Xmodem協(xié)議詳解以及源代碼剖析_第2頁(yè)
Xmodem協(xié)議詳解以及源代碼剖析_第3頁(yè)
Xmodem協(xié)議詳解以及源代碼剖析_第4頁(yè)
Xmodem協(xié)議詳解以及源代碼剖析_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、研究Xmodem協(xié)議必看的11個(gè)問(wèn)題Xmodem協(xié)議作為串口數(shù)據(jù)傳輸主要的方式之一,恐怕只有做過(guò)bootloader的才 有機(jī)會(huì)接觸一下,網(wǎng)上有關(guān)該協(xié)議的內(nèi)容要么是英語(yǔ)要么講解不詳細(xì)。筆者以前寫bootloader時(shí)研究 過(guò)1k-Xmodem,參考了不少相關(guān)資料。這里和大家交流一下我 對(duì)Xmodem的理解,多多指 教!1 . Xmodem協(xié)議是什么?XMODEM協(xié)議是一種串口通信中 廣泛用到的異步文件傳輸協(xié)議。分為標(biāo)準(zhǔn) Xmodem和1k-Xmodem兩種,前者以128字節(jié)塊的形式傳輸數(shù)據(jù),后者字節(jié)塊為1k 即1024字節(jié),并且每個(gè)塊都使用一個(gè)校驗(yàn)和過(guò)程來(lái)進(jìn)行錯(cuò)誤檢測(cè)。在校驗(yàn)過(guò)程中 如果接收方

2、關(guān)于一個(gè)塊的 校驗(yàn)和與它在發(fā)送方的校驗(yàn)和相同時(shí),接收方就向發(fā)送方 發(fā)送一個(gè)確認(rèn)字節(jié)(ACK。由于Xmodem需要對(duì)每個(gè)塊都進(jìn)行認(rèn)可,這將導(dǎo)致性能 有所下降,特別是延時(shí)比較長(zhǎng)的場(chǎng)合,這種協(xié)議顯得效率更低。除了 Xmodem,還有Ymodem , Zmodem協(xié)議。他們的協(xié)議內(nèi)容和 Xmodem類 似,不同的是Ymodem允許批處理文件傳輸,效率更高;Zmodem則是改進(jìn)的了 Xmodem,它只需要對(duì) 損壞的塊進(jìn)行重發(fā),其它正確的塊不需要發(fā)送確認(rèn)字節(jié)。減少 了通信量。2 . Xmodem協(xié)議相關(guān)控制字符SOH 0x01STX 0x02EOT 0x04ACK 0x06CAN 0x18CTRLZ 0x

3、1A3 .標(biāo)準(zhǔn)Xmodem協(xié)議(每個(gè)數(shù)據(jù)包含有128字節(jié)數(shù)據(jù)幀格式| SOH |信息包序號(hào)|信息包序號(hào)的補(bǔ)碼|數(shù)據(jù)區(qū)段|校驗(yàn)和|I I I I I I4 . 1k-Xmodem (每個(gè)數(shù)據(jù)包含有1024字節(jié)數(shù)據(jù)幀格式I STX I信息包序號(hào)I信息包序號(hào)的補(bǔ)碼I數(shù)據(jù)區(qū)段I校驗(yàn)和II I I I I I5 .數(shù)據(jù)包說(shuō)明對(duì)于標(biāo)準(zhǔn)Xmodem協(xié)議來(lái)說(shuō),如果傳送的文件不是128的整數(shù)倍,那么最后一個(gè) 數(shù)據(jù)包的有效內(nèi)容肯定小于幀長(zhǎng),不足的部分需要用CTRL- Z(0x1A來(lái)填充。這里 可能有人會(huì)問(wèn),如果我傳送的是bootloader工程生成的.bin文件,mcu收到后遇到 0x1A字符會(huì)怎么處理?其實(shí)如果

4、傳送的是文本文件,那么接收方對(duì)于接收的內(nèi)容是 很容易識(shí)別的,因?yàn)镃TRL-Z不是前128個(gè)ascii碼,不是通用可見(jiàn)字符,如果是二進(jìn) 制文件,mcu其實(shí)也不會(huì)把它當(dāng)作代碼來(lái)執(zhí) 行。哪怕是excel文件等,由于其內(nèi)部會(huì) 有些結(jié)構(gòu)表示各個(gè)字段長(zhǎng)度等,所以不會(huì)讀取多余的填充字符。否則Xmodem太弱 了。對(duì)于1k-Xmodem,同上理。6 .如何啟動(dòng)傳輸?傳輸由接U方啟動(dòng),方法是向發(fā)送方發(fā)送C或者NAK(注意哦,這里提到的 NAK是用來(lái)啟動(dòng)傳輸?shù)?。以下我們?huì)看到NAK還可以用來(lái)對(duì)數(shù)據(jù)產(chǎn)生重傳的機(jī) 制。接收方發(fā)送NAK信號(hào)表示接收方打算用累加和校驗(yàn);發(fā)送字符C則表示接 收方想打算使用CRC校驗(yàn)(具體校

5、驗(yàn) 規(guī)則下文Xmodem源碼,源碼勝于 雄辯。7 .傳輸過(guò)程當(dāng)接收方發(fā)送的第一個(gè)C或者NAK到達(dá)發(fā)送方,發(fā)送方認(rèn)為可以發(fā)送第一個(gè) 數(shù)據(jù)包,傳輸已經(jīng)啟動(dòng)。發(fā)送方接著應(yīng)該將數(shù)據(jù)以每次128字節(jié)的數(shù)據(jù)加上包頭,包 號(hào)包號(hào)補(bǔ)碼,末尾加上校驗(yàn)和,打包成幀格式傳送。 發(fā)送方發(fā)了第一包后就等待接 收方的確認(rèn)字節(jié)ACK ,收到接收方傳來(lái)的ACK確認(rèn),就認(rèn)為數(shù)據(jù)包被接收方正確接 收,并且接收方要求發(fā)送方繼續(xù)發(fā)送下一個(gè)包;如果發(fā)送方收到接收方傳來(lái)的 NAK(這里,NAK用來(lái)告訴發(fā)送方重傳,不是用來(lái)啟動(dòng)傳輸 字節(jié),則表示接收方請(qǐng)求 重發(fā)剛才的數(shù)據(jù)包;如果發(fā)送方收到接收方傳來(lái)的CAN字節(jié),則表示接收方請(qǐng)求無(wú) 條件停止

6、傳輸。8 .如何結(jié)束傳輸?如果發(fā)送方正常傳輸完全部數(shù)據(jù),需要結(jié)束傳輸,正常結(jié)束需要發(fā)送方發(fā)送 EOT字節(jié)通知接收方。接收方回以ACK進(jìn)行確認(rèn)。當(dāng)然接收方也可強(qiáng)制停止傳 輸,當(dāng)接收方發(fā)送CAN字節(jié)給發(fā)送方,表示接收方想無(wú)條件停止傳輸,發(fā)送方收到 CAN后,不需要再發(fā)送EOT確認(rèn)(因?yàn)榻邮辗揭呀?jīng)不想理它了,呵呵。9 .特殊處理雖然數(shù)據(jù)包是以SOH來(lái)標(biāo)志一個(gè)信息包的起始的,但在SOH位置上如果出現(xiàn) EOT則表示數(shù)據(jù)傳輸結(jié)束,再也沒(méi)有數(shù)據(jù)傳過(guò)來(lái)。接收方首先應(yīng)確認(rèn)數(shù)據(jù)包序號(hào)的完整性,通過(guò)對(duì)數(shù)據(jù)包序號(hào)取補(bǔ),然后和數(shù)據(jù)包 序號(hào)的補(bǔ)碼異或,結(jié)果為0表示正確,結(jié)果不為0則發(fā)送NAK請(qǐng)求重傳。接收方確 認(rèn)數(shù)據(jù)包序

7、號(hào)正確后,然后檢查是否期望的序號(hào)。如果不是期望得到的數(shù)據(jù)包序號(hào),說(shuō)明發(fā)生嚴(yán)重錯(cuò)誤,應(yīng)該發(fā)送一個(gè)CAN來(lái)中止傳輸。如果接收到的數(shù)據(jù)包的包序號(hào)和前一包相同,那么接收方會(huì)忽略這個(gè)重復(fù)包,向發(fā)送方發(fā)出ACK,準(zhǔn)備接收下一 個(gè)包。接收方確認(rèn)了信息包序號(hào)的完整性和是正確期望的后,只對(duì)128字節(jié)的數(shù)據(jù)區(qū) 段進(jìn)行算術(shù)和校驗(yàn),結(jié)果與幀中最后一個(gè)字節(jié)(算術(shù)校驗(yàn)和比較,相同發(fā)送ACK,不同 發(fā)送NAK。10.校驗(yàn)和的說(shuō)明Xmodem協(xié)議支持2種校驗(yàn)和,它們是累加和與CRC校驗(yàn)。當(dāng)接收方一開(kāi)始啟動(dòng)傳輸時(shí)發(fā)送的是 NAK ,表示它希望以累加和方式校驗(yàn)。 當(dāng)接收方一開(kāi)始啟動(dòng)傳輸時(shí)發(fā)送的是字符 “ C裳示它希望以CRC方式

8、校驗(yàn)。可能有人會(huì)問(wèn),接收方想怎么校驗(yàn)發(fā)送方都得配合嗎,難道發(fā)送方必須都支持累 加和校 驗(yàn)和CRC校驗(yàn)?事實(shí)上Xmodem要求支持CRC的就必須同時(shí)支持累加 和, 如果發(fā)送方只支 持累加和,而接收方用字符“C來(lái)啟動(dòng),那么發(fā)送方只要不管它, 當(dāng)接收方繼續(xù)發(fā)送 “ C ”三次后都沒(méi)收到應(yīng)答,就自動(dòng)會(huì)改為發(fā)送NAK,因?yàn)樗呀?jīng) 明白發(fā)送方可能不支持 CRC校驗(yàn),現(xiàn)在接收方改為累加和校驗(yàn)和發(fā)送方通訊。發(fā) 送方收到NAK就趕緊發(fā)送數(shù)據(jù)包響應(yīng)。11. Xmodem協(xié)議代碼看了以上說(shuō)明,再參考代碼,應(yīng)該很容易會(huì)理解代碼編寫者的思路。XModem源碼#include crc16.h#define SOH 0x0

9、1#define STX 0x02#define EOT 0x04#define ACK 0x06#define CAN 0x18#define CTRLZ 0x1A#define DLY_1S 1000* define MAXRETRANS 25static int last_error = 0;#include string.hvoid port_outbyte(unsigned char trycharunsigned char buf2;buf0 = trychar;lowLevel_write(buf,1;unsigned char port_inbyte(unsigned int

10、time_out unsigned char ch; int i;last_error = 0;if(lowLevel_read(&ch,1 = 1 return ch;last_error = 1;return ch;static int check(int crc, const unsigned char *buf, int sz if (crcunsigned short crc = crc16_ccitt(buf, sz; unsigned short tcrc = (bufsz8+bufsz+1; if (crc = tcrc return 1;elseint i;unsigned

11、char cks = 0;for (i = 0; i 1 = 0 ; int xmodemReceive(unsigned char *dest, int destsz unsigned char xbuff1030;unsigned char *p;int bufsz, crc = 0;unsigned char trychar = C;unsigned char packetno = 1;int i, c, len = 0;int retry, retrans = MAXRETRANS;for(;for( retry = 0; retry 16; +retryif (trycharport

12、_outbyte(trychar;c = port_inbyte(DLY_1S1;if (last_error = 0switch (ccase SOH:bufsz = 128;goto start_recv;case STX:bufsz = 1024;goto start_recv;case EOT:flushinput(;port_outbyte(ACK; return len;case CAN:c = port_inbyte(DLY_1S; if (c = CANflushinput(;port_outbyte(ACK; return -1;break;default:break;if

13、(trychar = Ctrychar = NAK;continue;flushinput(;port_outbyte(CAN;port_outbyte(CAN; port_outbyte(CAN;return -2;start_recv:if (trychar = Ccrc = 1;trychar = 0;p = xbuff;* p+ = c;for (i = 0; i bufszcount = bufsz;if (count 0memcpy (&destlen, &xbuff3, count;len += count;+packetno;retrans = MAXRETRANS+1;if

14、(-retrans = 0flushinput(;port_outbyte(CAN;port_outbyte(CAN;port_outbyte(CAN; return -3; port_outbyte(ACK; continue; reject: flushinput(; port_outbyte(NAK; int xmodemTransmit(unsigned char *src, int srcsz unsigned char xbuff1030; int bufsz, crc = -1; unsigned char packetno = 1; int i, c, len = 0; int

15、 retry; for(; for( retry = 0; retry 16; +retry c = port_inbyte(DLY_1S bufsz c = bufsz; if (c = 0 memset (&xbuff3, 0, bufsz; if (c = 0 xbuff3 = CTRLZ; else memcpy(&xbuff3, &srclen, c; if (c 8 & 0xFF; xbuffbufsz+4 =ccrc & 0xFF; else unsigned char ccks = 0; for (i = 3; i bufsz+3; +i ccks += xbuffi; xbu

16、ffbufsz+3 = ccks; for (retry = 0; retry MAXRETRANS;+retry for (i = 0; i bufsz+4+(crc?1:0; +i port_outbyte(xbuffi; c = port_inbyte(DLY_1S; if (last_error = 0 switch (c case ACK: +packetno; len += bufsz; goto start_trans; case CAN: c = port_inbyte(DLY_1S; if ( c = CAN port_outbyte(ACK; flushinput(; return

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論