• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      無需內(nèi)存管理單元的微控制器動態(tài)程序管理方法

      2018-05-16 09:29:09
      關(guān)鍵詞:編譯器管理器應(yīng)用程序

      (賽諾微醫(yī)療科技(浙江)有限公司 北京分公司,北京 100012)

      引 言

      在現(xiàn)代計算機(jī)系統(tǒng)中,操作系統(tǒng)使用內(nèi)存管理單元(MMU)為每個進(jìn)程提供虛擬地址空間,MMU負(fù)責(zé)虛擬地址到物理地址的轉(zhuǎn)換。物理地址對應(yīng)真實內(nèi)存,所有進(jìn)程共享物理內(nèi)存。進(jìn)程在設(shè)計時都假定其是系統(tǒng)中唯一的代碼,可以使用任何地址空間。出于對功耗和面積的考慮,嵌入式系統(tǒng)中多數(shù)微控制器(MCU)并沒有MMU單元,例如基于ARM Cortex-M架構(gòu)的系列處理器。

      使用μCLinux可以在不具有MMU的MCU中動態(tài)加載程序。這引出一個問題:為什么不推薦μCLinux?首先,μCLinux對RAM的需求在兆字節(jié)級別,這對于許多小型系統(tǒng)來說過于龐大。此外,μCLinux需要一臺Linux計算機(jī)來編譯程序。最重要的一點是,已有的MCU程序要運行于μCLinux下,需要重寫代碼并更換開發(fā)環(huán)境。所以考慮到工作量及硬件成本,μCLinux并不是最佳選擇。

      本文討論一種無需MMU即可實現(xiàn)系統(tǒng)運行時動態(tài)地添加、更新和刪除應(yīng)用程序的方法。本方法在工程實踐中取得了良好的效果。

      1 硬件平臺及軟件開發(fā)環(huán)境

      為便于闡述,給定如下硬件平臺及軟件開發(fā)環(huán)境。

      假設(shè)有如下硬件系統(tǒng):處理器基于Cortex-M內(nèi)核且沒有MMU單元;處理器通過擴(kuò)展總線與外部SRAM相連;通過SDIO接口與外部SD卡相連;通過SPI總線與外部SPI-Flash相連。硬件平臺框架示意圖如圖1所示。

      圖1 硬件平臺框架示意圖

      軟件開發(fā)使用IAR Embedded Workbench for ARM Version:6.30。

      2 設(shè)計目標(biāo)

      假設(shè)有5個可以正常工作于前述硬件平臺的獨立應(yīng)用程序,這些程序使用IAR開發(fā),其名稱分別為app1~app5。現(xiàn)在,把app1裝入SPI-FLASHA,把app2裝入SPI-FLASHB,把app3~app5裝入SD卡(基于FAT文件系統(tǒng))。

      設(shè)計一個程序管理器,可以按需動態(tài)裝載上述任意應(yīng)用程序并執(zhí)行。應(yīng)用程序執(zhí)行完畢或用戶中斷應(yīng)用程序后,系統(tǒng)控制權(quán)可以返回程序管理器,以便后續(xù)加載應(yīng)用程序。

      3 程序管理器與程序加載器

      程序管理器與程序加載器都可以稱為loader,但兩者的工作機(jī)制有很大不同。一般來說,loader的工作主要是初始化硬件并加載目標(biāo)程序,例如,Cortex-A系列MPU通過前級loader初始化外部SDRAM并加載uboot,進(jìn)而由uboot加載Linux。這里的loader和uboot都可以看作程序加載器,兩者的共同點也很明顯,即加載目標(biāo)程序后,目標(biāo)程序即開始運行,控制權(quán)交給目標(biāo)程序。除非系統(tǒng)復(fù)位,否則,控制權(quán)永遠(yuǎn)不會返回到loader。

      相比而言,程序管理器除了加載目標(biāo)文件并引導(dǎo)其運行外,還必須具有控制權(quán)接管和多次加載目標(biāo)文件的能力。這一點,有點操作系統(tǒng)任務(wù)調(diào)度管理的意味。

      4 設(shè)計實現(xiàn)

      基于ARM Cortex-M系列的處理器,解決應(yīng)用程序加載問題的一種常見方法是在編譯時將固定地址分配給應(yīng)用程序。例如,應(yīng)用程序A加載于地址0x2 1000處,應(yīng)用程序B加載于地址0x2 2000處。這類處理方法有兩個明顯的不足:應(yīng)用程序的擴(kuò)展規(guī)模受限;系統(tǒng)運行時不能動態(tài)地添加、更新和刪除應(yīng)用程序。預(yù)先分配地址技術(shù)無法實現(xiàn)應(yīng)用程序的動態(tài)管理。

      4.1 設(shè)計思想

      針對不具有MMU單元的MCU,動態(tài)管理應(yīng)用程序可以使用以下幾種方法:在程序管理器中實現(xiàn)ELF分析器;使用可重定位代碼編譯,使用程序管理器轉(zhuǎn)化二進(jìn)制程序的內(nèi)存位置;使用位置無關(guān)代碼(PIC)進(jìn)行編譯,并在載入應(yīng)用程序時調(diào)整程序管理器的全局偏移寄存器。

      使用ELF語法分析器的缺點是:程序管理器需要比其它方法進(jìn)行更多的處理,意味著程序管理器將占用大量的程序存儲空間。

      使用可重定位代碼和內(nèi)存位置轉(zhuǎn)化技術(shù)比構(gòu)建ELF解析器簡單,并且性能比位置無關(guān)的代碼略好。

      位置無關(guān)代碼是一個很好的解決方案,但由于使用全局偏移的間接層而略微降低了性能。由于ARM指令集針對PIC操作進(jìn)行了優(yōu)化,大多數(shù)代碼的運行開銷可低至幾乎沒有額外運行成本。

      本文所實現(xiàn)的動態(tài)程序管理方法基于位置無關(guān)代碼(PIC)技術(shù),PIC技術(shù)允許將代碼放在任何地址。在PIC代碼中,所有分支和跳轉(zhuǎn)目標(biāo)都基于PC相對偏移;所有對數(shù)據(jù)部分的引用都通過全局偏移寄存器(GOR)進(jìn)行間接尋址。

      本文所設(shè)計的程序管理器(loader)使用PIC技術(shù)來加載多個應(yīng)用程序。程序管理器根據(jù)SRAM的真實地址在加載應(yīng)用程序時更新全局偏移寄存器GOR中的基地址。GOR本身是一個寄存器,其值在切換至應(yīng)用程序代碼之前由程序管理器設(shè)置。

      4.2 設(shè)計步驟

      應(yīng)用程序動態(tài)管理,需要結(jié)合處理器的架構(gòu)特點并充分利用編譯器的多種機(jī)制才能實現(xiàn)。針對本文的硬件平臺及開發(fā)環(huán)境,對系統(tǒng)資源做如下劃分:loader程序的存儲位置及運行位置均位于MCU片內(nèi)Flash;應(yīng)用程序存儲于外部存儲器,運行于外部SRAM;全局棧區(qū)及l(fā)oader程序所使用的內(nèi)存變量位于MCU片內(nèi)RAM;應(yīng)用程序使用的內(nèi)存變量位于外部SRAM。

      4.2.1 應(yīng)用程序設(shè)計

      結(jié)合Cortex-M系列MCU的架構(gòu)特點,配合IAR的相關(guān)機(jī)制,在應(yīng)用程序設(shè)計中完成以下工作:

      (1)源代碼修改

      ① 用匯編語言編寫一個名為ropi_rwpi_header.s的模塊,并將其加入應(yīng)用程序工程文件。該模塊主要內(nèi)容如代碼段1所示,用于記錄應(yīng)用程序的關(guān)鍵信息,如ROM起始地址,RO、RW容量,程序入口偏移等。這些信息由匯編文件指導(dǎo)IAR編譯器自動產(chǎn)生。

      【代碼段1】

      DATA

      ropi_rwpi_header:

      DC32ROM_address ; 編譯時ROM 地址,定義于鏈接腳本icf文件中

      DC32ROPI$$Length; 包含本頭模塊的RO字節(jié)數(shù)

      DC32RWPI$$Length; 程序RW字節(jié)數(shù)

      DC32main - . - 4; 代碼起始至main函數(shù)的偏移

      END

      ② 修改應(yīng)用程序的啟動文件。在啟動文件頭部引入main符號,并將NVIC向量表的第二項,即系統(tǒng)上電入口地址修改為main,如代碼段2所示。

      【代碼段2】

      SECTION.intvec:CODE:ROOT(2)

      EXTERNmain

      PUBLIC __vector_table

      DATA

      __intial_spEQU0x20000400

      __vector_table

      DCD __intial_sp

      DCDmain

      ③ 在應(yīng)用程序main函數(shù)中新增三個函數(shù)調(diào)用語句。即SystemInit、__iar_data_init3和nvic_update。其中,SystemInit是CMSIS內(nèi)建函數(shù),用于設(shè)置處理器時鐘系統(tǒng);__iar_data_init3是IAR內(nèi)建函數(shù),用于運行時數(shù)據(jù)初始化;nvic_update需要自行編寫,用于更新向量表入口并設(shè)置處理器向量表偏移寄存器VTOR。nvic_update依據(jù)loader在加載應(yīng)用程序時傳入的程序基地址,將NVIC向量表中的地址增加相應(yīng)的偏移。需要注意的是,NVIC中的第一個32位數(shù)據(jù)是編譯時的棧頂,該數(shù)據(jù)無需任何操作,忽略即可。

      (2)編譯器設(shè)置及鏈接腳本修改

      ① 在IAR工程設(shè)置C/C++ Compiler選項的Code頁面中,依照圖2完成設(shè)置,指示編譯器產(chǎn)生PIC代碼。

      圖2 指示IAR編譯器生成PIC代碼

      ② 在Linker選項的Library頁面中,依照圖3所示將入口符號設(shè)置為ropi_rwpi_header。

      圖3 修改程序入口符號

      ③ 在Linker選項的Config頁面中,依照圖4示例將.intvec start及ROM地址設(shè)置為0x00。其它參數(shù)對PIC代碼沒有意義,忽略即可。本步驟也可在icf文件中將__ICFEDIT_region_ROM_start__和__ICFEDIT_intvec_start__定義為0x00實現(xiàn),效果相同。

      圖4 修改起始地址

      ④ 參照代碼段3的示例內(nèi)容修改IAR應(yīng)用工程的icf鏈接腳本,強制編譯器在目標(biāo)文件頭部加入ropi_rwpi_header模塊。

      【代碼段3】

      define exported symbol ROM_address = __ICFEDIT_region_ROM_start__;

      define block RO with alignment = 4, fixed order{

      ro object ropi_rwpi_header.o,

      ro section .intvec,

      ro, ro data

      };

      "ROM":

      place in ROM_region{

      block RO };

      define movable block RW with alignment = 8, fixed order, static base{

      rw,

      block HEAP

      };

      "RAM":

      place in RAM_region { block RW };

      原有應(yīng)用程序工程完成上述步驟后,編譯即得到可動態(tài)管理的應(yīng)用程序。從上述步驟可以看出,本方法不需要對已有代碼進(jìn)行任何重寫,只需簡單的處理即可。

      4.2.2 Loader程序設(shè)計

      基于前述資源劃分,結(jié)合Cortex-M系列MCU的架構(gòu)特點,配合IAR的相關(guān)機(jī)制,需要在loader程序設(shè)計中完成以下工作:

      (1)源代碼修改

      ① 在loader程序的啟動文件中增加外部SRAM初始化函數(shù),完成外部SRAM初始化;

      ② 加載應(yīng)用程序時,從SPI-Flash或SD卡讀入目標(biāo)應(yīng)用程序。例如從SD卡讀入目標(biāo)文件可使用fopen類函數(shù)和“rb”參數(shù)完成;

      ③ 解析目標(biāo)文件的頭部信息區(qū),得到目標(biāo)文件的入口偏移、目標(biāo)程序大小及全局變量容量等信息;

      ④ 依據(jù)頭部信息區(qū)代碼容量分配程序基址。此步驟有兩種方法:動態(tài)管理和靜態(tài)管理。動態(tài)管理是依據(jù)目標(biāo)程序容量申請堆空間,并將外部存儲器中的應(yīng)用程序讀入堆起始地址;靜態(tài)管理是人為將外部SRAM劃分成程序區(qū)及數(shù)據(jù)區(qū)。靜態(tài)管理的好處是,避免了多次加載不同應(yīng)用程序時造成的內(nèi)存碎片;

      ⑤ 依據(jù)頭部信息區(qū)數(shù)據(jù)容量分配數(shù)據(jù)基址。此步驟有兩種方法:動態(tài)管理和靜態(tài)管理。動態(tài)管理是依據(jù)目標(biāo)程序全局變量容量申請堆空間,并將配分的起始地址寫入GOR;靜態(tài)管理則是將人為劃分的數(shù)據(jù)區(qū)起始地址寫入GOR。靜態(tài)管理的好處是避免了多次加載不同應(yīng)用程序時造成的內(nèi)存碎片;

      ⑥ 將步驟④ 得到的起始地址加上頭信息區(qū)的偏移值后賦值給函數(shù)指針;

      ⑦ 通過固定內(nèi)存區(qū)域或以函數(shù)參數(shù)的方式將起始地址傳入對應(yīng)函數(shù),以便應(yīng)用程序修改NVIC向量偏移及設(shè)置VTOR;

      ⑧ 調(diào)用函數(shù)指針。

      至此,應(yīng)用程序開始運行。如果應(yīng)用程序設(shè)計是可返回的或可通過命令終止的,則當(dāng)應(yīng)用程序結(jié)束后系統(tǒng)控制權(quán)將自動返還至loader,以便系統(tǒng)進(jìn)行后續(xù)程序管理。

      上述步驟的代碼舉例請參閱代碼段4,內(nèi)容僅供參考。

      【代碼段4】

      typedef int function(void);

      typedef function * function_p;

      struct ropi_rwpi_header_layout{

      uint ROM_address;

      size_t code_bytes;

      size_t data_bytes;

      size_t start_offset;

      };

      //數(shù)據(jù)基址寄存器

      static __no_init char* rwpi_data @ R9

      //程序執(zhí)行函數(shù)

      void execute(char * program_image){

      int status = 0;

      struct ropi_rwpi_header_layout ropi_rwpi_header;

      //從SD卡讀取應(yīng)用程序文件

      FILE* f = fopen(program_image, "rb");

      fread((char*) &ropi_rwpi_header, 1, sizeof(ropi_rwpi_header), f);

      //為PIC代碼動態(tài)申請空間并拷貝代碼

      unsigned char* ropi_code = malloc(ropi_rwpi_header.code_bytes - sizeof(ropi_rwpi_header));

      fread(ropi_code, 1, ropi_rwpi_header.code_bytes- sizeof(ropi_rwpi_header), f);

      fclose(f);

      //動態(tài)申請RAM并寫入基址寄存器

      rwpi_data = malloc(ropi_rwpi_header.data_bytes);

      function_p application = (function_p)(ropi_code + ropi_rwpi_header.start_offset);

      status = application(ropi_code); // 應(yīng)用程序執(zhí)行完畢或被用戶終止返回

      free(rwpi_data);

      free(ropi_code);

      }

      (2)編譯器設(shè)置及鏈接腳本修改

      修改loader程序的鏈接器腳本文件,將堆區(qū)置于外部SRAM。

      依據(jù)上述方法,可將一個普通loader程序轉(zhuǎn)換為動態(tài)程序管理器loader。將編譯后的loader下載至MCU片內(nèi)程序存儲器,將編譯得到的應(yīng)用程序?qū)懭隨PI-Flash或SD卡。啟動系統(tǒng),即可按需動態(tài)加載、刪除或更新應(yīng)用程序。

      結(jié) 語

      參考文獻(xiàn)

      [1] 唐思超.嵌入式系統(tǒng)軟件設(shè)計實戰(zhàn)--基于IAR Embedded Workbench[M].北京:北京航空航天大學(xué)出版社,2010.

      [2] Arm.Cortex-M3 Technical Reference Manual[EB/OL].[2018-02].www.arm.com.

      [3] IAR Systems.ARM IAR Assembler Reference Guide[EB/OL].[2018-02].www.iar.com.

      [4] IAR Systems.IAR Development Guide-Compiling and Linking[EB/OL].[2018-02].www.iar.com.

      猜你喜歡
      編譯器管理器應(yīng)用程序
      應(yīng)急狀態(tài)啟動磁盤管理器
      基于相異編譯器的安全計算機(jī)平臺交叉編譯環(huán)境設(shè)計
      刪除Win10中自帶的應(yīng)用程序
      電腦報(2019年12期)2019-09-10 05:08:20
      Windows文件緩沖處理技術(shù)概述
      高集成度2.5A備份電源管理器簡化鋰離子電池備份系統(tǒng)
      快速導(dǎo)出QQ群消息
      電腦迷(2014年2期)2014-04-29 19:21:13
      通用NC代碼編譯器的設(shè)計與實現(xiàn)
      關(guān)閉應(yīng)用程序更新提醒
      電腦迷(2012年15期)2012-04-29 17:09:47
      編譯器無關(guān)性編碼在微控制器中的優(yōu)勢
      三星電子將開設(shè)應(yīng)用程序下載商店
      吴川市| 开封市| 濮阳市| 随州市| 南岸区| 天水市| 安国市| 西充县| 班玛县| 迭部县| 绥棱县| 丰县| 文成县| 专栏| 竹北市| 松滋市| 苏尼特右旗| 惠水县| 视频| 江山市| 秦皇岛市| 荔波县| 茂名市| 嘉兴市| 乌拉特中旗| 邛崃市| 玛纳斯县| 诸城市| 定南县| 长葛市| 镇安县| 吴堡县| 中宁县| 昔阳县| 江达县| 徐水县| 株洲县| 师宗县| 攀枝花市| 宜章县| 志丹县|