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

        ?

        基于μCOS系統(tǒng)的嵌入式動態(tài)加載技術(shù)實現(xiàn)與改進

        2017-12-02 14:03:19裴俊宇劉子龍
        軟件導刊 2017年11期

        裴俊宇 劉子龍

        摘要:針對嵌入式操作系統(tǒng)不支持外部程序動態(tài)加載技術(shù),限制其靈活性和可擴展性的弊端,基于STM32F103μc/OSIII平臺,運用ELF文件重定位原理,對原系統(tǒng)功能進行拓展,對編譯合適的ELF文件、ELF加載器實現(xiàn)等作深入分析。測試表明,系統(tǒng)支持對軟件模塊的動態(tài)加載功能,并實現(xiàn)外部任務之間的通訊。最后針對內(nèi)存開銷大的問題作出改進,使該項技術(shù)具備更高的實用價值。

        關(guān)鍵詞關(guān)鍵詞:動態(tài)加載;μC/OS;單地址空間;ELF文件

        DOIDOI:10.11907/rjdk.171728

        中圖分類號:TP319

        文獻標識碼:A文章編號文章編號:16727800(2017)011014904

        0引言

        在電子技術(shù)迅速發(fā)展下,嵌入式系統(tǒng)不僅在硬件性能上快速提升,能勝任更多任務,而且在應用上也越發(fā)廣泛,軟件復雜度越來越高,使得對嵌入式軟件開發(fā)提出了新的要求[1]。相比PC操作系統(tǒng)上早已十分成熟的動態(tài)加載技術(shù),常見的μcos嵌入式操作系統(tǒng)缺乏對動態(tài)加載程序的支持,一是ROM技術(shù)限制,二是內(nèi)存使用緊張,無法運行太多程序[2]。Flash技術(shù)的發(fā)展及內(nèi)存的增加,使得基于嵌入式操作系統(tǒng)的動態(tài)加載具備可行性。一些高端嵌入式設備已經(jīng)具備GB級的內(nèi)存,硬件支持虛擬地址空間,能夠運行Linux量級的系統(tǒng)。但實時性不滿足要求,性能過剩且成本偏高。作為嵌入式市場主力的中低端設備,普遍仍是單地址空間,內(nèi)存受限,此時提高系統(tǒng)的可擴展性迫在眉睫。

        本文基于STM32平臺,討論在典型單地址空間、無內(nèi)核態(tài)的μcos嵌入式操作系統(tǒng)上動態(tài)加載技術(shù)實現(xiàn),并針對嵌入式內(nèi)存使用緊張問題作出改進。

        1基本原理與機制

        傳統(tǒng)嵌入式開發(fā)通常將程序編譯鏈接成一個二進制文件,然后燒錄到芯片上運行調(diào)試。從簡單的裸機程序到操作系統(tǒng)與應用綁定編譯的復雜任務,都要通過反復重新編譯鏈接下載調(diào)試流程,周期長而繁瑣,不能快速迭代,對于市場快速變化需求而言顯得效率低下。此外,每次運行程序都是將特定的任務載入內(nèi)存,不能像PC端一樣安裝、卸除程序,每一次變動都要重新燒錄整個程序,無法靈活地調(diào)整更新[3]。

        通常而言,代碼經(jīng)過編譯和鏈接生成二進制可執(zhí)行文件,其中鏈接分為靜態(tài)鏈接、加載時鏈接和運行時鏈接。靜態(tài)鏈接即將程序和它需要的庫鏈接成一個單一文件,獨立運行、速度快,但是生成文件較大,如果要改動就需重新鏈接。加載時鏈接指程序在連接時不會把外部引用的庫代碼鏈接到執(zhí)行程序中,而是在它被加載器加載時將外部庫加載入內(nèi)存進行鏈接。優(yōu)點是程序本身小、靈活。運行時鏈接是加載時鏈接的更進一步,只有在真正調(diào)用外部庫代碼時才將外部庫加載入內(nèi)存進行鏈接[4]。

        嵌入式動態(tài)加載實現(xiàn)主要采用加載時鏈接,即從外部存儲設備中加載程序到內(nèi)存中,在操作系統(tǒng)中動態(tài)申請一個任務棧,讓外部加載的程序在該任務棧上運行,并服從操作系統(tǒng)資源管理,同時程序也能申請一些資源,如內(nèi)存塊、定時器等。

        2系統(tǒng)實現(xiàn)

        單地址空間即整個系統(tǒng)使用一個連續(xù)的單地址空間。無用戶態(tài)與內(nèi)核態(tài)之分,用戶程序的代碼可以直接訪問到操作系統(tǒng)代碼。

        動態(tài)模塊設計參考了Linux中動態(tài)庫文件的實現(xiàn)原理,采用Unix標準的ELF格式文件。該文件格式通用性廣、可拓展性強,對arm體系編譯器有很好的支持。通過設置恰當?shù)木幾g和鏈接參數(shù),生成可重定位位置無關(guān)代碼[56]。

        實現(xiàn)過程中主要解決如下問題:①解決編譯問題,好的外部程序必須是位置無關(guān)代碼,可以加載到任意內(nèi)存地址運行,而燒錄程序要額外生成一個符號表,以便動態(tài)鏈接;②操作系統(tǒng)通過文件系統(tǒng)讀取文件,能夠加載識別配置文件和程序;③加載模塊加載外部程序需進行鏈接,使得操作系統(tǒng)能夠找到外部程序入口,外部程序能夠調(diào)用系統(tǒng)函數(shù),操作軟硬件資源;④解決外部任務之間的通訊。

        2.1編譯器與鏈接器參數(shù)

        采用KeilIDE,默認編譯器為armcc,為了方便鏈接,使用編譯器宏命令導出符號表,以便下一步鏈接。

        此處參考armcc手冊,使用宏命令建立一個結(jié)構(gòu)數(shù)組,存儲符號和地址信息。

        struct my_module_symtab

        {

        void *addr;

        const char *name;

        };,

        #define SYM_EXPORT(symbol)

        const char __sym_##symbol##_name[] SECTION(".rodata.name") = #symbol;

        const struct my_module_symtab __sym_##symbol SECTION("SymTab")=

        {

        (void *)&symbol,

        _sym_##symbol##_name

        }

        存儲符號名和符號地址。其中,SECTION()命令是armcc專屬宏指令,編譯時將該變量放在指定Seciton。__sym_##symbol##_name創(chuàng)建一個字符串常量存儲符號名,struct my_module_symtab用來存儲該符號名和符號地址。

        由于該結(jié)構(gòu)變量都存儲在SECTION("SymTa b")中,因此編譯預處理后將順序分布在SymTabsection中。通過armcc的宏&MySymTabMYMMYMBase訪問section的首元素,&MySymTabMYMMYMLimit訪問尾元素,像數(shù)組一樣操作符號表。SYM_EXPORT()用來輸出變量和符號,提供重定位時的參考信息。

        外部程序選用armnoneeabigcc作為交叉工具鏈。編譯器參數(shù)如表1所示。endprint

        該命令將編譯出所需的ELF文件格式,其中包含重定位符號表,對應已經(jīng)生成好的符號表,進行重定位[7]。

        2.2外部程序加載到內(nèi)存

        在片外Flash上建立fatfs文件系統(tǒng)。Fatfs系統(tǒng)通過usb接口傳輸ELF文件。其中配置文件選項如表3所示。

        系統(tǒng)啟動后加載文件系統(tǒng),等基本驅(qū)動初始化完畢后,加載配置文件。配置文件名固定,程序名不固定。根據(jù)配置文件的加載程序數(shù)量,依次對任務進行加載,創(chuàng)建新任務。需要配置好任務優(yōu)先級、任務周期及任務棧大小,還有可選的傳入?yún)?shù),最后進入OSStart()啟動任務循環(huán)。Usb庫和文件系統(tǒng)都是移植現(xiàn)成的,配置文件為方便使用采取JSON格式,JSON解析使用cJSON庫。

        2.3ELF加載器實現(xiàn)

        操作系統(tǒng)加載外部ELF文件到內(nèi)存后需解析ELF文件,將其中的有用信息提取出來,主要是代碼段、數(shù)據(jù)段及重定位表。重定位表的作用是指出需要重定位項在ELF文件的偏移位置,根據(jù)重定位段和符號表進行重定位操作,最后將程序的入口交給操作系統(tǒng),再由操作系統(tǒng)創(chuàng)建新任務啟動運行,此時成功加載了一個外部程序[78]。

        2.3.1ELF文件頭解析

        解析ELF header,加載到內(nèi)存,編譯出來的文件是Shared Object File,也即Type字段為DYN,ELF Header檢查正常進入下一步[9]。根據(jù)ELF Header后緊跟SectionHeader和SectionHeaderStringTable,其中給出了ELF文件中所包含內(nèi)容的具體信息。使用readELF工具打印出ELFheader,其各Section如圖1所示。

        圖1ELFSectionList

        其中,.rel.dyn中包含了重定位信息,.symtab記錄了符號表。通過Section Header中offset定位各表,即可在下一步重定位操作[10]。

        2.3.2重定位

        重定位之前,需要先將代碼和數(shù)據(jù)加載到內(nèi)存。.text中包含代碼、.rodata只讀數(shù)據(jù)段、.data數(shù)據(jù)段,.bss是未初始化全局變量數(shù)據(jù)段,需要預留出足夠空間。.symtab和.strtab及.symtab,.rel.dyn用于重定位,工作完成后可丟棄。

        根據(jù)重定位表中信息,確定重定位類型,從而確定重定位地址計算方式。重定位項結(jié)構(gòu)體[11]如下:

        struct ELF32_rel {

        ELF32_Addr r_offset;

        ELF32_Word r_info;//SYMBOL<<8+TYPE&0xff.

        };

        //r_offset是需要進行重定位的地址;

        //r_info包含了重定位項的基本信息;

        //SYMBOL是重定位以后需要指向的符號;

        //TYPE是重定位的類型

        重定位過程就是重定位表的遍歷,依次將每個符號地址進行重定位[12]。

        重定位類型很多,但大多數(shù)很少出現(xiàn)。通過對編譯器參數(shù)的設置,使得產(chǎn)生的重定位類型簡單且容易定位。大多為R_ARM_GLOB_DAT、R_RAM_ABS32,及R_ARM_REL32型[1314]。

        假設addr為加載到內(nèi)存后的符號指向地址,sym_val為上述結(jié)構(gòu)體中的r_offset,則3種類型的定位方式如表4所示。

        2.3.3任務創(chuàng)建

        重定位完成后,調(diào)用操作系統(tǒng)創(chuàng)建OS_TCB和CPU_STK并將資源分配給新任務,同時外部程序?qū)⑷肟诮唤o操作系統(tǒng)以便創(chuàng)建新任務。操作系統(tǒng)入口在鏈接時已經(jīng)指定好main函數(shù),ELF header中包含EntryPointAddress即為程序入口。其中,OS_PRIO、CPU_STK_SIZE、OS_TICK、Argument由配置文件指定[15]。

        OSTaskCreate((OS_TCB*)&MyAppTCB,/* Create the start task*/

        (CPU_CHAR*)"Exteral Program1",

        (OS_TASK_PTR ) EntryPointAddress,

        (void*) Argument,

        (OS_PRIO) MyAppPriority(8),

        (CPU_STK*)&MyAppStk[0],

        (CPU_STK_SIZE)MY_APP_STK_SIZE(512) / 10,

        (CPU_STK_SIZE) MY_APP_STK_SIZE,

        (OS_MSG_QTY) 5u,

        (OS_TICK) MyTick(1000),

        (void*) 0,

        (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),

        (OS_ERR*)&err);

        2.4任務通訊

        任務間通訊分為兩種情況:原生程序和外部程序間通訊、外部程序和外部程序間通訊。已知原生程序之間通訊通過全局變量實現(xiàn),通過信號量或互斥量防止競爭。加載外部程序時,如果符號表中有同名的全局變量,會重定位到原生程序中的同名全局變量;如果沒有,則為全局變量分配獨立內(nèi)存,并將其名稱和地址加入到符號表中,由此實現(xiàn)外部程序和原生程序之間的通訊。

        外部和外部程序之間,可以通過約定好的全局變量進行通訊,但這樣不夠靈活;也可通過調(diào)用系統(tǒng)函數(shù)實現(xiàn)通訊,使用操作系統(tǒng)提供消息機制。從任務抽象來看,原生任務和外部加載任務并無不同,一律通過調(diào)用系統(tǒng)函數(shù)接口、消息隊列發(fā)送消息,信號量、事件標志組實現(xiàn)同步。endprint

        3內(nèi)存改進

        在小型嵌入式設備中,內(nèi)存是一種緊缺資源,因此多數(shù)程序內(nèi)存在使用上都是精打細算,早在編程階段就已規(guī)劃好。但對于動態(tài)加載的外部程序,內(nèi)存浪費十分嚴重。一個程序運行只需要代碼段和數(shù)據(jù)段即可,但實際過程中把整個ELF文件都加載進了內(nèi)存,ELF文件頭、重定位表等在加載后即失去作用,屬于冗余信息。

        嵌入式燒錄好的代碼在ROM上運行,但外部程序代碼卻在RAM上運行,實際上是對RAM的浪費?,F(xiàn)代硬件的發(fā)展已經(jīng)支持直接對片上Flash的編程,片上Flash可以直接運行代碼。為了節(jié)省內(nèi)存,提高內(nèi)存利用率,本文對片上Flash地址空間進行管理,在重定位時直接將代碼段重定位到片上Flash的地址,數(shù)據(jù)保留在RAM中,使得二者像原生代碼一樣分離,達到了節(jié)省內(nèi)存的目的。甚至對數(shù)據(jù)段也可以規(guī)劃管理,對于相對固定的參數(shù)類數(shù)據(jù)燒入Flash,而變量保留在內(nèi)存里,達到對內(nèi)存最大效率的利用。已知單地址空間,ROM和RAM只是地址分布不同,因此改進地址分布。ROM中的代碼地址重定位指向RAM,地址分布如圖2所示。

        圖2地址分布

        4測試運行

        為測試驗證軟件模塊是否正常運行,基于STM32F103平臺,設計不同的外部任務進行加載測試。嵌入式平臺上最通用的調(diào)試方式是通過LED燈指示程序運行狀況。將信號燈任務程序編譯為外部程序進行加載,該程序?qū)⒄{(diào)用系統(tǒng)函數(shù)和驅(qū)動接口,對LED進行點亮、閃爍、延時、流水燈等操作。借助該測試樣例成功驗證功能,包括外部程序成功加載、調(diào)用系統(tǒng)函數(shù)及多個外部程序之間的通訊。

        5結(jié)語

        本文參考Linux動態(tài)加載庫原理,實現(xiàn)ELF文件動態(tài)加載,使得μcosIII支持外部程序的動態(tài)加載,提高操作系統(tǒng)的可拓展性和靈活性。將代碼段和數(shù)據(jù)段分離,盡可能使外部加載代碼類似于原生代碼的方式執(zhí)行,對動態(tài)加載內(nèi)存開銷大的問題作出改進,通過配置文件提高靈活性,使該技術(shù)在嵌入式領域具備實用價值。不足之處是支持多個任務模塊之間的通信,但依賴加載順序,對Static型不支持,在編碼過程中需注意Static變量使用,采用全局變量進行替代。本文闡述的動態(tài)軟件模塊機制有待進一步完善。

        參考文獻參考文獻:

        [1]張丹.嵌入式系統(tǒng)引導加載程序分析[J].軟件,2012,7(9):129132.

        [2]李忠儒.嵌入式系統(tǒng)的發(fā)展趨勢[J].辦公自動化,2011,35(11):3537.

        [3]王婧怡,應忍冬,周玲玲.微內(nèi)核系統(tǒng)直接加載文件機制的設計與研究[J].信息技術(shù),2009,15(10):7376

        [4]RANDALLHYDE.深入理解計算機[M].韓海東,譯.北京:電子工業(yè)出版社,2006:295300.

        [5]陳紫卿,孫昕.FreeRTOS動態(tài)軟件模塊[J].計算機與現(xiàn)代化,2016,8(6):2428.

        [6]鄭映,張祖平.基于ARM+μCOSII的程序動態(tài)加載實現(xiàn)方案[J].艦船電子工程,2009,29(5):8890.

        [7]RICHARD M STALLMAN,THE GCC DEVELOPER COMMUNITY.Using the GNU compiler collection (GNU tools for ARM embedded processors)[M].GNU Press,2016.

        [8]楊偉,羅蕾.嵌入式系統(tǒng)中的模塊動態(tài)加載技術(shù)[J].單片機與嵌入式系統(tǒng)應用,2015,23(11):810

        [9]李培亮,李振鵬.嵌入式單地址空間操作系統(tǒng)動態(tài)加載的研究[J].電子測試,2010,8(7):2327.

        [10]朱裕祿.系統(tǒng)下的文件分析[J].電腦知識與技術(shù)學術(shù)交流,2006,17(26):6466

        [11]何先波,唐寧九,呂方,等.文件格式及應用[J].計算機應用研究,2001,18(11):144145

        [12]袁鴻野.基于嵌入式操作系統(tǒng)的動態(tài)鏈接器設計與實現(xiàn)[D].成都:電子科技大學,2013.

        [13]寧濤.面向嵌入式應用的動態(tài)加載機制研究.[D]重慶:重慶大學,2008.

        [14]TOOL INTERFACE STANDARD(TIS).Executable and linking format (ELF) specification.version1.2[S].2010.

        [15]JEAN J.Labrosse μC/OSIII reference manual[M].US:Micriμm Press,2015.

        責任編輯(責任編輯:孫娟)endprint

        亚洲AV无码久久精品成人| 丰满少妇人妻无码专区| 影音先锋男人站| 亚洲国产成人久久一区www妖精| 国产成人免费a在线视频| 亚洲Av无码专区尤物| 美女福利视频在线观看网址| 老鸭窝视频在线观看| 国产精一品亚洲二区在线播放| 夜夜揉揉日日人人| 69国产成人综合久久精| 久久九九精品国产不卡一区| 色婷婷五月综合激情中文字幕| 无码人妻久久一区二区三区app | 色噜噜狠狠色综合欧洲| 国产自拍成人在线免费视频| 亚洲熟妇无码久久精品| 真实单亲乱l仑对白视频 | 一区二区三区婷婷在线| 日韩一区二区av伦理| 极品老师腿张开粉嫩小泬| 狠狠色综合网站久久久久久久 | 国产特黄级aaaaa片免| 蜜桃一区二区三区视频网址| 亚洲色欲色欲大片www无码| 97成人精品| 人妻少妇偷人精品久久人妻| 女人18片毛片60分钟| 理论片午午伦夜理片影院| 国色天香精品亚洲精品| 少妇人妻无奈的跪趴翘起| 无遮挡呻吟娇喘视频免费播放| 亚洲欧洲巨乳清纯| 麻豆国产AV网站| 中文字幕一区在线直播| 国产揄拍国产精品| 狼友AV在线| 91国产精品自拍视频| 中文字幕精品一区二区精品| 欧美老妇人与禽交| 国产天堂av手机在线|