999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

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

2018-05-16 09:29:09
關鍵詞:程序

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

引 言

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

使用μ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)地添加、更新和刪除應用程序的方法。本方法在工程實踐中取得了良好的效果。

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

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

假設有如下硬件系統(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 設計目標

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

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

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

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

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

4 設計實現(xiàn)

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

4.1 設計思想

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

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

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

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

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

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

4.2 設計步驟

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

4.2.1 應用程序設計

結(jié)合Cortex-M系列MCU的架構特點,配合IAR的相關機制,在應用程序設計中完成以下工作:

(1)源代碼修改

① 用匯編語言編寫一個名為ropi_rwpi_header.s的模塊,并將其加入應用程序工程文件。該模塊主要內(nèi)容如代碼段1所示,用于記錄應用程序的關鍵信息,如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

② 修改應用程序的啟動文件。在啟動文件頭部引入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

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

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

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

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

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

圖3 修改程序入口符號

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

圖4 修改起始地址

④ 參照代碼段3的示例內(nèi)容修改IAR應用工程的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 };

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

4.2.2 Loader程序設計

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

(1)源代碼修改

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

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

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

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

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

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

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

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

至此,應用程序開始運行。如果應用程序設計是可返回的或可通過命令終止的,則當應用程序結(jié)束后系統(tǒng)控制權將自動返還至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卡讀取應用程序文件

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); // 應用程序執(zhí)行完畢或被用戶終止返回

free(rwpi_data);

free(ropi_code);

}

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

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

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

結(jié) 語

參考文獻

[1] 唐思超.嵌入式系統(tǒng)軟件設計實戰(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.

猜你喜歡
程序
給Windows添加程序快速切換欄
電腦愛好者(2020年6期)2020-05-26 09:27:33
試論我國未決羈押程序的立法完善
人大建設(2019年12期)2019-05-21 02:55:44
失能的信仰——走向衰亡的民事訴訟程序
“程序猿”的生活什么樣
英國與歐盟正式啟動“離婚”程序程序
基于VMM的程序行為異常檢測
偵查實驗批準程序初探
我國刑事速裁程序的構建
創(chuàng)衛(wèi)暗訪程序有待改進
恐怖犯罪刑事訴訟程序的完善
主站蜘蛛池模板: 亚洲美女视频一区| 一级香蕉视频在线观看| 亚洲国产成熟视频在线多多 | 亚洲最大福利视频网| 免费毛片视频| 欧美色99| 91视频精品| 亚洲欧美极品| 极品国产一区二区三区| 无码'专区第一页| 18禁高潮出水呻吟娇喘蜜芽| 国产菊爆视频在线观看| 亚洲性视频网站| 欧美激情第一区| 国产另类视频| 亚洲一级毛片在线观| 国产精品高清国产三级囯产AV| 超清人妻系列无码专区| 秋霞午夜国产精品成人片| 人妻中文久热无码丝袜| 亚洲精品人成网线在线 | 欧美a√在线| 永久在线精品免费视频观看| 毛片视频网| 99福利视频导航| 在线国产资源| 男女性午夜福利网站| 九色在线视频导航91| 久久超级碰| 亚洲国产精品久久久久秋霞影院| 激情视频综合网| 欧美一区中文字幕| 久久青草精品一区二区三区| 在线国产91| 国语少妇高潮| 综合亚洲网| 国产免费a级片| 免费毛片a| 欧美天堂在线| 在线无码av一区二区三区| 婷婷色中文网| 中日韩欧亚无码视频| 久久国产热| 国产在线精彩视频二区| 丁香婷婷激情综合激情| a在线亚洲男人的天堂试看| 国产91导航| 亚洲成人在线网| 一本久道久久综合多人| 国产一国产一有一级毛片视频| 久久国产亚洲偷自| 亚洲天堂自拍| 3p叠罗汉国产精品久久| 国产成人精品优优av| 九九热视频精品在线| 99精品这里只有精品高清视频| 97se亚洲综合在线韩国专区福利| 亚洲无限乱码一二三四区| 综合五月天网| 思思热精品在线8| 67194在线午夜亚洲 | 亚洲国产AV无码综合原创| 国产一级α片| 婷婷六月在线| 国产丝袜精品| 色天堂无毒不卡| 亚洲丝袜第一页| 精品国产女同疯狂摩擦2| 亚洲精品成人片在线观看| 免费看的一级毛片| 欧美天天干| 色综合天天综合中文网| 久久国产黑丝袜视频| 亚洲精品午夜天堂网页| 国产91丝袜在线播放动漫 | 91青青草视频在线观看的| 国产人免费人成免费视频| 亚洲第一成年免费网站| 亚洲第一区欧美国产综合| 欧美精品在线观看视频| 久久a毛片| 亚洲欧美成人在线视频|