<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > AVR之BOOTLOADER技術詳解

          AVR之BOOTLOADER技術詳解

          作者: 時間:2016-11-13 來源:網(wǎng)絡 收藏
          ATmega128具備引導加載支持的用戶程序自編程功能(In-System Programming by On-chipBoot Program),它提供了一個真正的由MCU本身自動下載和更新(采用讀/寫同時"Read-While-Write"進行的方式)程序代碼的系統(tǒng)程序 自編程更新的機制。利用AVR的這個功能,可以實現(xiàn)在應用編程(IAP)以及實現(xiàn)系統(tǒng)程序的遠程自動更新的應用。
          IAP的本質就是,MCU可以靈活地運行一個常駐Flash的引導加載程序(Boot Loader Program),實現(xiàn)對用戶應用程序的在線自編程更新。引導加載程序的設計可以使用任何的可用的數(shù)據(jù)接口和相關的協(xié)議讀取代碼,或者從程序存儲器中讀取 代碼,然后將代碼寫入(編程)到Flash存儲器中。
          引導加載程序有能力讀寫整個Flash存儲器,包括引導加載程序所在的引導加載區(qū)本身。引導加載程序還可以對自身進行更新修改,甚至可以將自身刪除,使系 統(tǒng)的自編程能力消失。引導加載程序區(qū)的大小可以由芯片的熔絲位設置,該段程序區(qū)還提供兩組鎖定位,以便用戶選擇對該段程序區(qū)的不同級別的保護。
          本節(jié)將給出一個實際的的Boot Loader程序,它可以配合Windows中的超級終端程序,采用Xmodem傳輸協(xié)議,通過RS232接口下載更新用戶的應用程序。
          5.2.1 基本設計思想
          1. Boot Loader程序的設計要點
          Boot Loader程序的設計是實現(xiàn)IAP的關鍵,它必須能過通過一個通信接口,采用某種協(xié)議正確的接收數(shù)據(jù),再將完整的數(shù)據(jù)寫入到用戶程序區(qū)中。本例Boot Loader程序的設計要點有:
          (1)采用ATmega128的USART口實現(xiàn)與PC之間的簡易RS232三線通信;
          (2) 采用Xmodem通信協(xié)議完成與PC機之間的數(shù)據(jù)交換;
          (3)用戶程序更新完成后自動轉入用戶程序執(zhí)行;
          (4) Boot Loader程序采用C語言內(nèi)嵌AVR匯編方式編寫,閱讀理解方便,可移植性強,代碼小于1K字。
          2. Xmodem通信協(xié)議
          Xmodem協(xié)議是一種使用撥號調制解調器的個人計算機通信中廣泛使用的異步文件運輸協(xié)議。這種協(xié)議以128字節(jié)塊的形式傳輸數(shù)據(jù),并且每個塊都使用一個 校驗和過程來進行錯誤檢測。如果接收方關于一個塊的校驗和與它在發(fā)送方的校驗和相同時,接收方就向發(fā)送方發(fā)送一個認可字節(jié)。為了便于讀者閱讀程序,下面簡 要說明該協(xié)議的主要特點,有關Xmoden的完整的協(xié)議請參考其它相關的資料。
          (1) Xmodem的控制字符: 01H、 04H、 06H、 15H、 18H、 1AH。
          (2) Xmodem傳輸數(shù)據(jù)塊格式:"
          個字節(jié)的數(shù)據(jù)塊...> "。其中為起始字節(jié);
          為數(shù)據(jù)塊編號字節(jié),每次加一;是前一字節(jié)的反碼;接下來是長度為128字節(jié)的數(shù)據(jù)塊;最后的是128字節(jié)數(shù)據(jù)的CRC校驗碼,長度為2個字節(jié)。
          (3)接收端收到一個數(shù)據(jù)塊并校驗正確時,回送;接收錯誤回送;而回送表示要發(fā)送端停止發(fā)送。
          (4) 發(fā)送端收到后,可繼續(xù)發(fā)送下一個數(shù)據(jù)塊(packNO+1);而收到則可再次重發(fā)上一個數(shù)據(jù)塊。
          (5)發(fā)送端發(fā)送表示全部數(shù)據(jù)發(fā)送完成。如果最后需要發(fā)送的數(shù)據(jù)不足128個字節(jié),用填滿一個數(shù)據(jù)塊。
          (6) 控制字符"C"有特殊的作用,當發(fā)送端收到"C"控制字符時,它回重新開始以CRC校驗方式發(fā)送數(shù)據(jù)塊(packNO = 1)。
          (7) 每發(fā)送一個新的數(shù)據(jù)塊
          加1,加到OxFF后下一個數(shù)據(jù)塊的
          為零。
          (8) 校驗方式采用16位CRC校驗(X^16 + X^12 + X^5 + 1)。
          5.2.2 源程序代碼
          下面給出的源程序是在ICCAVR中實現(xiàn)的。
          /*****************************************************
          采用串行接口實現(xiàn)Boot_load應用的實例
          華東師大電子系 馬 潮 2004.07
          Compiler: ICC-AVR 6.31
          Target: Mega128
          Crystal: 16Mhz
          Used: T/C0,USART0
          *****************************************************/
          #include
          #define SPM_PAGESIZE 256 //M128的一個Flash頁為256字節(jié)(128字)
          #define BAUD 38400 //波特率采用38400bps
          #define CRYSTAL 16000000 //系統(tǒng)時鐘16MHz
          //計算和定義M128的波特率設置參數(shù)
          #define BAUD_SETTING (unsigned char)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)
          #define BAUD_H (unsigned char)(BAUD_SETTING>>8)
          #define BAUD_L (unsigned char)BAUD_SETTING
          #define DATA_BUFFER_SIZE SPM_PAGESIZE //定義接收緩沖區(qū)長度
          //定義Xmoden控制字符
          #define XMODEM_NUL 0x00
          #define XMODEM_SOH 0x01
          #define XMODEM_STX 0x02
          #define XMODEM_EOT 0x04
          #define XMODEM_ACK 0x06
          #define XMODEM_NAK 0x15
          #define XMODEM_CAN 0x18
          #define XMODEM_EOF 0x1A
          #define XMODEM_RECIEVING_WAIT_CHAR C
          //定義全局變量
          const char startupString[]="Type d download, Others run app.nr看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();