亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

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

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

        引 言

        在現(xiàn)代計算機系統(tǒng)中,操作系統(tǒng)使用內(nèi)存管理單元(MMU)為每個進程提供虛擬地址空間,MMU負責虛擬地址到物理地址的轉(zhuǎn)換。物理地址對應(yīng)真實內(nèi)存,所有進程共享物理內(nèi)存。進程在設(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計算機來編譯程序。最重要的一點是,已有的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單元;處理器通過擴展總線與外部SRAM相連;通過SDIO接口與外部SD卡相連;通過SPI總線與外部SPI-Flash相連。硬件平臺框架示意圖如圖1所示。

        圖1 硬件平臺框架示意圖

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

        2 設(shè)計目標

        假設(shè)有5個可以正常工作于前述硬件平臺的獨立應(yīng)用程序,這些程序使用IAR開發(fā),其名稱分別為app1~app5?,F(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,但兩者的工作機制有很大不同。一般來說,loader的工作主要是初始化硬件并加載目標程序,例如,Cortex-A系列MPU通過前級loader初始化外部SDRAM并加載uboot,進而由uboot加載Linux。這里的loader和uboot都可以看作程序加載器,兩者的共同點也很明顯,即加載目標程序后,目標程序即開始運行,控制權(quán)交給目標程序。除非系統(tǒng)復(fù)位,否則,控制權(quán)永遠不會返回到loader。

        相比而言,程序管理器除了加載目標文件并引導其運行外,還必須具有控制權(quán)接管和多次加載目標文件的能力。這一點,有點操作系統(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)用程序的擴展規(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)化二進制程序的內(nèi)存位置;使用位置無關(guān)代碼(PIC)進行編譯,并在載入應(yīng)用程序時調(diào)整程序管理器的全局偏移寄存器。

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

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

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

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

        本文所設(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)特點并充分利用編譯器的多種機制才能實現(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)機制,在應(yīng)用程序設(shè)計中完成以下工作:

        (1)源代碼修改

        ① 用匯編語言編寫一個名為ropi_rwpi_header.s的模塊,并將其加入應(yīng)用程序工程文件。該模塊主要內(nèi)容如代碼段1所示,用于記錄應(yīng)用程序的關(guān)鍵信息,如ROM起始地址,RO、RW容量,程序入口偏移等。這些信息由匯編文件指導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鏈接腳本,強制編譯器在目標文件頭部加入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)用程序。從上述步驟可以看出,本方法不需要對已有代碼進行任何重寫,只需簡單的處理即可。

        4.2.2 Loader程序設(shè)計

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

        (1)源代碼修改

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

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

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

        ④ 依據(jù)頭部信息區(qū)代碼容量分配程序基址。此步驟有兩種方法:動態(tài)管理和靜態(tài)管理。動態(tài)管理是依據(jù)目標程序容量申請堆空間,并將外部存儲器中的應(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ù)目標程序全局變量容量申請堆空間,并將配分的起始地址寫入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è)計是可返回的或可通過命令終止的,則當應(yīng)用程序結(jié)束后系統(tǒng)控制權(quán)將自動返還至loader,以便系統(tǒng)進行后續(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é) 語

        參考文獻

        [1] 唐思超.嵌入式系統(tǒng)軟件設(shè)計實戰(zhàn)--基于IAR Embedded Workbench[M].北京:北京航空航天大學出版社,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)啟動磁盤管理器
        基于相異編譯器的安全計算機平臺交叉編譯環(huán)境設(shè)計
        刪除Win10中自帶的應(yīng)用程序
        電腦報(2019年12期)2019-09-10 05:08:20
        Windows文件緩沖處理技術(shù)概述
        高集成度2.5A備份電源管理器簡化鋰離子電池備份系統(tǒng)
        快速導出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)用程序下載商店
        五月综合缴情婷婷六月| 亚洲欧洲日产国产AV无码| 五月婷婷激情小说| 日韩精品一区二区三区中文9| 国产亚洲av综合人人澡精品| 白白在线视频免费观看嘛| 东京热人妻无码一区二区av| 99热免费观看| 国产美女高潮流白浆免费观看| 麻神在线观看免费观看| 欧美精品黑人粗大免费| 三上悠亚免费一区二区在线| 91青草久久久久久清纯| 青青草是针对华人绿色超碰| 99久久无色码中文字幕人妻蜜柚| 久久av高潮av无码av喷吹| 伊人亚洲综合网色AV另类| 亚洲免费一区二区av| av无码国产精品色午夜| 国产精品毛片无码| 99热这里只有精品久久6| 中国亚洲av第一精品| 国产超碰女人任你爽| 国产成人综合一区二区三区| 日本熟妇高潮爽视频在线观看| 国产一级二级三级在线观看视频| 日本精品αv中文字幕| 在线精品国内视频秒播| 久久综合久中文字幕青草| 国产精品亚洲精品日韩已方| 五月婷婷俺也去开心| 色老头久久综合网老妇女| 日本免费a一区二区三区| 国产乱码人妻一区二区三区| 麻豆高清免费国产一区| 1234.com麻豆性爰爱影| 久久精品国产亚洲av性瑜伽| 欧美俄罗斯40老熟妇| 国产国拍亚洲精品午夜不卡17| 国产亚洲一区二区精品| 欧美人与禽2o2o性论交|