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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于IAP和Keil MDK的遠(yuǎn)程升級(jí)設(shè)計(jì)

          基于IAP和Keil MDK的遠(yuǎn)程升級(jí)設(shè)計(jì)

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

            3.3.1.2 選擇扇區(qū)

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

            在任何擦除和編程Flash之前,必須選中扇區(qū),可以選中一個(gè)或多個(gè)。

            /******************************************************************

            * 名稱:SelSector()

            * 功能:操作扇區(qū)選擇,命令代碼50。

            * 入口參數(shù):sec1 起始扇區(qū)

            * sec2 終止扇區(qū)

            * 出口參數(shù):返回值(paramout緩沖區(qū)) CMD_SUCCESS,BUSY,INVALID_SECTOR

            *********************************************************************/

            void SelSector(uint8 sec1, uint8 sec2)

            {

            paramin[0] = _SELSECTOR; // 設(shè)置命令字

            paramin[1] = sec1; // 設(shè)置參數(shù)

            paramin[2] = sec2;

            iap_entry(paramin, paramout); // 調(diào)用IAP服務(wù)程序

            }

            代碼3-2 選擇扇區(qū)

            3.3.1.3 擦除扇區(qū)

            在編程Flash前必須執(zhí)行擦除操作,如果某個(gè)扇區(qū)已經(jīng)擦除,就不需要再次擦除??梢砸淮尾脸粋€(gè)或多個(gè)扇區(qū)。

            /******************************************************************

            * 名稱:EraseSector()

            * 功能:扇區(qū)擦除,命令代碼52。

            * 入口參數(shù):sec1 起始扇區(qū)

            * sec2 終止扇區(qū)

            * 出口參數(shù):IAP返回值(paramout緩沖區(qū)) CMD_SUCCESS,BUSY,INVALID_SECTOR ************************************************************************/

            void EraseSector(uint8 sec1, uint8 sec2)

            { paramin[0] = IAP_ERASESECTOR; // 設(shè)置命令字

            paramin[1] = sec1; // 設(shè)置參數(shù)

            paramin[2] = sec2;

            paramin[3] = Fosc/1000; // 當(dāng)不使用PLL功能時(shí),F(xiàn)cclk=Fosc

            iap_entry(paramin, paramout); // 調(diào)用IAP服務(wù)程序

            代碼3-3 擦除扇區(qū)

            3.3.1.4 編程扇區(qū)

            通過這個(gè)過程,數(shù)據(jù)可以從RAM中編程到片內(nèi)Flash中。

            注:

            1. 數(shù)據(jù)只能從片內(nèi)SRAM編程到片內(nèi)Flash。

            2. 片內(nèi)Flash的地址必須512字節(jié)對(duì)齊。

            3. 片內(nèi)RAM應(yīng)位于局部總線,即USB或以太網(wǎng)的SRAM不可以使用。

            4. 每一次編程字節(jié)應(yīng)該是512、1024、4096、8192中的一個(gè)。

            /*********************************************************************

            * 名稱:RamToFlash()

            * 功能:復(fù)制RAM的數(shù)據(jù)到FLASH,命令代碼51。

            * 入口參數(shù):dst 目標(biāo)地址,即FLASH起始地址。以512字節(jié)為分界

            * src 源地址,即RAM地址。地址必須字對(duì)齊

            * no 復(fù)制字節(jié)個(gè)數(shù),為512/1024/4096/8192

            * 出口參數(shù):IAP返回值(paramout緩沖區(qū)) CMD_SUCCESS,SRC_ADDR_ERROR,DST_ADDR_ERROR,

            SRC_ADDR_NOT_MAPPED,DST_ADDR_NOT_MAPPED,COUNT_ERROR,BUSY,未選擇扇區(qū)

            ********************************************************************/

            void RamToFlash(uint32 dst, uint32 src, uint32 no)

            { paramin[0] = IAP_RAMTOFLASH; // 設(shè)置命令字

            paramin[1] = dst; // 設(shè)置參數(shù)

            paramin[2] = src;

            paramin[3] = no;

            paramin[4] = Fosc/1000; // 當(dāng)不使用PLL功能時(shí),F(xiàn)cclk=Fosc

            iap_entry(paramin, paramout); // 調(diào)用IAP服務(wù)程序

            }

            代碼3-4 編程扇區(qū)

            3.3.1.5 比較數(shù)據(jù)

            通過這個(gè)函數(shù),可以檢查寫入Flash中的數(shù)據(jù)和RAM中的是否相同。

            注意源地址、目標(biāo)地址和字節(jié)數(shù)必須是4的倍數(shù)。可使用 MDK提供的關(guān)鍵字__align(n) 來指定n字節(jié)對(duì)齊。

            /********************************************************************

            * 名稱:Compare()

            * 功能:校驗(yàn)數(shù)據(jù),命令代碼56。

            * 入口參數(shù):dst 目標(biāo)地址,即RAM/FLASH起始地址。地址必須字對(duì)齊

            * src 源地址,即FLASH/RAM地址。地址必須字對(duì)齊

            * no 復(fù)制字節(jié)個(gè)數(shù),必須能被4整除

            * 出口參數(shù):IAP返回值(paramout緩沖區(qū)) CMD_SUCCESS,COMPARE_ERROR,ADDR_ERROR

            ******************************************************************/

            void Compare(uint32 dst, uint32 src, uint32 no)

            { paramin[0] = IAP_COMPARE; // 設(shè)置命令字

            paramin[1] = dst; // 設(shè)置參數(shù)

            paramin[2] = src;

            paramin[3] = no;

            iap_entry(paramin, paramout); // 調(diào)用IAP服務(wù)程序

            代碼3-5 比較數(shù)據(jù)

            3.3.2 IAP編程期間的中斷管理

            LPC2114片上Flash在擦除/編程期間絕不可被中斷打斷。但Bootloader中定時(shí)和串口接收又使用了中斷,因此必須在擦除/編程之前禁止總中斷,待操作完成后再使能總中斷。Bootloader運(yùn)行在用戶模式下,不具有禁止/使能中斷的權(quán)力,所以在本設(shè)計(jì)中使用軟中斷禁止/使能總中斷。 MDK提供了關(guān)鍵字__svc來觸發(fā)軟中斷。

            軟中斷函數(shù)聲明:

            __svc(0x00) void EnableIrq(void); //使能中斷,軟中斷0

            __svc(0x01) void DisableIrq(void); //禁止中斷,軟中斷1

            軟中斷函數(shù)代碼:

            /*

            *********************************************************************

            * 功 能:禁止中斷

            * 描 述:利用軟中斷實(shí)現(xiàn)在用戶模式下調(diào)用函數(shù)關(guān)中斷

            *********************************************************************/

            void DisableIrqFunc(void)

            {

            int temp;

            __asm

            {

            MRS temp,SPSR

            ORR temp,temp,#0x80

            MSR SPSR_c,temp

            }

            }

            /*

            ********************************************************************

            * 功 能:使能中斷

            * 描 述:利用軟中斷實(shí)現(xiàn)在用戶模式下調(diào)用函數(shù)開中斷

            ********************************************************************

            */

            void EnableIrqFunc(void)

            {

            int temp;

            __asm

            {

            MRS temp,SPSR

            BIC temp,temp,#0x80

            MSR SPSR_c,temp

            }

            }

            代碼3-6 禁止/使能總中斷

            更改啟動(dòng)代碼,掛接軟中斷入口:

            ;軟中斷入口

            EXPORT SWI_Handler

            extern EnableIrq1

            extern DisableIrq1

            SWI_Handler

            STMFD SP!, {R0,R12,LR} ;入棧

            LDR R0, [LR,#-4] ;取軟中斷指令,軟中斷號(hào)就包含其中

            BIC R0,R0,#0xFF000000

            CMP R0,#0 ;判斷是否軟中斷0

            BLEQ EnableIrqFunc

            BLNE DisableIrqFunc

            LDMFD SP!,{R0,R12,PC}^

            代碼3-7 掛接軟中斷入口

            在程序中,如果想禁止中斷,只需使用DisableIrq();若是能中斷,只需使用EnableIrq()。

            3.3.3 使用分散加載機(jī)制精確定位入口地址

            應(yīng)用程序接收到升級(jí)指令后,會(huì)跳轉(zhuǎn)到0x00000400處執(zhí)行Bootloader升級(jí)程序。因此Bootloader程序的入口地址必須精確定位到0x00000400處。這可以使用 MDK提供的分散加載機(jī)制來完成。

            分散加載代碼見代碼3-8.

            ; *************************************************************

            ; *** Scatter-Loading Description File generated by uVision ***

            ; *************************************************************

            LR_IROM1 0x00000400 0x00001C00 { ; load region size_region

            ER_IROM1 0x00000400 0x00001C00 { ; load address = execution address

            *.o (RESET, +First)

            *(InRoot$$Sections)

            .ANY (+RO)

            }

            RW_IRAM1 0x40000040 0x00003FA0 { ; RW data

            .ANY (+RW +ZI)

            }

            }

            代碼3-8 分散加載代碼

            這段代碼顯示出Bootloader程序從0x00000400處開始執(zhí)行,最多占用0x1C00字節(jié)的Flash空間。另外,該程序的RAM從0x40000040開始,長(zhǎng)度為0x3FA0個(gè)字節(jié)。這樣RAM的低64字節(jié)保留給中斷向量映射使用,高32字節(jié)保留給IAP編程使用。

            3.3.4 中斷向量的重映射

            Bootloader的起始地址位于0x00000400,中斷向量也從這一地址開始存儲(chǔ)。但默認(rèn)情況下ARM發(fā)生異常時(shí),會(huì)跳轉(zhuǎn)到0x00000000處的64字節(jié)中斷向量區(qū)域執(zhí)行相應(yīng)操作,所以為了使Bootloader能相應(yīng)中斷,必須將位于0x00000400開始的64字節(jié)中斷向量表重映射到RAM的低區(qū)。LPC2114使用向寄存器MEMMAP寫入0x02來完成這一過程。

            代碼3-9 描述了中斷向量重映射的過程。

            ; Copy Exception Vectors to Internal RAM ---------------------------------------

            ADR R8, Vectors ; 源地址

            LDR R9, =RAM_BASE ; 目標(biāo)地址,這里是0x40000000

            LDMIA R8!, {R0-R7} ; 裝載向量表

            STMIA R9!, {R0-R7} ; 存儲(chǔ)向量表

            LDMIA R8!, {R0-R7} ; 裝載處理程序地址

            STMIA R9!, {R0-R7} ; 存儲(chǔ)處理程序地址

            ; Memory Mapping (when Interrupt Vectors are in RAM)

            MEMMAP EQU 0xE01FC040 ; Memory Mapping Control

            IF :DEF:REMAP

            LDR R0, =MEMMAP

            IF :DEF:EXTMEM_MODE

            MOV R1, #3

            ELIF :DEF:RAM_MODE

            MOV R1, #2

            ELSE

            MOV R1, #1

            ENDIF

            STR R1, [R0]

            ENDIF

            代碼3-9 中斷向量重映射

            由于Keil MDK提供的啟動(dòng)代碼中使用條件編譯指令,所以,要想正確的執(zhí)行中斷向量重映射,還需要在Keil MDK編譯器工程設(shè)置Options for target“你的工程目標(biāo)名”下的Asm標(biāo)簽中找到Define編輯框,在編輯框中鍵入“REMAP RAM_MODE”。如圖3-2所示

          clip_image009

           

            圖3-2

            注意:在擦除/編程Flash的時(shí)候還應(yīng)該禁止PLL、存儲(chǔ)器加速模塊。

            3.4 用戶程序的設(shè)計(jì)

            用戶程序運(yùn)行在高區(qū)(扇區(qū)8~13)或者低區(qū)(扇區(qū)1~7),用于實(shí)現(xiàn)數(shù)據(jù)的采集、處理和上傳等等,用戶程序除本身功能的要求外,還需要注意:

            ? 使用分散加載機(jī)制,將程序入口精確定位到0x00010000(高區(qū))或0x00008000(低區(qū))。

            ? 進(jìn)行中斷向量重映射,映射到RAM最底處。

              

          clip_image001[2]
          4 通訊協(xié)議與上位機(jī)軟件  

           

            4.1 Intel的hex格式

            Intel hex文件是記錄文本行的ASCII文本文件,在Intel HEX文件中,每一行是一個(gè)HEX記錄,由十六進(jìn)制數(shù)組成的機(jī)器碼或者數(shù)據(jù)常量。一個(gè)數(shù)據(jù)記錄以一個(gè)回車和一個(gè)換行結(jié)束。

            一個(gè)Intel HEX文件可以包含任意多的十六進(jìn)制記錄,每條記錄有五個(gè)域,下面是一個(gè)記錄的格式.

            : LL AAAA TT [DD...] CC

            每一組字母是獨(dú)立的一域,每一個(gè)字母是一個(gè)十六進(jìn)制數(shù)字,每一域至少由兩個(gè)十六進(jìn)制數(shù)字組成,下面是字節(jié)的描述.

            :冒號(hào) 是每一條Intel HEX記錄的開始

            LL 是這條記錄的長(zhǎng)度域,他表示數(shù)據(jù)(dd)的字節(jié)數(shù)目.

            AAAA 是地址域,他

            表示數(shù)據(jù)的起始地址

            TT 這個(gè)域表示這條HEX記錄的類型,他有可能是下面這幾種類型

            00 ----數(shù)據(jù)記錄

            01 ----文件結(jié)束記錄

            02 ----擴(kuò)展段地址記錄

            04 ----擴(kuò)展線性地址記錄

            DD 是數(shù)據(jù)域,表示一個(gè)字節(jié)的數(shù)據(jù),一個(gè)記錄可能有多個(gè)數(shù)據(jù)字節(jié),字節(jié)數(shù)目可以查看LL域的說明。



          關(guān)鍵詞: IAP Keil

          評(píng)論


          相關(guān)推薦

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

          關(guān)閉