色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > 基于IAP和Keil MDK的遠程升級設(shè)計

          基于IAP和Keil MDK的遠程升級設(shè)計

          作者: 時間:2016-12-19 來源:網(wǎng)絡(luò) 收藏

            寫在前面:三個周之前,我突然想寫一個遠程升級的程序。那個時候我只是大概知道的意思是在應用編程,但怎么編,我還一無所知。我給自己定下一個個階段目標,從最基礎(chǔ)的代碼一點點寫起,解決一個又一個的問題。三個周之后,我用自己設(shè)計的方法實驗了50多次,無一例升級失敗。

          本文引用地址:http://cafeforensic.com/article/201612/341760.htm

            三個周來,遇到了很多的不解、困惑,甚至是想放棄,但我現(xiàn)在想說的是:很多未知的困難會擋在我們面前,我們會感覺毫無頭緒甚至覺得毫無出路忍不住要放棄,但多堅持一下,那些困難不但能煙消云散還能帶給我們進步。

            本設(shè)計是基于LPC2114和 MDK(V4.10),但所有支持的處理器都可借鑒本方案,重要的是思想,而不是用什么。

            0 引言

            在應用編程()技術(shù)為系統(tǒng)在線升級和遠程升級提供了良好的解決方案,也為數(shù)據(jù)存儲和現(xiàn)場固件的升級都帶來了極大的靈活性。通??衫眯酒拇锌诮拥接嬎銠C的RS232口、通過現(xiàn)有的Internet或、無線網(wǎng)絡(luò)或者其他通信方式很方便地實現(xiàn)在線以及遠程升級和維護。

            本文以NXP的LPC2114 ARM微處理器為平臺,以 MDK為開發(fā)工具,闡述IAP的原理、Flash的劃分、分散加載機制、中斷重映射以及在線升級的實現(xiàn)方案及其優(yōu)化。本方案使用多種校驗技術(shù),最大限度的保障傳輸數(shù)據(jù)的正確性;使用bootloader機制,即使因意外事件(斷電,編程Flash失敗等)造成升級失敗后,程序也能返回到升級前的狀態(tài)。

            1 LPC2114的Flash規(guī)劃

            1.1 扇區(qū)描述

            LPC2114共有128KB片內(nèi)Flash,共分為16個扇區(qū),分別為0扇區(qū)~15扇區(qū),每個扇區(qū)為8KB存儲空間。其中第15扇區(qū)出廠時被固化為Boot Block區(qū),控制復位后的初始化操作,并提供實現(xiàn)Flash 編程的方法。所以用戶可用的Flash空間只有120KB。IAP程序固化于Boot Block中,IAP操作是以扇區(qū)為單位,并占用片內(nèi)RAM的高32字節(jié)。下表列出LPC2114器件所包含的扇區(qū)數(shù)和存儲器地址.

            表1.1 LPC2114 Flash 器件中的扇區(qū)

          image

            1.2 Flash的扇區(qū)劃分

            本設(shè)計將Flash劃分為四個區(qū),扇區(qū)0存放跳轉(zhuǎn)程序和升級引導程序(Bootloader)。分站上電后執(zhí)行跳轉(zhuǎn)程序,跳轉(zhuǎn)到用戶程序處。用戶程序運行過程中,如果接收到升級指令,會從用戶程序跳轉(zhuǎn)到引導程序區(qū)(Bootloader),接收新程序數(shù)據(jù)包,完成Flash編程并跳轉(zhuǎn)到新程序區(qū)執(zhí)行程序。扇區(qū)1~扇區(qū)7為程序存儲低區(qū);扇區(qū)8~扇區(qū)13為程序存儲高區(qū);扇區(qū)14存放當前程序運行區(qū)域標志,如果當前程序運行在高區(qū),該標志區(qū)的最低四個字節(jié)為0x00010000,如果當前程序運行在低區(qū),該標志區(qū)的最低四個字節(jié)為0x00008000。

            2 IAP的原理與軟件設(shè)計

            2.1 IAP的原理

            IAP函數(shù)是固化在微處理器內(nèi)部flash上的一些函數(shù)代碼,最終的用戶程序可以直接通過調(diào)用這些函數(shù)來對內(nèi)部flash進行擦除和編程操作。LPC2114微處理器的內(nèi)部flash有一個塊稱為Boot Block,位于flash的頂端,可供調(diào)用的IAP函數(shù)就位于該塊中。上電后Boot Block被映射到內(nèi)部地址空間的頂端,同樣IAP函數(shù)人口地址也被映射到地址0x7ffffff0處。用戶可通過跳轉(zhuǎn)到該地址來調(diào)用相應的lAP函數(shù)。

            2.2 IAP 命令

            對于在應用編程來說,應當通過寄存器r0 中的字指針指向存儲器(RAM)包含的命令代碼和參數(shù)來調(diào)用IAP 程序。IAP 命令的結(jié)果返回到寄存器r1 所指向的返回表。用戶可通過傳遞寄存器r0 和r1 中的相同指針重用命令表來得到結(jié)果。參數(shù)表應當大到足夠保存所有的結(jié)果以防結(jié)果的數(shù)目大于參數(shù)的數(shù)目。參數(shù)傳遞見圖2-1。參數(shù)和結(jié)果的數(shù)目根據(jù)IAP命令而有所不同。參數(shù)的最大數(shù)目為5,由“將RAM 內(nèi)容復制到Flash”命令傳遞。結(jié)果的最大數(shù)目為2,由“扇區(qū)查空”命令返回。命令處理程序在接收到一個未定義的命令時發(fā)送狀態(tài)代碼INVALID_COMMAND。IAP 程序是thumb 代碼,位于地址0x7FFFFFF0。

              

          clip_image005

            圖2-1 IAP的參數(shù)傳遞

            表2-1描述了IAP的命令。

            表2-1 IAP 命令匯總

            IAP命令命令代碼描述

            準備編程扇區(qū)50該命令必須在執(zhí)行“將 RAM 內(nèi)容復制到Flash”或“擦除扇區(qū)”命令之前執(zhí)行。這兩個命令的成功執(zhí)行會導致相關(guān)的扇區(qū)再次被保護。該命令不能用于boot 扇區(qū)。要準備單個扇區(qū),可將起始和結(jié)束扇區(qū)號設(shè)置為相同值。

            將RAM內(nèi)容復制到Flash51該命令用于編程 Flash 存儲器。受影響的扇區(qū)應當先通過調(diào)用“準備寫操作的扇區(qū)”命令準備。當成功執(zhí)行復制命令后,扇區(qū)將自動受到保護。該命令不能寫boot 扇區(qū)。

            擦除扇區(qū)52該命令用于擦除片內(nèi) Flash 存儲器的一個或多個扇區(qū)。boot 扇區(qū)不能由該命令擦除。要擦除單個扇區(qū)可將起始和結(jié)束扇區(qū)號設(shè)定為相同值。

            扇區(qū)查空53該命令用于對片內(nèi) Flash 存儲器的一個或多個扇區(qū)進行查空。要查空單個扇區(qū)可將起始和結(jié)束扇區(qū)號設(shè)定為相同值。

            讀器件ID54該命令用于讀取器件的 ID 號。

            讀Boot版本55該命令用于讀取 boot 代碼版本號。

            IAP比較56該命令用來比較兩個地址單元的存儲器內(nèi)容。當源或目標地址包含從地址0 開始的前64字節(jié)中的任意一個時,比較的結(jié)果不一定正確。前64字節(jié)重新映射到Flash boot 扇區(qū)。

            2.3 IAP 編程函數(shù)接口

            IAP 功能可用下面的C 代碼來調(diào)用。

            定義 IAP 程序的入口地址。由于IAP 地址的第0 位是1,因此,當程序計數(shù)器轉(zhuǎn)移到該地址時會引起Thumb 指令集的變化。

            #define IAP_LOCATION 0x7ffffff1

            定義數(shù)據(jù)結(jié)構(gòu)或指針,將IAP 命令表和結(jié)果表傳遞給IAP 函數(shù)

            unsigned long command[5];

            unsigned long result[2];

            定義函數(shù)類型指針,函數(shù)包含2 個參數(shù),無返回值。注意:IAP 將函數(shù)結(jié)果和R1 中的表格基址一同返回。

            typedef void (*IAP) (unsigned int [ ] , unsigned int [ ]);

            IAP iap_entry;

            設(shè)置函數(shù)指針

            iap_entry=(IAP) IAP_LOCATION;

            使用下面的語句來調(diào)用IAP。

            iap_entry (command , result);

            Flash 存儲器在寫或擦除操作過程中不可被訪問。執(zhí)行Flash 寫/擦除操作的IAP 命令

            使用片內(nèi)RAM 頂端的32 個字節(jié)空間。如果應用程序中允許IAP 編程,那么用戶程序不應

            使用該空間。

            3 LPC2114升級實現(xiàn)過程

            由于在升級程序軟件設(shè)計中,分散加載機制、中斷向量的重映射、軟中斷等的實現(xiàn)還與所使用的編譯器緊密相關(guān),因此,本文結(jié)合 MDK(V4.10)編譯工具,來詳細闡述升級程序的實現(xiàn)過程。

            3.1 總體思路

            分站上電后,首先運行位于Flash 0x000~0x3FF中的跳轉(zhuǎn)程序。跳轉(zhuǎn)程序會讀取位于14扇區(qū)的當前程序運行標志,如果該扇區(qū)的最低四個字節(jié)為0x00010000,表示當前程序運行在高區(qū),跳轉(zhuǎn)程序會跳轉(zhuǎn)到Flash的0x00010000處執(zhí)行用戶程序;如果該標志區(qū)的最低四個字節(jié)為0x00008000,表示當前程序運行在低區(qū),跳轉(zhuǎn)程序會跳轉(zhuǎn)到Flash的0x00002000處執(zhí)行用戶程序。用戶程序正常執(zhí)行后,會按照設(shè)計進行正常的程序采集、數(shù)據(jù)處理傳送。當接收到升級命令后,用戶程序會跳轉(zhuǎn)到Flash的0x00000400處的Bootloader處進行升級的一些操作。當升級成功后,Bootloader程序更新當前程序運行區(qū)標志,程序跳轉(zhuǎn)到新程序處運行,如果升級不成功,返回升級前的程序。

            流程圖如下所示:

          clip_image006

            3.2 跳轉(zhuǎn)程序的設(shè)計

            跳轉(zhuǎn)程序是分站上電后最先運行的程序,根據(jù)當前程序運行區(qū)標志,跳轉(zhuǎn)到相應的用戶程序區(qū)執(zhí)行。本段程序占用Flash的最低1K字節(jié)空間,與Bootloader同在第0扇區(qū)。

            跳轉(zhuǎn)程序的啟動代碼僅初始化堆棧,不使用PLL和存儲加速功能。代碼1描述了跳轉(zhuǎn)程序的主要啟動代碼。

            ; Enter User Mode and set its Stack Pointer

            MSR CPSR_c, #Mode_USR

            MOV SP, R0

            SUB SL, SP, #USR_Stack_Size

            ; Enter the C code

            IMPORT __main

            LDR R0, =__main

            BX R0

            代碼1:跳轉(zhuǎn)程序啟動代碼

            當跳轉(zhuǎn)程序確定要跳轉(zhuǎn)到高區(qū)用戶程序或者低區(qū)用戶程序后,使用函數(shù)指針跳轉(zhuǎn)到0x00010000處(高區(qū)用戶函數(shù)入口地址)或0x00002000處(低區(qū)用戶函數(shù)入口地址)。

            定義函數(shù)指針:

            void (*UserProgram)() ;

            指定入口地址:

            UserProgram = (void (*)()) (0x00010000);

            UserProgram = (void (*)()) (0x00002000);

            實現(xiàn)跳轉(zhuǎn):

            (*UserProgram)() ;

            要將用戶代碼精確定位到Flash的0x00010000處(高區(qū)用戶函數(shù)入口地址)或0x00002000處(低區(qū)用戶函數(shù)入口地址),需要使用編譯器的分散加載機制,將在Bootloader中詳細描述實現(xiàn)過程。

            另外,跳轉(zhuǎn)程序還在燒錄代碼的同時初始化當前程序運行區(qū)標志,即對Flash的0x0001C000地址處寫入0x00008000,表示當前用戶程序在低區(qū)。主要使用了編譯器的__at關(guān)鍵字:精確定位變量。需要注意的是,使用該關(guān)鍵字必須包含頭文件absacc.h。

            const uint32 x __at(0x0001C000)=0x00008000; //初始化用戶程序標志區(qū),默認運行低區(qū)

            3.3 升級程序Bootloader的設(shè)計

            升級程序的好壞,在很大程度上取決于Bootloader設(shè)計的好壞。

            一個優(yōu)秀的IAP升級Bootloader,必須做好升級中出現(xiàn)故障等異常的處理。保證系統(tǒng)不會崩潰,即使升級失敗,也能返回升級前的程序。

            ? 有升級指令,進行初始化工作(串口、定時器、看門狗)

            ? 接收升級數(shù)據(jù)包,檢測幀頭、長度、幀號、數(shù)據(jù)區(qū)校驗,最大程度的保證升級數(shù)據(jù)的完整性、正確性。

            ? 實時檢測接收狀態(tài),10 S內(nèi)沒有接收到數(shù)據(jù)或接收到的數(shù)據(jù)包都是錯的,則退出升級,返回原程序。

            ? 接收的數(shù)據(jù)按照512字節(jié)一組寫入Flash,寫入后再讀出與原數(shù)據(jù)進行對比校驗,校

            驗成功后,本次編程Flash成功。允許連續(xù)3次編程Flash,三次都不成功,退出升級程序,執(zhí)行原程序。

            ? 升級成功后,更新當前程序運行區(qū)標志,跳轉(zhuǎn)到新程序,同時原程序保存。

            本設(shè)計的Bootload位于Flash的0x400開始的扇區(qū)0存儲區(qū)內(nèi),使用分散加載機制,將程序的入口地址定位到0x00000400處。當用戶程序接收到升級指令后,就會使用函數(shù)指針跳轉(zhuǎn)到這個入口處。

            3.3.1 使用IAP

            圖3-1 描述了使用IAP編程Flash所必須的步驟。

          clip_image007

            3.3.1.1 定義系統(tǒng)參數(shù)

            在使用IAP前,需要定義一些系統(tǒng)參數(shù),比如系統(tǒng)時鐘、IAP中斷入口、輸入輸出緩存。

            #define IAP_CLK 11059200UL

            #define IAP_LOCATION 0x7FFFFFF1

            typedef void(*IAP)(uint32 [],uint32 []); //定義函數(shù)類型指針

            IAP iap_entry=(IAP)IAP_LOCATION; //設(shè)置函數(shù)指針

            unsigned long command[5] = {0,0,0,0,0};

            unsigned long result[2]= {0,0};

            代碼3-1:定義系統(tǒng)參數(shù)


          上一頁 1 2 3 下一頁

          關(guān)鍵詞: IAP Keil

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉